]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
xen/console: Introduce console=xen
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 23 Nov 2017 10:59:59 +0000 (10:59 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 6 Dec 2017 11:54:21 +0000 (11:54 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/drivers/char/console.c
xen/include/asm-x86/guest/hypercall.h

index 19d0e74f171cd0dae09a84ed0021e0ca8eb5c92c..5882b04cf05cfa010b008f3ac814e474d40f98a0 100644 (file)
@@ -30,6 +30,7 @@
 #include <xen/hypercall.h> /* for do_console_io */
 #include <xen/early_printk.h>
 #include <xen/warning.h>
+#include <asm/guest.h>
 
 /* console: comma-separated list of console outputs. */
 static char __initdata opt_console[30] = OPT_CONSOLE_STR;
@@ -83,6 +84,8 @@ static uint32_t conringc, conringp;
 
 static int __read_mostly sercon_handle = -1;
 
+static bool __read_mostly opt_console_xen; /* console=xen */
+
 static DEFINE_SPINLOCK(console_lock);
 
 /*
@@ -458,6 +461,19 @@ static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count)
             sercon_puts(kbuf);
             video_puts(kbuf);
 
+            if ( opt_console_xen )
+            {
+                unsigned long tmp;
+                size_t len = strlen(kbuf);
+
+                if ( xen_guest )
+                    xen_hypercall_console_write(kbuf, len);
+                else
+                    asm volatile ( "rep outsb;"
+                                   : "=&S" (tmp), "=&c" (tmp)
+                                   : "0" (kbuf), "1" (len), "d" (0xe9) );
+            }
+
             if ( opt_console_to_ring )
             {
                 conring_puts(kbuf);
@@ -567,6 +583,19 @@ static void __putstr(const char *str)
     sercon_puts(str);
     video_puts(str);
 
+    if ( opt_console_xen )
+    {
+        unsigned long tmp;
+        size_t len = strlen(str);
+
+        if ( xen_guest )
+            xen_hypercall_console_write(str, len);
+        else
+            asm volatile ( "rep outsb;"
+                           : "=&S" (tmp), "=&c" (tmp)
+                           : "0" (str), "1" (len), "d" (0xe9) );
+    }
+
     conring_puts(str);
 
     if ( !console_locks_busted )
@@ -762,6 +791,8 @@ void __init console_init_preirq(void)
             p++;
         if ( !strncmp(p, "vga", 3) )
             video_init();
+        else if ( !strncmp(p, "xen", 3) )
+            opt_console_xen = true;
         else if ( !strncmp(p, "none", 4) )
             continue;
         else if ( (sh = serial_parse_handle(p)) >= 0 )
index 4bb749f240562536c5017fccf85e117a9eb93780..d5fe535c0321caf5d27896c417b77b57e0daf248 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)
 {
     return xen_hypercall_sched_op(SCHEDOP_shutdown, &reason);
@@ -106,6 +113,12 @@ static inline long xen_hypercall_shutdown(unsigned int reason)
 
 #else /* CONFIG_XEN_GUEST */
 
+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();