diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-29 02:11:17 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-29 02:11:17 +0200 |
commit | 18cb657ca1bafe635f368346a1676fb04c512edf (patch) | |
tree | b0eb6a4ceddf98e7bf820be7ff24bf131ff56b0c /drivers/char/hvc_xen.c | |
parent | Merge branch 'packaging' of git://git.kernel.org/pub/scm/linux/kernel/git/mma... (diff) | |
parent | xen: register xen pci notifier (diff) | |
download | linux-18cb657ca1bafe635f368346a1676fb04c512edf.tar.xz linux-18cb657ca1bafe635f368346a1676fb04c512edf.zip |
Merge branch 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
and branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm
* 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm:
xen: register xen pci notifier
xen: initialize cpu masks for pv guests in xen_smp_init
xen: add a missing #include to arch/x86/pci/xen.c
xen: mask the MTRR feature from the cpuid
xen: make hvc_xen console work for dom0.
xen: add the direct mapping area for ISA bus access
xen: Initialize xenbus for dom0.
xen: use vcpu_ops to setup cpu masks
xen: map a dummy page for local apic and ioapic in xen_set_fixmap
xen: remap MSIs into pirqs when running as initial domain
xen: remap GSIs as pirqs when running as initial domain
xen: introduce XEN_DOM0 as a silent option
xen: map MSIs into pirqs
xen: support GSI -> pirq remapping in PV on HVM guests
xen: add xen hvm acpi_register_gsi variant
acpi: use indirect call to register gsi in different modes
xen: implement xen_hvm_register_pirq
xen: get the maximum number of pirqs from xen
xen: support pirq != irq
* 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: (27 commits)
X86/PCI: Remove the dependency on isapnp_disable.
xen: Update Makefile with CONFIG_BLOCK dependency for biomerge.c
MAINTAINERS: Add myself to the Xen Hypervisor Interface and remove Chris Wright.
x86: xen: Sanitse irq handling (part two)
swiotlb-xen: On x86-32 builts, select SWIOTLB instead of depending on it.
MAINTAINERS: Add myself for Xen PCI and Xen SWIOTLB maintainer.
xen/pci: Request ACS when Xen-SWIOTLB is activated.
xen-pcifront: Xen PCI frontend driver.
xenbus: prevent warnings on unhandled enumeration values
xenbus: Xen paravirtualised PCI hotplug support.
xen/x86/PCI: Add support for the Xen PCI subsystem
x86: Introduce x86_msi_ops
msi: Introduce default_[teardown|setup]_msi_irqs with fallback.
x86/PCI: Export pci_walk_bus function.
x86/PCI: make sure _PAGE_IOMAP it set on pci mappings
x86/PCI: Clean up pci_cache_line_size
xen: fix shared irq device passthrough
xen: Provide a variant of xen_poll_irq with timeout.
xen: Find an unbound irq number in reverse order (high to low).
xen: statically initialize cpu_evtchn_mask_p
...
Fix up trivial conflicts in drivers/pci/Makefile
Diffstat (limited to 'drivers/char/hvc_xen.c')
-rw-r--r-- | drivers/char/hvc_xen.c | 98 |
1 files changed, 65 insertions, 33 deletions
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index 6b8e6d18a8e6..3740e327f180 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c @@ -79,7 +79,7 @@ static int __write_console(const char *data, int len) return sent; } -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) { int ret = len; @@ -102,7 +102,7 @@ static int write_console(uint32_t vtermno, const char *data, int len) return ret; } -static int read_console(uint32_t vtermno, char *buf, int len) +static int domU_read_console(uint32_t vtermno, char *buf, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -123,28 +123,62 @@ static int read_console(uint32_t vtermno, char *buf, int len) return recv; } -static const struct hv_ops hvc_ops = { - .get_chars = read_console, - .put_chars = write_console, +static struct hv_ops domU_hvc_ops = { + .get_chars = domU_read_console, + .put_chars = domU_write_console, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, .notifier_hangup = notifier_hangup_irq, }; -static int __init xen_init(void) +static int dom0_read_console(uint32_t vtermno, char *buf, int len) +{ + return HYPERVISOR_console_io(CONSOLEIO_read, len, buf); +} + +/* + * Either for a dom0 to write to the system console, or a domU with a + * debug version of Xen + */ +static int dom0_write_console(uint32_t vtermno, const char *str, int len) +{ + int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); + if (rc < 0) + return 0; + + return len; +} + +static struct hv_ops dom0_hvc_ops = { + .get_chars = dom0_read_console, + .put_chars = dom0_write_console, + .notifier_add = notifier_add_irq, + .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, +}; + +static int __init xen_hvc_init(void) { struct hvc_struct *hp; + struct hv_ops *ops; - if (!xen_pv_domain() || - xen_initial_domain() || - !xen_start_info->console.domU.evtchn) + if (!xen_pv_domain()) return -ENODEV; - xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + if (xen_initial_domain()) { + ops = &dom0_hvc_ops; + xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); + } else { + if (!xen_start_info->console.domU.evtchn) + return -ENODEV; + + 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); @@ -161,7 +195,7 @@ void xen_console_resume(void) rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); } -static void __exit xen_fini(void) +static void __exit xen_hvc_fini(void) { if (hvc) hvc_remove(hvc); @@ -169,29 +203,24 @@ static void __exit xen_fini(void) static int xen_cons_init(void) { + struct hv_ops *ops; + if (!xen_pv_domain()) return 0; - hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); + if (xen_initial_domain()) + ops = &dom0_hvc_ops; + else + ops = &domU_hvc_ops; + + hvc_instantiate(HVC_COOKIE, 0, ops); return 0; } -module_init(xen_init); -module_exit(xen_fini); +module_init(xen_hvc_init); +module_exit(xen_hvc_fini); console_initcall(xen_cons_init); -static void raw_console_write(const char *str, int len) -{ - while(len > 0) { - int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); - if (rc <= 0) - break; - - str += rc; - len -= rc; - } -} - #ifdef CONFIG_EARLY_PRINTK static void xenboot_write_console(struct console *console, const char *string, unsigned len) @@ -199,19 +228,22 @@ static void xenboot_write_console(struct console *console, const char *string, unsigned int linelen, off = 0; const char *pos; - raw_console_write(string, len); + dom0_write_console(0, string, len); + + if (xen_initial_domain()) + return; - write_console(0, "(early) ", 8); + domU_write_console(0, "(early) ", 8); while (off < len && NULL != (pos = strchr(string+off, '\n'))) { linelen = pos-string+off; if (off + linelen > len) break; - write_console(0, string+off, linelen); - write_console(0, "\r\n", 2); + domU_write_console(0, string+off, linelen); + domU_write_console(0, "\r\n", 2); off += linelen + 1; } if (off < len) - write_console(0, string+off, len-off); + domU_write_console(0, string+off, len-off); } struct console xenboot_console = { @@ -223,7 +255,7 @@ struct console xenboot_console = { void xen_raw_console_write(const char *str) { - raw_console_write(str, strlen(str)); + dom0_write_console(0, str, strlen(str)); } void xen_raw_printk(const char *fmt, ...) |