From: Anthony Liguori <aligu...@amazon.com> Our initial approach exposed the console ring directly to guests which worked well except for the fact that very old versions of Xen did not support console ring for HVM guests. It also proved to be complicated from a management tool perspective since both the serial console and the paravirt console for HVM guests produced output.
Having a simple xencons implementation helps simplify using Vixen as a management tool no longer needs to care about whether or not this mode is enabled. In order to output to the console without the '(Xen)' adornment, we introduce a new entry point into the console code too. Signed-off-by: Anthony Liguori <aligu...@amazon.com> --- xen/arch/x86/guest/vixen.c | 41 +++++++++++++++++++++++++++++++++++++++ xen/common/event_channel.c | 5 ++++- xen/drivers/char/console.c | 16 +++++++++++++++ xen/include/asm-x86/guest/vixen.h | 2 ++ xen/include/xen/lib.h | 1 + 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/guest/vixen.c b/xen/arch/x86/guest/vixen.c index 59faa0c..d871218 100644 --- a/xen/arch/x86/guest/vixen.c +++ b/xen/arch/x86/guest/vixen.c @@ -26,6 +26,7 @@ #include <xen/event.h> #include <asm/apic.h> #include <xen/pci_ids.h> +#include <public/io/console.h> #define PCI_DEVICE_ID_XENSOURCE_PLATFORM 0x0001 @@ -43,6 +44,9 @@ static bool vixen_per_cpu_notifications = true; static uint8_t vixen_evtchn_vector; static bool vixen_needs_apic_ack = true; struct irqaction vixen_irqaction; +static volatile struct xencons_interface *vixen_xencons_iface; +static uint16_t vixen_xencons_port; +static spinlock_t vixen_xencons_lock; integer_param("vixen_domid", vixen_domid); boolean_param("vixen_ptver", vixen_ptver); @@ -89,6 +93,8 @@ void __init init_vixen(void) } } + spin_lock_init(&vixen_xencons_lock); + in_vixen = 1; } @@ -304,6 +310,41 @@ static void vixen_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) vixen_upcall(smp_processor_id()); } +bool vixen_ring_process(uint16_t port) +{ + volatile struct xencons_interface *r = vixen_xencons_iface; + char buffer[128]; + size_t n; + + if (r == NULL || port != vixen_xencons_port) { + return false; + } + + spin_lock(&vixen_xencons_lock); + + n = 0; + while (r->out_prod != r->out_cons) { + char ch = r->out[MASK_XENCONS_IDX(r->out_cons, r->out)]; + if (n == sizeof(buffer) - 1) { + buffer[n] = 0; + guest_puts(hardware_domain, buffer); + n = 0; + } + buffer[n++] = ch; + rmb(); + r->out_cons++; + } + + if (n) { + buffer[n] = 0; + guest_puts(hardware_domain, buffer); + } + + spin_unlock(&vixen_xencons_lock); + + return true; +} + static int hvm_set_parameter(int idx, uint64_t value) { struct xen_hvm_param xhv; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 54ea720..6d060a5 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -1241,7 +1241,10 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) struct evtchn_send send; if ( copy_from_guest(&send, arg, 1) != 0 ) return -EFAULT; - rc = evtchn_send(current->domain, send.port); + if ( vixen_ring_process(send.port) ) + rc = 0; + else + rc = evtchn_send(current->domain, send.port); break; } diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 3eb130d..4be34d4 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -775,6 +775,22 @@ void guest_printk(const struct domain *d, const char *fmt, ...) va_end(args); } +void guest_puts(const struct domain *d, const char *kbuf) +{ + spin_lock_irq(&console_lock); + + sercon_puts(kbuf); + video_puts(kbuf); + + if ( opt_console_to_ring ) + { + conring_puts(kbuf); + tasklet_schedule(¬ify_dom0_con_ring_tasklet); + } + + spin_unlock_irq(&console_lock); +} + void __init console_init_preirq(void) { char *p; diff --git a/xen/include/asm-x86/guest/vixen.h b/xen/include/asm-x86/guest/vixen.h index 140645c..4b59cc7 100644 --- a/xen/include/asm-x86/guest/vixen.h +++ b/xen/include/asm-x86/guest/vixen.h @@ -88,4 +88,6 @@ void vixen_vcpu_initialize(struct vcpu *v); void __init vixen_transform(struct domain *dom0); +bool vixen_ring_process(uint16_t port); + #endif diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index ed00ae1..de84638 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -92,6 +92,7 @@ extern void printk(const char *format, ...) __attribute__ ((format (printf, 1, 2))); extern void guest_printk(const struct domain *d, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +extern void guest_puts(const struct domain *d, const char *message); extern void noreturn panic(const char *format, ...) __attribute__ ((format (printf, 1, 2))); extern long vm_assist(struct domain *, unsigned int cmd, unsigned int type, -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel