1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Based on the same principle as kgdboe using the NETPOLL api, this
4  * driver uses a console polling api to implement a gdb serial inteface
5  * which is multiplexed on a console port.
6  *
7  * Maintainer: Jason Wessel <jason.wessel@windriver.com>
8  *
9  * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc.
10  */
11 #include <linux/kernel.h>
12 #include <linux/ctype.h>
13 #include <linux/kgdb.h>
14 #include <linux/kdb.h>
15 #include <linux/tty.h>
16 #include <linux/console.h>
17 #include <linux/vt_kern.h>
18 #include <linux/input.h>
19 #include <linux/module.h>
20 
21 #define MAX_CONFIG_LEN		40
22 
23 static struct kgdb_io		kgdboc_io_ops;
24 
25 /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
26 static int configured		= -1;
27 
28 static char config[MAX_CONFIG_LEN];
29 static struct kparam_string kps = {
30 	.string			= config,
31 	.maxlen			= MAX_CONFIG_LEN,
32 };
33 
34 static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
35 static struct tty_driver	*kgdb_tty_driver;
36 static int			kgdb_tty_line;
37 
38 #ifdef CONFIG_KDB_KEYBOARD
kgdboc_reset_connect(struct input_handler * handler,struct input_dev * dev,const struct input_device_id * id)39 static int kgdboc_reset_connect(struct input_handler *handler,
40 				struct input_dev *dev,
41 				const struct input_device_id *id)
42 {
43 	input_reset_device(dev);
44 
45 	/* Return an error - we do not want to bind, just to reset */
46 	return -ENODEV;
47 }
48 
kgdboc_reset_disconnect(struct input_handle * handle)49 static void kgdboc_reset_disconnect(struct input_handle *handle)
50 {
51 	/* We do not expect anyone to actually bind to us */
52 	BUG();
53 }
54 
55 static const struct input_device_id kgdboc_reset_ids[] = {
56 	{
57 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
58 		.evbit = { BIT_MASK(EV_KEY) },
59 	},
60 	{ }
61 };
62 
63 static struct input_handler kgdboc_reset_handler = {
64 	.connect	= kgdboc_reset_connect,
65 	.disconnect	= kgdboc_reset_disconnect,
66 	.name		= "kgdboc_reset",
67 	.id_table	= kgdboc_reset_ids,
68 };
69 
70 static DEFINE_MUTEX(kgdboc_reset_mutex);
71 
kgdboc_restore_input_helper(struct work_struct * dummy)72 static void kgdboc_restore_input_helper(struct work_struct *dummy)
73 {
74 	/*
75 	 * We need to take a mutex to prevent several instances of
76 	 * this work running on different CPUs so they don't try
77 	 * to register again already registered handler.
78 	 */
79 	mutex_lock(&kgdboc_reset_mutex);
80 
81 	if (input_register_handler(&kgdboc_reset_handler) == 0)
82 		input_unregister_handler(&kgdboc_reset_handler);
83 
84 	mutex_unlock(&kgdboc_reset_mutex);
85 }
86 
87 static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
88 
kgdboc_restore_input(void)89 static void kgdboc_restore_input(void)
90 {
91 	if (likely(system_state == SYSTEM_RUNNING))
92 		schedule_work(&kgdboc_restore_input_work);
93 }
94 
kgdboc_register_kbd(char ** cptr)95 static int kgdboc_register_kbd(char **cptr)
96 {
97 	if (strncmp(*cptr, "kbd", 3) == 0 ||
98 		strncmp(*cptr, "kdb", 3) == 0) {
99 		if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
100 			kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
101 			kdb_poll_idx++;
102 			if (cptr[0][3] == ',')
103 				*cptr += 4;
104 			else
105 				return 1;
106 		}
107 	}
108 	return 0;
109 }
110 
kgdboc_unregister_kbd(void)111 static void kgdboc_unregister_kbd(void)
112 {
113 	int i;
114 
115 	for (i = 0; i < kdb_poll_idx; i++) {
116 		if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
117 			kdb_poll_idx--;
118 			kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
119 			kdb_poll_funcs[kdb_poll_idx] = NULL;
120 			i--;
121 		}
122 	}
123 	flush_work(&kgdboc_restore_input_work);
124 }
125 #else /* ! CONFIG_KDB_KEYBOARD */
126 #define kgdboc_register_kbd(x) 0
127 #define kgdboc_unregister_kbd()
128 #define kgdboc_restore_input()
129 #endif /* ! CONFIG_KDB_KEYBOARD */
130 
kgdboc_option_setup(char * opt)131 static int kgdboc_option_setup(char *opt)
132 {
133 	if (strlen(opt) >= MAX_CONFIG_LEN) {
134 		printk(KERN_ERR "kgdboc: config string too long\n");
135 		return -ENOSPC;
136 	}
137 	strcpy(config, opt);
138 
139 	return 0;
140 }
141 
142 __setup("kgdboc=", kgdboc_option_setup);
143 
cleanup_kgdboc(void)144 static void cleanup_kgdboc(void)
145 {
146 	if (kgdb_unregister_nmi_console())
147 		return;
148 	kgdboc_unregister_kbd();
149 	if (configured == 1)
150 		kgdb_unregister_io_module(&kgdboc_io_ops);
151 }
152 
configure_kgdboc(void)153 static int configure_kgdboc(void)
154 {
155 	struct tty_driver *p;
156 	int tty_line = 0;
157 	int err;
158 	char *cptr = config;
159 	struct console *cons;
160 
161 	err = kgdboc_option_setup(config);
162 	if (err || !strlen(config) || isspace(config[0]))
163 		goto noconfig;
164 
165 	err = -ENODEV;
166 	kgdboc_io_ops.is_console = 0;
167 	kgdb_tty_driver = NULL;
168 
169 	kgdboc_use_kms = 0;
170 	if (strncmp(cptr, "kms,", 4) == 0) {
171 		cptr += 4;
172 		kgdboc_use_kms = 1;
173 	}
174 
175 	if (kgdboc_register_kbd(&cptr))
176 		goto do_register;
177 
178 	p = tty_find_polling_driver(cptr, &tty_line);
179 	if (!p)
180 		goto noconfig;
181 
182 	cons = console_drivers;
183 	while (cons) {
184 		int idx;
185 		if (cons->device && cons->device(cons, &idx) == p &&
186 		    idx == tty_line) {
187 			kgdboc_io_ops.is_console = 1;
188 			break;
189 		}
190 		cons = cons->next;
191 	}
192 
193 	kgdb_tty_driver = p;
194 	kgdb_tty_line = tty_line;
195 
196 do_register:
197 	err = kgdb_register_io_module(&kgdboc_io_ops);
198 	if (err)
199 		goto noconfig;
200 
201 	err = kgdb_register_nmi_console();
202 	if (err)
203 		goto nmi_con_failed;
204 
205 	configured = 1;
206 
207 	return 0;
208 
209 nmi_con_failed:
210 	kgdb_unregister_io_module(&kgdboc_io_ops);
211 noconfig:
212 	kgdboc_unregister_kbd();
213 	config[0] = 0;
214 	configured = 0;
215 	cleanup_kgdboc();
216 
217 	return err;
218 }
219 
init_kgdboc(void)220 static int __init init_kgdboc(void)
221 {
222 	/* Already configured? */
223 	if (configured == 1)
224 		return 0;
225 
226 	return configure_kgdboc();
227 }
228 
kgdboc_get_char(void)229 static int kgdboc_get_char(void)
230 {
231 	if (!kgdb_tty_driver)
232 		return -1;
233 	return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
234 						kgdb_tty_line);
235 }
236 
kgdboc_put_char(u8 chr)237 static void kgdboc_put_char(u8 chr)
238 {
239 	if (!kgdb_tty_driver)
240 		return;
241 	kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
242 					kgdb_tty_line, chr);
243 }
244 
param_set_kgdboc_var(const char * kmessage,const struct kernel_param * kp)245 static int param_set_kgdboc_var(const char *kmessage,
246 				const struct kernel_param *kp)
247 {
248 	int len = strlen(kmessage);
249 
250 	if (len >= MAX_CONFIG_LEN) {
251 		printk(KERN_ERR "kgdboc: config string too long\n");
252 		return -ENOSPC;
253 	}
254 
255 	/* Only copy in the string if the init function has not run yet */
256 	if (configured < 0) {
257 		strcpy(config, kmessage);
258 		return 0;
259 	}
260 
261 	if (kgdb_connected) {
262 		printk(KERN_ERR
263 		       "kgdboc: Cannot reconfigure while KGDB is connected.\n");
264 
265 		return -EBUSY;
266 	}
267 
268 	strcpy(config, kmessage);
269 	/* Chop out \n char as a result of echo */
270 	if (config[len - 1] == '\n')
271 		config[len - 1] = '\0';
272 
273 	if (configured == 1)
274 		cleanup_kgdboc();
275 
276 	/* Go and configure with the new params. */
277 	return configure_kgdboc();
278 }
279 
280 static int dbg_restore_graphics;
281 
kgdboc_pre_exp_handler(void)282 static void kgdboc_pre_exp_handler(void)
283 {
284 	if (!dbg_restore_graphics && kgdboc_use_kms) {
285 		dbg_restore_graphics = 1;
286 		con_debug_enter(vc_cons[fg_console].d);
287 	}
288 	/* Increment the module count when the debugger is active */
289 	if (!kgdb_connected)
290 		try_module_get(THIS_MODULE);
291 }
292 
kgdboc_post_exp_handler(void)293 static void kgdboc_post_exp_handler(void)
294 {
295 	/* decrement the module count when the debugger detaches */
296 	if (!kgdb_connected)
297 		module_put(THIS_MODULE);
298 	if (kgdboc_use_kms && dbg_restore_graphics) {
299 		dbg_restore_graphics = 0;
300 		con_debug_leave();
301 	}
302 	kgdboc_restore_input();
303 }
304 
305 static struct kgdb_io kgdboc_io_ops = {
306 	.name			= "kgdboc",
307 	.read_char		= kgdboc_get_char,
308 	.write_char		= kgdboc_put_char,
309 	.pre_exception		= kgdboc_pre_exp_handler,
310 	.post_exception		= kgdboc_post_exp_handler,
311 };
312 
313 #ifdef CONFIG_KGDB_SERIAL_CONSOLE
314 /* This is only available if kgdboc is a built in for early debugging */
kgdboc_early_init(char * opt)315 static int __init kgdboc_early_init(char *opt)
316 {
317 	/* save the first character of the config string because the
318 	 * init routine can destroy it.
319 	 */
320 	char save_ch;
321 
322 	kgdboc_option_setup(opt);
323 	save_ch = config[0];
324 	init_kgdboc();
325 	config[0] = save_ch;
326 	return 0;
327 }
328 
329 early_param("ekgdboc", kgdboc_early_init);
330 #endif /* CONFIG_KGDB_SERIAL_CONSOLE */
331 
332 module_init(init_kgdboc);
333 module_exit(cleanup_kgdboc);
334 module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
335 MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
336 MODULE_DESCRIPTION("KGDB Console TTY Driver");
337 MODULE_LICENSE("GPL");
338