summaryrefslogtreecommitdiffstats
path: root/meta-agl-devel/meta-agl-jailhouse/recipes-kernel/linux/linux/0003-jailhouse-Add-simple-debug-console-via-the-hyperviso.patch
blob: 289f54ac307a941ef1456944fc8a98491f90ae88 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
From faa349f4d096554c6d5bfe74634599d2e26f64a7 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 03/32] jailhouse: Add simple debug console via the hypervisor

Jailhouse allows explicitly enabled 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. This also comes with earlycon support.

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 9d3a5c54a41d..07cb4d674c93 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8761,6 +8761,7 @@ L:	jailhouse-dev@googlegroups.com
 S:	Maintained
 F:	arch/x86/kernel/jailhouse.c
 F:	arch/x86/include/asm/jailhouse_para.h
+F:	drivers/virt/jailhouse_dbgcon.c
 
 JC42.4 TEMPERATURE SENSOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 363af2eaf2ba..99c5eaca6952 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -31,5 +31,16 @@ 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.
+
 source "drivers/virt/vboxguest/Kconfig"
 endif
diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
index fd331247c27a..89e86a1d0f19 100644
--- a/drivers/virt/Makefile
+++ b/drivers/virt/Makefile
@@ -4,4 +4,5 @@
 #
 
 obj-$(CONFIG_FSL_HV_MANAGER)	+= fsl_hypervisor.o
+obj-$(CONFIG_JAILHOUSE_DBGCON)	+= jailhouse_dbgcon.o
 obj-y				+= vboxguest/
diff --git a/drivers/virt/jailhouse_dbgcon.c b/drivers/virt/jailhouse_dbgcon.c
new file mode 100644
index 000000000000..1fd201ea1460
--- /dev/null
+++ b/drivers/virt/jailhouse_dbgcon.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Console driver for running over the Jailhouse partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2016-2018
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ */
+
+#include <linux/console.h>
+#include <linux/hypervisor.h>
+#include <linux/module.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");
+#else
+#error Unsupported architecture.
+#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)
+{
+	if (!jailhouse_paravirt())
+		return -ENODEV;
+
+	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.11.0