|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |