summaryrefslogtreecommitdiffstats
path: root/patches/jailhouse/jailhouse_0004.patch
blob: be612ff9fb0a1cd8fa4396e14dcd14f10d90439f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
From 8ba0c10a0b7fd44efe2e17462bb39732498b6d9b Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Sun, 11 Sep 2016 23:30:04 +0200
Subject: [PATCH] jailhouse: Add simple debug console via the hypervisor

Jailhouse allows explicitly configured cells to write character-wise
messages to the hypervisor debug console. Make use of this for a
platform-agnostic boot diagnosis channel, specifically for non-root
cells. It also comes with earlycon support.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 drivers/virt/Kconfig            | 11 +++++
 drivers/virt/Makefile           |  1 +
 drivers/virt/jailhouse_dbgcon.c | 99 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)
 create mode 100644 drivers/virt/jailhouse_dbgcon.c

diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 99ebdde..baf04bb 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -30,4 +30,15 @@ config FSL_HV_MANAGER
           4) A kernel interface for receiving callbacks when a managed
 	     partition shuts down.
 
+config JAILHOUSE_DBGCON
+	tristate "Jailhouse console driver"
+	depends on X86 || ARM || ARM64
+	help
+	  The Jailhouse hypervisor provides a simple write-only console for
+	  debugging the bootstrap process of its cells. This driver registers
+	  a console with the kernel to make use of it.
+
+	  Note that Jailhouse has to be configured to permit a cell the usage
+	  of the console interface.
+
 endif
diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
index c47f04d..abd4baa 100644
--- a/drivers/virt/Makefile
+++ b/drivers/virt/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_FSL_HV_MANAGER)	+= fsl_hypervisor.o
+obj-$(CONFIG_JAILHOUSE_DBGCON)	+= jailhouse_dbgcon.o
diff --git a/drivers/virt/jailhouse_dbgcon.c b/drivers/virt/jailhouse_dbgcon.c
new file mode 100644
index 0000000..5a8a8fb
--- /dev/null
+++ b/drivers/virt/jailhouse_dbgcon.c
@@ -0,0 +1,99 @@
+/*
+ * Console driver for running over the Jailhouse partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2016
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/serial_core.h>
+#ifdef CONFIG_X86
+#include <asm/alternative.h>
+#endif
+#ifdef CONFIG_ARM
+#include <asm/opcodes-virt.h>
+#endif
+
+#define JAILHOUSE_HC_DEBUG_CONSOLE_PUTC		8
+
+static void hypervisor_putc(char c)
+{
+#if defined(CONFIG_X86)
+	int result;
+
+	asm volatile(
+		ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9",
+			    X86_FEATURE_VMMCALL)
+		: "=a" (result)
+		: "a" (JAILHOUSE_HC_DEBUG_CONSOLE_PUTC), "D" (c)
+		: "memory");
+#elif defined(CONFIG_ARM)
+	register u32 num_res asm("r0") = JAILHOUSE_HC_DEBUG_CONSOLE_PUTC;
+	register u32 arg1 asm("r1") = c;
+
+	asm volatile(
+		__HVC(0x4a48)
+		: "=r" (num_res)
+		: "r" (num_res), "r" (arg1)
+		: "memory");
+#elif defined(CONFIG_ARM64)
+	register u64 num_res asm("x0") = JAILHOUSE_HC_DEBUG_CONSOLE_PUTC;
+	register u64 arg1 asm("x1") = c;
+
+	asm volatile(
+		"hvc #0x4a48\n\t"
+		: "=r" (num_res)
+		: "r" (num_res), "r" (arg1)
+		: "memory");
+#endif
+}
+
+static void jailhouse_dbgcon_write(struct console *con, const char *s,
+				   unsigned count)
+{
+	while (count > 0) {
+		hypervisor_putc(*s);
+		count--;
+		s++;
+	}
+}
+
+static int __init early_jailhouse_dbgcon_setup(struct earlycon_device *device,
+					       const char *options)
+{
+	device->con->write = jailhouse_dbgcon_write;
+	return 0;
+}
+
+EARLYCON_DECLARE(jailhouse, early_jailhouse_dbgcon_setup);
+
+static struct console jailhouse_dbgcon = {
+	.name = "jailhouse",
+	.write = jailhouse_dbgcon_write,
+	.flags = CON_PRINTBUFFER | CON_ANYTIME,
+	.index = -1,
+};
+
+static int __init jailhouse_dbgcon_init(void)
+{
+	register_console(&jailhouse_dbgcon);
+	return 0;
+}
+
+static void __exit jailhouse_dbgcon_exit(void)
+{
+	unregister_console(&jailhouse_dbgcon);
+}
+
+module_init(jailhouse_dbgcon_init);
+module_exit(jailhouse_dbgcon_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Jailhouse debug console driver");
+MODULE_AUTHOR("Jan Kiszka <jan.kiszka@siemens.com>");
-- 
2.1.4