.. | .. |
---|
19 | 19 | #include <linux/sched/rt.h> |
---|
20 | 20 | #include <linux/sched/debug.h> |
---|
21 | 21 | #include <linux/sched/task.h> |
---|
| 22 | +#include <linux/ctype.h> |
---|
22 | 23 | #include <linux/interrupt.h> |
---|
23 | 24 | #include <linux/mm.h> |
---|
24 | 25 | #include <linux/fs.h> |
---|
.. | .. |
---|
63 | 64 | return sysrq_enabled || sysrq_always_enabled; |
---|
64 | 65 | } |
---|
65 | 66 | |
---|
| 67 | +/** |
---|
| 68 | + * sysrq_mask - Getter for sysrq_enabled mask. |
---|
| 69 | + * |
---|
| 70 | + * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise. |
---|
| 71 | + */ |
---|
| 72 | +int sysrq_mask(void) |
---|
| 73 | +{ |
---|
| 74 | + if (sysrq_always_enabled) |
---|
| 75 | + return 1; |
---|
| 76 | + return sysrq_enabled; |
---|
| 77 | +} |
---|
| 78 | +EXPORT_SYMBOL_GPL(sysrq_mask); |
---|
| 79 | + |
---|
66 | 80 | /* |
---|
67 | 81 | * A value of 1 means 'all', other nonzero values are an op mask: |
---|
68 | 82 | */ |
---|
.. | .. |
---|
93 | 107 | pr_info("Loglevel set to %d\n", i); |
---|
94 | 108 | console_loglevel = i; |
---|
95 | 109 | } |
---|
96 | | -static struct sysrq_key_op sysrq_loglevel_op = { |
---|
| 110 | +static const struct sysrq_key_op sysrq_loglevel_op = { |
---|
97 | 111 | .handler = sysrq_handle_loglevel, |
---|
98 | 112 | .help_msg = "loglevel(0-9)", |
---|
99 | 113 | .action_msg = "Changing Loglevel", |
---|
.. | .. |
---|
106 | 120 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; |
---|
107 | 121 | schedule_work(SAK_work); |
---|
108 | 122 | } |
---|
109 | | -static struct sysrq_key_op sysrq_SAK_op = { |
---|
| 123 | +static const struct sysrq_key_op sysrq_SAK_op = { |
---|
110 | 124 | .handler = sysrq_handle_SAK, |
---|
111 | 125 | .help_msg = "sak(k)", |
---|
112 | 126 | .action_msg = "SAK", |
---|
113 | 127 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, |
---|
114 | 128 | }; |
---|
115 | 129 | #else |
---|
116 | | -#define sysrq_SAK_op (*(struct sysrq_key_op *)NULL) |
---|
| 130 | +#define sysrq_SAK_op (*(const struct sysrq_key_op *)NULL) |
---|
117 | 131 | #endif |
---|
118 | 132 | |
---|
119 | 133 | #ifdef CONFIG_VT |
---|
.. | .. |
---|
122 | 136 | vt_reset_unicode(fg_console); |
---|
123 | 137 | } |
---|
124 | 138 | |
---|
125 | | -static struct sysrq_key_op sysrq_unraw_op = { |
---|
| 139 | +static const struct sysrq_key_op sysrq_unraw_op = { |
---|
126 | 140 | .handler = sysrq_handle_unraw, |
---|
127 | 141 | .help_msg = "unraw(r)", |
---|
128 | 142 | .action_msg = "Keyboard mode set to system default", |
---|
129 | 143 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, |
---|
130 | 144 | }; |
---|
131 | 145 | #else |
---|
132 | | -#define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) |
---|
| 146 | +#define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL) |
---|
133 | 147 | #endif /* CONFIG_VT */ |
---|
134 | 148 | |
---|
135 | 149 | static void sysrq_handle_crash(int key) |
---|
.. | .. |
---|
139 | 153 | |
---|
140 | 154 | panic("sysrq triggered crash\n"); |
---|
141 | 155 | } |
---|
142 | | -static struct sysrq_key_op sysrq_crash_op = { |
---|
| 156 | +static const struct sysrq_key_op sysrq_crash_op = { |
---|
143 | 157 | .handler = sysrq_handle_crash, |
---|
144 | 158 | .help_msg = "crash(c)", |
---|
145 | 159 | .action_msg = "Trigger a crash", |
---|
.. | .. |
---|
152 | 166 | local_irq_enable(); |
---|
153 | 167 | emergency_restart(); |
---|
154 | 168 | } |
---|
155 | | -static struct sysrq_key_op sysrq_reboot_op = { |
---|
| 169 | +static const struct sysrq_key_op sysrq_reboot_op = { |
---|
156 | 170 | .handler = sysrq_handle_reboot, |
---|
157 | 171 | .help_msg = "reboot(b)", |
---|
158 | 172 | .action_msg = "Resetting", |
---|
159 | 173 | .enable_mask = SYSRQ_ENABLE_BOOT, |
---|
160 | 174 | }; |
---|
161 | 175 | |
---|
| 176 | +const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; |
---|
| 177 | + |
---|
162 | 178 | static void sysrq_handle_sync(int key) |
---|
163 | 179 | { |
---|
164 | 180 | emergency_sync(); |
---|
165 | 181 | } |
---|
166 | | -static struct sysrq_key_op sysrq_sync_op = { |
---|
| 182 | +static const struct sysrq_key_op sysrq_sync_op = { |
---|
167 | 183 | .handler = sysrq_handle_sync, |
---|
168 | 184 | .help_msg = "sync(s)", |
---|
169 | 185 | .action_msg = "Emergency Sync", |
---|
.. | .. |
---|
175 | 191 | sysrq_timer_list_show(); |
---|
176 | 192 | } |
---|
177 | 193 | |
---|
178 | | -static struct sysrq_key_op sysrq_show_timers_op = { |
---|
| 194 | +static const struct sysrq_key_op sysrq_show_timers_op = { |
---|
179 | 195 | .handler = sysrq_handle_show_timers, |
---|
180 | 196 | .help_msg = "show-all-timers(q)", |
---|
181 | 197 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
---|
.. | .. |
---|
185 | 201 | { |
---|
186 | 202 | emergency_remount(); |
---|
187 | 203 | } |
---|
188 | | -static struct sysrq_key_op sysrq_mountro_op = { |
---|
| 204 | +static const struct sysrq_key_op sysrq_mountro_op = { |
---|
189 | 205 | .handler = sysrq_handle_mountro, |
---|
190 | 206 | .help_msg = "unmount(u)", |
---|
191 | 207 | .action_msg = "Emergency Remount R/O", |
---|
.. | .. |
---|
198 | 214 | debug_show_all_locks(); |
---|
199 | 215 | } |
---|
200 | 216 | |
---|
201 | | -static struct sysrq_key_op sysrq_showlocks_op = { |
---|
| 217 | +static const struct sysrq_key_op sysrq_showlocks_op = { |
---|
202 | 218 | .handler = sysrq_handle_showlocks, |
---|
203 | 219 | .help_msg = "show-all-locks(d)", |
---|
204 | 220 | .action_msg = "Show Locks Held", |
---|
205 | 221 | }; |
---|
206 | 222 | #else |
---|
207 | | -#define sysrq_showlocks_op (*(struct sysrq_key_op *)NULL) |
---|
| 223 | +#define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL) |
---|
208 | 224 | #endif |
---|
209 | 225 | |
---|
210 | 226 | #ifdef CONFIG_SMP |
---|
211 | | -static DEFINE_SPINLOCK(show_lock); |
---|
| 227 | +static DEFINE_RAW_SPINLOCK(show_lock); |
---|
212 | 228 | |
---|
213 | 229 | static void showacpu(void *dummy) |
---|
214 | 230 | { |
---|
215 | 231 | unsigned long flags; |
---|
216 | 232 | |
---|
217 | 233 | /* Idle CPUs have no interesting backtrace. */ |
---|
218 | | - if (idle_cpu(smp_processor_id())) |
---|
| 234 | + if (idle_cpu(smp_processor_id())) { |
---|
| 235 | + pr_info("CPU%d: backtrace skipped as idling\n", smp_processor_id()); |
---|
219 | 236 | return; |
---|
| 237 | + } |
---|
220 | 238 | |
---|
221 | | - spin_lock_irqsave(&show_lock, flags); |
---|
| 239 | + raw_spin_lock_irqsave(&show_lock, flags); |
---|
222 | 240 | pr_info("CPU%d:\n", smp_processor_id()); |
---|
223 | | - show_stack(NULL, NULL); |
---|
224 | | - spin_unlock_irqrestore(&show_lock, flags); |
---|
| 241 | + show_stack(NULL, NULL, KERN_INFO); |
---|
| 242 | + raw_spin_unlock_irqrestore(&show_lock, flags); |
---|
225 | 243 | } |
---|
226 | 244 | |
---|
227 | 245 | static void sysrq_showregs_othercpus(struct work_struct *dummy) |
---|
.. | .. |
---|
243 | 261 | |
---|
244 | 262 | if (in_irq()) |
---|
245 | 263 | regs = get_irq_regs(); |
---|
246 | | - if (regs) { |
---|
247 | | - pr_info("CPU%d:\n", smp_processor_id()); |
---|
| 264 | + |
---|
| 265 | + pr_info("CPU%d:\n", smp_processor_id()); |
---|
| 266 | + if (regs) |
---|
248 | 267 | show_regs(regs); |
---|
249 | | - } |
---|
| 268 | + else |
---|
| 269 | + show_stack(NULL, NULL, KERN_INFO); |
---|
| 270 | + |
---|
250 | 271 | schedule_work(&sysrq_showallcpus); |
---|
251 | 272 | } |
---|
252 | 273 | } |
---|
253 | 274 | |
---|
254 | | -static struct sysrq_key_op sysrq_showallcpus_op = { |
---|
| 275 | +static const struct sysrq_key_op sysrq_showallcpus_op = { |
---|
255 | 276 | .handler = sysrq_handle_showallcpus, |
---|
256 | 277 | .help_msg = "show-backtrace-all-active-cpus(l)", |
---|
257 | 278 | .action_msg = "Show backtrace of all active CPUs", |
---|
.. | .. |
---|
269 | 290 | show_regs(regs); |
---|
270 | 291 | perf_event_print_debug(); |
---|
271 | 292 | } |
---|
272 | | -static struct sysrq_key_op sysrq_showregs_op = { |
---|
| 293 | +static const struct sysrq_key_op sysrq_showregs_op = { |
---|
273 | 294 | .handler = sysrq_handle_showregs, |
---|
274 | 295 | .help_msg = "show-registers(p)", |
---|
275 | 296 | .action_msg = "Show Regs", |
---|
.. | .. |
---|
281 | 302 | show_state(); |
---|
282 | 303 | show_workqueue_state(); |
---|
283 | 304 | } |
---|
284 | | -static struct sysrq_key_op sysrq_showstate_op = { |
---|
| 305 | +static const struct sysrq_key_op sysrq_showstate_op = { |
---|
285 | 306 | .handler = sysrq_handle_showstate, |
---|
286 | 307 | .help_msg = "show-task-states(t)", |
---|
287 | 308 | .action_msg = "Show State", |
---|
.. | .. |
---|
292 | 313 | { |
---|
293 | 314 | show_state_filter(TASK_UNINTERRUPTIBLE); |
---|
294 | 315 | } |
---|
295 | | -static struct sysrq_key_op sysrq_showstate_blocked_op = { |
---|
| 316 | +static const struct sysrq_key_op sysrq_showstate_blocked_op = { |
---|
296 | 317 | .handler = sysrq_handle_showstate_blocked, |
---|
297 | 318 | .help_msg = "show-blocked-tasks(w)", |
---|
298 | 319 | .action_msg = "Show Blocked State", |
---|
.. | .. |
---|
306 | 327 | { |
---|
307 | 328 | ftrace_dump(DUMP_ALL); |
---|
308 | 329 | } |
---|
309 | | -static struct sysrq_key_op sysrq_ftrace_dump_op = { |
---|
| 330 | +static const struct sysrq_key_op sysrq_ftrace_dump_op = { |
---|
310 | 331 | .handler = sysrq_ftrace_dump, |
---|
311 | 332 | .help_msg = "dump-ftrace-buffer(z)", |
---|
312 | 333 | .action_msg = "Dump ftrace buffer", |
---|
313 | 334 | .enable_mask = SYSRQ_ENABLE_DUMP, |
---|
314 | 335 | }; |
---|
315 | 336 | #else |
---|
316 | | -#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) |
---|
| 337 | +#define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) |
---|
317 | 338 | #endif |
---|
318 | 339 | |
---|
319 | 340 | static void sysrq_handle_showmem(int key) |
---|
320 | 341 | { |
---|
321 | 342 | show_mem(0, NULL); |
---|
322 | 343 | } |
---|
323 | | -static struct sysrq_key_op sysrq_showmem_op = { |
---|
| 344 | +static const struct sysrq_key_op sysrq_showmem_op = { |
---|
324 | 345 | .handler = sysrq_handle_showmem, |
---|
325 | 346 | .help_msg = "show-memory-usage(m)", |
---|
326 | 347 | .action_msg = "Show Memory", |
---|
.. | .. |
---|
341 | 362 | if (is_global_init(p)) |
---|
342 | 363 | continue; |
---|
343 | 364 | |
---|
344 | | - do_send_sig_info(sig, SEND_SIG_FORCED, p, PIDTYPE_MAX); |
---|
| 365 | + do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); |
---|
345 | 366 | } |
---|
346 | 367 | read_unlock(&tasklist_lock); |
---|
347 | 368 | } |
---|
.. | .. |
---|
351 | 372 | send_sig_all(SIGTERM); |
---|
352 | 373 | console_loglevel = CONSOLE_LOGLEVEL_DEBUG; |
---|
353 | 374 | } |
---|
354 | | -static struct sysrq_key_op sysrq_term_op = { |
---|
| 375 | +static const struct sysrq_key_op sysrq_term_op = { |
---|
355 | 376 | .handler = sysrq_handle_term, |
---|
356 | 377 | .help_msg = "terminate-all-tasks(e)", |
---|
357 | 378 | .action_msg = "Terminate All Tasks", |
---|
.. | .. |
---|
381 | 402 | { |
---|
382 | 403 | schedule_work(&moom_work); |
---|
383 | 404 | } |
---|
384 | | -static struct sysrq_key_op sysrq_moom_op = { |
---|
| 405 | +static const struct sysrq_key_op sysrq_moom_op = { |
---|
385 | 406 | .handler = sysrq_handle_moom, |
---|
386 | 407 | .help_msg = "memory-full-oom-kill(f)", |
---|
387 | 408 | .action_msg = "Manual OOM execution", |
---|
388 | 409 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
---|
389 | 410 | }; |
---|
390 | 411 | |
---|
391 | | -#ifdef CONFIG_BLOCK |
---|
392 | 412 | static void sysrq_handle_thaw(int key) |
---|
393 | 413 | { |
---|
394 | 414 | emergency_thaw_all(); |
---|
395 | 415 | } |
---|
396 | | -static struct sysrq_key_op sysrq_thaw_op = { |
---|
| 416 | +static const struct sysrq_key_op sysrq_thaw_op = { |
---|
397 | 417 | .handler = sysrq_handle_thaw, |
---|
398 | 418 | .help_msg = "thaw-filesystems(j)", |
---|
399 | 419 | .action_msg = "Emergency Thaw of all frozen filesystems", |
---|
400 | 420 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
---|
401 | 421 | }; |
---|
402 | | -#endif |
---|
403 | 422 | |
---|
404 | 423 | static void sysrq_handle_kill(int key) |
---|
405 | 424 | { |
---|
406 | 425 | send_sig_all(SIGKILL); |
---|
407 | 426 | console_loglevel = CONSOLE_LOGLEVEL_DEBUG; |
---|
408 | 427 | } |
---|
409 | | -static struct sysrq_key_op sysrq_kill_op = { |
---|
| 428 | +static const struct sysrq_key_op sysrq_kill_op = { |
---|
410 | 429 | .handler = sysrq_handle_kill, |
---|
411 | 430 | .help_msg = "kill-all-tasks(i)", |
---|
412 | 431 | .action_msg = "Kill All Tasks", |
---|
.. | .. |
---|
417 | 436 | { |
---|
418 | 437 | normalize_rt_tasks(); |
---|
419 | 438 | } |
---|
420 | | -static struct sysrq_key_op sysrq_unrt_op = { |
---|
| 439 | +static const struct sysrq_key_op sysrq_unrt_op = { |
---|
421 | 440 | .handler = sysrq_handle_unrt, |
---|
422 | 441 | .help_msg = "nice-all-RT-tasks(n)", |
---|
423 | 442 | .action_msg = "Nice All RT Tasks", |
---|
.. | .. |
---|
427 | 446 | /* Key Operations table and lock */ |
---|
428 | 447 | static DEFINE_SPINLOCK(sysrq_key_table_lock); |
---|
429 | 448 | |
---|
430 | | -static struct sysrq_key_op *sysrq_key_table[36] = { |
---|
| 449 | +static const struct sysrq_key_op *sysrq_key_table[62] = { |
---|
431 | 450 | &sysrq_loglevel_op, /* 0 */ |
---|
432 | 451 | &sysrq_loglevel_op, /* 1 */ |
---|
433 | 452 | &sysrq_loglevel_op, /* 2 */ |
---|
.. | .. |
---|
484 | 503 | /* y: May be registered on sparc64 for global register dump */ |
---|
485 | 504 | NULL, /* y */ |
---|
486 | 505 | &sysrq_ftrace_dump_op, /* z */ |
---|
| 506 | + NULL, /* A */ |
---|
| 507 | + NULL, /* B */ |
---|
| 508 | + NULL, /* C */ |
---|
| 509 | + NULL, /* D */ |
---|
| 510 | + NULL, /* E */ |
---|
| 511 | + NULL, /* F */ |
---|
| 512 | + NULL, /* G */ |
---|
| 513 | + NULL, /* H */ |
---|
| 514 | + NULL, /* I */ |
---|
| 515 | + NULL, /* J */ |
---|
| 516 | + NULL, /* K */ |
---|
| 517 | + NULL, /* L */ |
---|
| 518 | + NULL, /* M */ |
---|
| 519 | + NULL, /* N */ |
---|
| 520 | + NULL, /* O */ |
---|
| 521 | + NULL, /* P */ |
---|
| 522 | + NULL, /* Q */ |
---|
| 523 | + NULL, /* R */ |
---|
| 524 | + NULL, /* S */ |
---|
| 525 | + NULL, /* T */ |
---|
| 526 | + NULL, /* U */ |
---|
| 527 | + NULL, /* V */ |
---|
| 528 | + NULL, /* W */ |
---|
| 529 | + NULL, /* X */ |
---|
| 530 | + NULL, /* Y */ |
---|
| 531 | + NULL, /* Z */ |
---|
487 | 532 | }; |
---|
488 | 533 | |
---|
489 | 534 | /* key2index calculation, -1 on invalid index */ |
---|
.. | .. |
---|
495 | 540 | retval = key - '0'; |
---|
496 | 541 | else if ((key >= 'a') && (key <= 'z')) |
---|
497 | 542 | retval = key + 10 - 'a'; |
---|
| 543 | + else if ((key >= 'A') && (key <= 'Z')) |
---|
| 544 | + retval = key + 36 - 'A'; |
---|
498 | 545 | else |
---|
499 | 546 | retval = -1; |
---|
500 | 547 | return retval; |
---|
.. | .. |
---|
503 | 550 | /* |
---|
504 | 551 | * get and put functions for the table, exposed to modules. |
---|
505 | 552 | */ |
---|
506 | | -struct sysrq_key_op *__sysrq_get_key_op(int key) |
---|
| 553 | +static const struct sysrq_key_op *__sysrq_get_key_op(int key) |
---|
507 | 554 | { |
---|
508 | | - struct sysrq_key_op *op_p = NULL; |
---|
| 555 | + const struct sysrq_key_op *op_p = NULL; |
---|
509 | 556 | int i; |
---|
510 | 557 | |
---|
511 | 558 | i = sysrq_key_table_key2index(key); |
---|
.. | .. |
---|
515 | 562 | return op_p; |
---|
516 | 563 | } |
---|
517 | 564 | |
---|
518 | | -static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) |
---|
| 565 | +static void __sysrq_put_key_op(int key, const struct sysrq_key_op *op_p) |
---|
519 | 566 | { |
---|
520 | 567 | int i = sysrq_key_table_key2index(key); |
---|
521 | 568 | |
---|
.. | .. |
---|
525 | 572 | |
---|
526 | 573 | void __handle_sysrq(int key, bool check_mask) |
---|
527 | 574 | { |
---|
528 | | - struct sysrq_key_op *op_p; |
---|
| 575 | + const struct sysrq_key_op *op_p; |
---|
529 | 576 | int orig_log_level; |
---|
| 577 | + int orig_suppress_printk; |
---|
530 | 578 | int i; |
---|
| 579 | + |
---|
| 580 | + orig_suppress_printk = suppress_printk; |
---|
| 581 | + suppress_printk = 0; |
---|
531 | 582 | |
---|
532 | 583 | rcu_sysrq_start(); |
---|
533 | 584 | rcu_read_lock(); |
---|
.. | .. |
---|
574 | 625 | } |
---|
575 | 626 | rcu_read_unlock(); |
---|
576 | 627 | rcu_sysrq_end(); |
---|
| 628 | + |
---|
| 629 | + suppress_printk = orig_suppress_printk; |
---|
577 | 630 | } |
---|
578 | 631 | |
---|
579 | 632 | void handle_sysrq(int key) |
---|
.. | .. |
---|
602 | 655 | unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; |
---|
603 | 656 | unsigned int alt; |
---|
604 | 657 | unsigned int alt_use; |
---|
| 658 | + unsigned int shift; |
---|
| 659 | + unsigned int shift_use; |
---|
605 | 660 | bool active; |
---|
606 | 661 | bool need_reinject; |
---|
607 | 662 | bool reinjecting; |
---|
.. | .. |
---|
653 | 708 | |
---|
654 | 709 | state->reset_requested = true; |
---|
655 | 710 | |
---|
656 | | - ksys_sync(); |
---|
657 | | - kernel_restart(NULL); |
---|
| 711 | + orderly_reboot(); |
---|
658 | 712 | } |
---|
659 | 713 | |
---|
660 | 714 | static void sysrq_handle_reset_request(struct sysrq_state *state) |
---|
.. | .. |
---|
729 | 783 | |
---|
730 | 784 | /* Get reset timeout if any. */ |
---|
731 | 785 | of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms); |
---|
| 786 | + |
---|
| 787 | + of_node_put(np); |
---|
732 | 788 | } |
---|
733 | 789 | #else |
---|
734 | 790 | static void sysrq_of_get_keyreset_config(void) |
---|
.. | .. |
---|
785 | 841 | } |
---|
786 | 842 | break; |
---|
787 | 843 | |
---|
| 844 | + case KEY_LEFTSHIFT: |
---|
| 845 | + case KEY_RIGHTSHIFT: |
---|
| 846 | + if (!value) |
---|
| 847 | + sysrq->shift = KEY_RESERVED; |
---|
| 848 | + else if (value != 2) |
---|
| 849 | + sysrq->shift = code; |
---|
| 850 | + break; |
---|
| 851 | + |
---|
788 | 852 | case KEY_SYSRQ: |
---|
789 | 853 | if (value == 1 && sysrq->alt != KEY_RESERVED) { |
---|
790 | 854 | sysrq->active = true; |
---|
791 | 855 | sysrq->alt_use = sysrq->alt; |
---|
| 856 | + /* either RESERVED (for released) or actual code */ |
---|
| 857 | + sysrq->shift_use = sysrq->shift; |
---|
792 | 858 | /* |
---|
793 | 859 | * If nothing else will be pressed we'll need |
---|
794 | 860 | * to re-inject Alt-SysRq keysroke. |
---|
.. | .. |
---|
811 | 877 | |
---|
812 | 878 | default: |
---|
813 | 879 | if (sysrq->active && value && value != 2) { |
---|
| 880 | + unsigned char c = sysrq_xlate[code]; |
---|
| 881 | + |
---|
814 | 882 | sysrq->need_reinject = false; |
---|
815 | | - __handle_sysrq(sysrq_xlate[code], true); |
---|
| 883 | + if (sysrq->shift_use != KEY_RESERVED) |
---|
| 884 | + c = toupper(c); |
---|
| 885 | + __handle_sysrq(c, true); |
---|
816 | 886 | } |
---|
817 | 887 | break; |
---|
818 | 888 | } |
---|
.. | .. |
---|
960 | 1030 | .id_table = sysrq_ids, |
---|
961 | 1031 | }; |
---|
962 | 1032 | |
---|
963 | | -static bool sysrq_handler_registered; |
---|
964 | | - |
---|
965 | 1033 | static inline void sysrq_register_handler(void) |
---|
966 | 1034 | { |
---|
967 | 1035 | int error; |
---|
.. | .. |
---|
971 | 1039 | error = input_register_handler(&sysrq_handler); |
---|
972 | 1040 | if (error) |
---|
973 | 1041 | pr_err("Failed to register input handler, error %d", error); |
---|
974 | | - else |
---|
975 | | - sysrq_handler_registered = true; |
---|
976 | 1042 | } |
---|
977 | 1043 | |
---|
978 | 1044 | static inline void sysrq_unregister_handler(void) |
---|
979 | 1045 | { |
---|
980 | | - if (sysrq_handler_registered) { |
---|
981 | | - input_unregister_handler(&sysrq_handler); |
---|
982 | | - sysrq_handler_registered = false; |
---|
983 | | - } |
---|
| 1046 | + input_unregister_handler(&sysrq_handler); |
---|
984 | 1047 | } |
---|
985 | 1048 | |
---|
986 | 1049 | static int sysrq_reset_seq_param_set(const char *buffer, |
---|
.. | .. |
---|
1046 | 1109 | |
---|
1047 | 1110 | return 0; |
---|
1048 | 1111 | } |
---|
| 1112 | +EXPORT_SYMBOL_GPL(sysrq_toggle_support); |
---|
1049 | 1113 | |
---|
1050 | | -static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, |
---|
1051 | | - struct sysrq_key_op *remove_op_p) |
---|
| 1114 | +static int __sysrq_swap_key_ops(int key, const struct sysrq_key_op *insert_op_p, |
---|
| 1115 | + const struct sysrq_key_op *remove_op_p) |
---|
1052 | 1116 | { |
---|
1053 | 1117 | int retval; |
---|
1054 | 1118 | |
---|
.. | .. |
---|
1071 | 1135 | return retval; |
---|
1072 | 1136 | } |
---|
1073 | 1137 | |
---|
1074 | | -int register_sysrq_key(int key, struct sysrq_key_op *op_p) |
---|
| 1138 | +int register_sysrq_key(int key, const struct sysrq_key_op *op_p) |
---|
1075 | 1139 | { |
---|
1076 | 1140 | return __sysrq_swap_key_ops(key, op_p, NULL); |
---|
1077 | 1141 | } |
---|
1078 | 1142 | EXPORT_SYMBOL(register_sysrq_key); |
---|
1079 | 1143 | |
---|
1080 | | -int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) |
---|
| 1144 | +int unregister_sysrq_key(int key, const struct sysrq_key_op *op_p) |
---|
1081 | 1145 | { |
---|
1082 | 1146 | return __sysrq_swap_key_ops(key, NULL, op_p); |
---|
1083 | 1147 | } |
---|
.. | .. |
---|
1101 | 1165 | return count; |
---|
1102 | 1166 | } |
---|
1103 | 1167 | |
---|
1104 | | -static const struct file_operations proc_sysrq_trigger_operations = { |
---|
1105 | | - .write = write_sysrq_trigger, |
---|
1106 | | - .llseek = noop_llseek, |
---|
| 1168 | +static const struct proc_ops sysrq_trigger_proc_ops = { |
---|
| 1169 | + .proc_write = write_sysrq_trigger, |
---|
| 1170 | + .proc_lseek = noop_llseek, |
---|
1107 | 1171 | }; |
---|
1108 | 1172 | |
---|
1109 | 1173 | static void sysrq_init_procfs(void) |
---|
1110 | 1174 | { |
---|
1111 | 1175 | if (!proc_create("sysrq-trigger", S_IWUSR, NULL, |
---|
1112 | | - &proc_sysrq_trigger_operations)) |
---|
| 1176 | + &sysrq_trigger_proc_ops)) |
---|
1113 | 1177 | pr_err("Failed to register proc interface\n"); |
---|
1114 | 1178 | } |
---|
1115 | 1179 | |
---|