[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 21/22] vixen: provide Xencons implementation



From: Anthony Liguori <aliguori@xxxxxxxxxx>

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 <aliguori@xxxxxxxxxx>
---
 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 76d9638..eeffafa 100644
--- a/xen/arch/x86/guest/vixen.c
+++ b/xen/arch/x86/guest/vixen.c
@@ -23,6 +23,7 @@
 #include <public/version.h>
 #include <xen/event.h>
 #include <asm/apic.h>
+#include <public/io/console.h>
 
 static int in_vixen;
 static uint8_t global_si_data[4 << 10] __attribute__((aligned(4096)));
@@ -31,6 +32,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;
 
 void __init init_vixen(void)
 {
@@ -49,6 +53,8 @@ void __init init_vixen(void)
 
     printk("Vixen running under Xen %d.%d\n", major, minor);
 
+    spin_lock_init(&vixen_xencons_lock);
+
     in_vixen = 1;
 }
 
@@ -239,6 +245,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 a07343d..a83aeb2 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -764,6 +764,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(&notify_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 e486cc3..f46c6ed 100644
--- a/xen/include/asm-x86/guest/vixen.h
+++ b/xen/include/asm-x86/guest/vixen.h
@@ -82,4 +82,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@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.