blob: 72f3048d8fe5f901603d3c7f11041b60e52a8cba [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 58d058f1fe1cc5981c57be8b48d3b2f74f25c0d6 Mon Sep 17 00:00:00 2001
2From: Jan Kiszka <jan.kiszka@siemens.com>
3Date: Sun, 11 Sep 2016 23:30:04 +0200
4Subject: [PATCH] jailhouse: Add simple debug console via the hypervisor
5
6Jailhouse allows explicitly enabled cells to write character-wise
7messages to the hypervisor debug console. Make use of this for a
8platform-agnostic boot diagnosis channel, specifically for non-root
9cells. This also comes with earlycon support.
10
11Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
12(cherry picked from commit 60685bd589aef4972d20724863079edf2039eaa2)
13From http://git.kiszka.org/?p=linux.git;a=shortlog;h=refs/heads/queues/jailhouse
14---
15 MAINTAINERS | 1 +
16 drivers/virt/Kconfig | 11 +++++
17 drivers/virt/Makefile | 1 +
18 drivers/virt/jailhouse_dbgcon.c | 103 ++++++++++++++++++++++++++++++++++++++++
19 4 files changed, 116 insertions(+)
20 create mode 100644 drivers/virt/jailhouse_dbgcon.c
21
22--- a/MAINTAINERS
23+++ b/MAINTAINERS
24@@ -8773,6 +8773,7 @@ L: jailhouse-dev@googlegroups.com
25 S: Maintained
26 F: arch/x86/kernel/jailhouse.c
27 F: arch/x86/include/asm/jailhouse_para.h
28+F: drivers/virt/jailhouse_dbgcon.c
29
30 JC42.4 TEMPERATURE SENSOR DRIVER
31 M: Guenter Roeck <linux@roeck-us.net>
32--- a/drivers/virt/Kconfig
33+++ b/drivers/virt/Kconfig
34@@ -31,5 +31,16 @@ config FSL_HV_MANAGER
35 4) A kernel interface for receiving callbacks when a managed
36 partition shuts down.
37
38+config JAILHOUSE_DBGCON
39+ tristate "Jailhouse console driver"
40+ depends on X86 || ARM || ARM64
41+ help
42+ The Jailhouse hypervisor provides a simple write-only console for
43+ debugging the bootstrap process of its cells. This driver registers
44+ a console with the kernel to make use of it.
45+
46+ Note that Jailhouse has to be configured to permit a cell the usage
47+ of the console interface.
48+
49 source "drivers/virt/vboxguest/Kconfig"
50 endif
51--- a/drivers/virt/Makefile
52+++ b/drivers/virt/Makefile
53@@ -4,4 +4,5 @@
54 #
55
56 obj-$(CONFIG_FSL_HV_MANAGER) += fsl_hypervisor.o
57+obj-$(CONFIG_JAILHOUSE_DBGCON) += jailhouse_dbgcon.o
58 obj-y += vboxguest/
59--- /dev/null
60+++ b/drivers/virt/jailhouse_dbgcon.c
61@@ -0,0 +1,103 @@
62+/* SPDX-License-Identifier: GPL-2.0 */
63+/*
64+ * Console driver for running over the Jailhouse partitioning hypervisor
65+ *
66+ * Copyright (c) Siemens AG, 2016-2018
67+ *
68+ * Authors:
69+ * Jan Kiszka <jan.kiszka@siemens.com>
70+ */
71+
72+#include <linux/console.h>
73+#include <linux/hypervisor.h>
74+#include <linux/module.h>
75+#include <linux/serial_core.h>
76+#ifdef CONFIG_X86
77+#include <asm/alternative.h>
78+#endif
79+#ifdef CONFIG_ARM
80+#include <asm/opcodes-virt.h>
81+#endif
82+
83+#define JAILHOUSE_HC_DEBUG_CONSOLE_PUTC 8
84+
85+static void hypervisor_putc(char c)
86+{
87+#if defined(CONFIG_X86)
88+ int result;
89+
90+ asm volatile(
91+ ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9",
92+ X86_FEATURE_VMMCALL)
93+ : "=a" (result)
94+ : "a" (JAILHOUSE_HC_DEBUG_CONSOLE_PUTC), "D" (c)
95+ : "memory");
96+#elif defined(CONFIG_ARM)
97+ register u32 num_res asm("r0") = JAILHOUSE_HC_DEBUG_CONSOLE_PUTC;
98+ register u32 arg1 asm("r1") = c;
99+
100+ asm volatile(
101+ __HVC(0x4a48)
102+ : "=r" (num_res)
103+ : "r" (num_res), "r" (arg1)
104+ : "memory");
105+#elif defined(CONFIG_ARM64)
106+ register u64 num_res asm("x0") = JAILHOUSE_HC_DEBUG_CONSOLE_PUTC;
107+ register u64 arg1 asm("x1") = c;
108+
109+ asm volatile(
110+ "hvc #0x4a48\n\t"
111+ : "=r" (num_res)
112+ : "r" (num_res), "r" (arg1)
113+ : "memory");
114+#else
115+#error Unsupported architecture.
116+#endif
117+}
118+
119+static void jailhouse_dbgcon_write(struct console *con, const char *s,
120+ unsigned count)
121+{
122+ while (count > 0) {
123+ hypervisor_putc(*s);
124+ count--;
125+ s++;
126+ }
127+}
128+
129+static int __init early_jailhouse_dbgcon_setup(struct earlycon_device *device,
130+ const char *options)
131+{
132+ device->con->write = jailhouse_dbgcon_write;
133+ return 0;
134+}
135+
136+EARLYCON_DECLARE(jailhouse, early_jailhouse_dbgcon_setup);
137+
138+static struct console jailhouse_dbgcon = {
139+ .name = "jailhouse",
140+ .write = jailhouse_dbgcon_write,
141+ .flags = CON_PRINTBUFFER | CON_ANYTIME,
142+ .index = -1,
143+};
144+
145+static int __init jailhouse_dbgcon_init(void)
146+{
147+ if (!jailhouse_paravirt())
148+ return -ENODEV;
149+
150+ register_console(&jailhouse_dbgcon);
151+ return 0;
152+}
153+
154+static void __exit jailhouse_dbgcon_exit(void)
155+{
156+ unregister_console(&jailhouse_dbgcon);
157+}
158+
159+module_init(jailhouse_dbgcon_init);
160+module_exit(jailhouse_dbgcon_exit);
161+
162+MODULE_LICENSE("GPL v2");
163+MODULE_DESCRIPTION("Jailhouse debug console driver");
164+MODULE_AUTHOR("Jan Kiszka <jan.kiszka@siemens.com>");