]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
xen/console: Introduce console=xen
authorWei Liu <wei.liu2@citrix.com>
Thu, 11 Jan 2018 10:18:09 +0000 (10:18 +0000)
committerRoger Pau Monne <roger.pau@citrix.com>
Thu, 11 Jan 2018 17:51:19 +0000 (17:51 +0000)
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@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
xen/drivers/char/console.c
xen/include/asm-x86/guest/hypercall.h

index 19d0e74f171cd0dae09a84ed0021e0ca8eb5c92c..d05ebf9f70ce0f220e06ecdb98ffa6a74976aa8c 100644 (file)
 #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 )
index e0b00f97fb9a8cea57deaa36ae72e663dad66fc1..9cd95d2b9289b6d91a56c819e294ac2fad12863b 100644 (file)
@@ -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();