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

[Xen-devel] [PATCH v2 25/62] xen/console: Introduce console=xen



This specifies whether to use Xen specific console output. There are
two variants: one is the hypervisor console, the other is the magic
debug port 0xe9.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/drivers/char/console.c            | 46 +++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/guest/hypercall.h | 13 ++++++++++
 2 files changed, 59 insertions(+)

diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 19d0e74f17..d05ebf9f70 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -31,6 +31,10 @@
 #include <xen/early_printk.h>
 #include <xen/warning.h>
 
+#ifdef CONFIG_X86
+#include <asm/guest.h>
+#endif
+
 /* console: comma-separated list of console outputs. */
 static char __initdata opt_console[30] = OPT_CONSOLE_STR;
 string_param("console", opt_console);
@@ -83,6 +87,10 @@ static uint32_t conringc, conringp;
 
 static int __read_mostly sercon_handle = -1;
 
+#ifdef CONFIG_X86
+static bool __read_mostly opt_console_xen; /* console=xen */
+#endif
+
 static DEFINE_SPINLOCK(console_lock);
 
 /*
@@ -432,6 +440,16 @@ static void notify_dom0_con_ring(unsigned long unused)
 static DECLARE_SOFTIRQ_TASKLET(notify_dom0_con_ring_tasklet,
                                notify_dom0_con_ring, 0);
 
+#ifdef CONFIG_X86
+static inline void xen_console_write_debug_port(const char *buf, size_t len)
+{
+    unsigned long tmp;
+    asm volatile ( "rep outsb;"
+                   : "=&S" (tmp), "=&c" (tmp)
+                   : "0" (buf), "1" (len), "d" (0xe9) );
+}
+#endif
+
 static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count)
 {
     char kbuf[128];
@@ -458,6 +476,18 @@ static long 
guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count)
             sercon_puts(kbuf);
             video_puts(kbuf);
 
+#ifdef CONFIG_X86
+            if ( opt_console_xen )
+            {
+                size_t len = strlen(kbuf);
+
+                if ( xen_guest )
+                    xen_hypercall_console_write(kbuf, len);
+                else
+                    xen_console_write_debug_port(kbuf, len);
+            }
+#endif
+
             if ( opt_console_to_ring )
             {
                 conring_puts(kbuf);
@@ -567,6 +597,18 @@ static void __putstr(const char *str)
     sercon_puts(str);
     video_puts(str);
 
+#ifdef CONFIG_X86
+    if ( opt_console_xen )
+    {
+        size_t len = strlen(str);
+
+        if ( xen_guest )
+            xen_hypercall_console_write(str, len);
+        else
+            xen_console_write_debug_port(str, len);
+    }
+#endif
+
     conring_puts(str);
 
     if ( !console_locks_busted )
@@ -762,6 +804,10 @@ void __init console_init_preirq(void)
             p++;
         if ( !strncmp(p, "vga", 3) )
             video_init();
+#ifdef CONFIG_X86
+        else if ( !strncmp(p, "xen", 3) )
+            opt_console_xen = true;
+#endif
         else if ( !strncmp(p, "none", 4) )
             continue;
         else if ( (sh = serial_parse_handle(p)) >= 0 )
diff --git a/xen/include/asm-x86/guest/hypercall.h 
b/xen/include/asm-x86/guest/hypercall.h
index e0b00f97fb..9cd95d2b92 100644
--- a/xen/include/asm-x86/guest/hypercall.h
+++ b/xen/include/asm-x86/guest/hypercall.h
@@ -99,6 +99,13 @@ static inline long xen_hypercall_memory_op(unsigned int cmd, 
void *arg)
 /*
  * Higher level hypercall helpers
  */
+static inline void xen_hypercall_console_write(
+    const char *buf, unsigned int count)
+{
+    (void)_hypercall64_3(long, __HYPERVISOR_console_io,
+                         CONSOLEIO_write, count, buf);
+}
+
 static inline long xen_hypercall_shutdown(unsigned int reason)
 {
     struct sched_shutdown s = { .reason = reason };
@@ -109,6 +116,12 @@ static inline long xen_hypercall_shutdown(unsigned int 
reason)
 
 #include <public/sched.h>
 
+static inline void xen_hypercall_console_write(
+    const char *buf, unsigned int count)
+{
+    ASSERT_UNREACHABLE();
+}
+
 static inline long xen_hypercall_shutdown(unsigned int reason)
 {
     ASSERT_UNREACHABLE();
-- 
2.11.0


_______________________________________________
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®.