From 62b0e0c94beefd2134a5eb09c10b69b964e78aa9 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Mon, 26 Nov 2007 07:38:29 +0100 Subject: [PATCH] xen dom0: Make hvc_xen console work for dom0. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Juan Quintela --- arch/x86/xen/events.c | 2 +- drivers/char/hvc_xen.c | 61 +++++++++++++++++++++++++++++++++++++++++------ include/xen/events.h | 2 + 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c index 6d1da58..2bf9731 100644 --- a/arch/x86/xen/events.c +++ b/arch/x86/xen/events.c @@ -311,7 +311,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) } -static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) +int bind_virq_to_irq(unsigned int virq, unsigned int cpu) { struct evtchn_bind_virq bind_virq; int evtchn, irq; diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index dd68f85..511fa6a 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c @@ -50,7 +50,7 @@ static inline void notify_daemon(void) notify_remote_via_evtchn(xen_start_info->console.domU.evtchn); } -static int write_console(uint32_t vtermno, const char *data, int len) +static int domU_write_console(uint32_t vtermno, const char *data, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -71,7 +71,28 @@ static int write_console(uint32_t vtermno, const char *data, int len) return sent; } -static int read_console(uint32_t vtermno, char *buf, int len) +static int dom0_write_console(uint32_t vtermno, const char *data, int len) +{ + int ret; + + ret = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)data); + + return ret < 0 ? 0 : len; +} + +static int write_console(uint32_t vtermno, const char *data, int len) +{ + int ret; + + if (is_initial_xendomain()) + ret = dom0_write_console(vtermno, data, len); + else + ret = domU_write_console(vtermno, data, len); + + return ret; +} + +static int domU_read_console(uint32_t vtermno, char *buf, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -92,22 +113,40 @@ static int read_console(uint32_t vtermno, char *buf, int len) return recv; } -static struct hv_ops hvc_ops = { - .get_chars = read_console, - .put_chars = write_console, +static int dom0_read_console(uint32_t vtermno, char *buf, int len) +{ + return HYPERVISOR_console_io(CONSOLEIO_read, len, buf); +} + +static struct hv_ops domU_hvc_ops = { + .get_chars = domU_read_console, + .put_chars = domU_write_console, +}; + +static struct hv_ops dom0_hvc_ops = { + .get_chars = dom0_read_console, + .put_chars = dom0_write_console, }; static int __init xen_init(void) { struct hvc_struct *hp; + struct hv_ops *ops; if (!is_running_on_xen()) return 0; - xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + if (is_initial_xendomain()) { + ops = &dom0_hvc_ops; + xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, smp_processor_id()); + } else { + ops = &domU_hvc_ops; + xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + } + if (xencons_irq < 0) xencons_irq = 0 /* NO_IRQ */; - hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); + hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256); if (IS_ERR(hp)) return PTR_ERR(hp); @@ -123,10 +162,16 @@ static void __exit xen_fini(void) static int xen_cons_init(void) { + struct hv_ops *ops; + if (!is_running_on_xen()) return 0; - hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); + ops = &domU_hvc_ops; + if (is_initial_xendomain()) + ops = &dom0_hvc_ops; + + hvc_instantiate(HVC_COOKIE, 0, ops); return 0; } diff --git a/include/xen/events.h b/include/xen/events.h index 2bde54d..0436486 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -18,6 +18,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id); +int bind_virq_to_irq(unsigned int virq, unsigned int cpu); + int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler, unsigned long irqflags, const char *devname, -- 1.5.3.4