From 748e4f3d702def1a4bff191e0cf93b6a05340f01 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:41:34 +0000 Subject: [PATCH] add gpio led uart --- kernel/drivers/tty/sysrq.c | 176 ++++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 120 insertions(+), 56 deletions(-) diff --git a/kernel/drivers/tty/sysrq.c b/kernel/drivers/tty/sysrq.c index baaa438..7ca209d 100644 --- a/kernel/drivers/tty/sysrq.c +++ b/kernel/drivers/tty/sysrq.c @@ -19,6 +19,7 @@ #include <linux/sched/rt.h> #include <linux/sched/debug.h> #include <linux/sched/task.h> +#include <linux/ctype.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/fs.h> @@ -63,6 +64,19 @@ return sysrq_enabled || sysrq_always_enabled; } +/** + * sysrq_mask - Getter for sysrq_enabled mask. + * + * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise. + */ +int sysrq_mask(void) +{ + if (sysrq_always_enabled) + return 1; + return sysrq_enabled; +} +EXPORT_SYMBOL_GPL(sysrq_mask); + /* * A value of 1 means 'all', other nonzero values are an op mask: */ @@ -93,7 +107,7 @@ pr_info("Loglevel set to %d\n", i); console_loglevel = i; } -static struct sysrq_key_op sysrq_loglevel_op = { +static const struct sysrq_key_op sysrq_loglevel_op = { .handler = sysrq_handle_loglevel, .help_msg = "loglevel(0-9)", .action_msg = "Changing Loglevel", @@ -106,14 +120,14 @@ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; schedule_work(SAK_work); } -static struct sysrq_key_op sysrq_SAK_op = { +static const struct sysrq_key_op sysrq_SAK_op = { .handler = sysrq_handle_SAK, .help_msg = "sak(k)", .action_msg = "SAK", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else -#define sysrq_SAK_op (*(struct sysrq_key_op *)NULL) +#define sysrq_SAK_op (*(const struct sysrq_key_op *)NULL) #endif #ifdef CONFIG_VT @@ -122,14 +136,14 @@ vt_reset_unicode(fg_console); } -static struct sysrq_key_op sysrq_unraw_op = { +static const struct sysrq_key_op sysrq_unraw_op = { .handler = sysrq_handle_unraw, .help_msg = "unraw(r)", .action_msg = "Keyboard mode set to system default", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else -#define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) +#define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL) #endif /* CONFIG_VT */ static void sysrq_handle_crash(int key) @@ -139,7 +153,7 @@ panic("sysrq triggered crash\n"); } -static struct sysrq_key_op sysrq_crash_op = { +static const struct sysrq_key_op sysrq_crash_op = { .handler = sysrq_handle_crash, .help_msg = "crash(c)", .action_msg = "Trigger a crash", @@ -152,18 +166,20 @@ local_irq_enable(); emergency_restart(); } -static struct sysrq_key_op sysrq_reboot_op = { +static const struct sysrq_key_op sysrq_reboot_op = { .handler = sysrq_handle_reboot, .help_msg = "reboot(b)", .action_msg = "Resetting", .enable_mask = SYSRQ_ENABLE_BOOT, }; +const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; + static void sysrq_handle_sync(int key) { emergency_sync(); } -static struct sysrq_key_op sysrq_sync_op = { +static const struct sysrq_key_op sysrq_sync_op = { .handler = sysrq_handle_sync, .help_msg = "sync(s)", .action_msg = "Emergency Sync", @@ -175,7 +191,7 @@ sysrq_timer_list_show(); } -static struct sysrq_key_op sysrq_show_timers_op = { +static const struct sysrq_key_op sysrq_show_timers_op = { .handler = sysrq_handle_show_timers, .help_msg = "show-all-timers(q)", .action_msg = "Show clockevent devices & pending hrtimers (no others)", @@ -185,7 +201,7 @@ { emergency_remount(); } -static struct sysrq_key_op sysrq_mountro_op = { +static const struct sysrq_key_op sysrq_mountro_op = { .handler = sysrq_handle_mountro, .help_msg = "unmount(u)", .action_msg = "Emergency Remount R/O", @@ -198,13 +214,13 @@ debug_show_all_locks(); } -static struct sysrq_key_op sysrq_showlocks_op = { +static const struct sysrq_key_op sysrq_showlocks_op = { .handler = sysrq_handle_showlocks, .help_msg = "show-all-locks(d)", .action_msg = "Show Locks Held", }; #else -#define sysrq_showlocks_op (*(struct sysrq_key_op *)NULL) +#define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL) #endif #ifdef CONFIG_SMP @@ -215,12 +231,14 @@ unsigned long flags; /* Idle CPUs have no interesting backtrace. */ - if (idle_cpu(smp_processor_id())) + if (idle_cpu(smp_processor_id())) { + pr_info("CPU%d: backtrace skipped as idling\n", smp_processor_id()); return; + } raw_spin_lock_irqsave(&show_lock, flags); pr_info("CPU%d:\n", smp_processor_id()); - show_stack(NULL, NULL); + show_stack(NULL, NULL, KERN_INFO); raw_spin_unlock_irqrestore(&show_lock, flags); } @@ -243,15 +261,18 @@ if (in_irq()) regs = get_irq_regs(); - if (regs) { - pr_info("CPU%d:\n", smp_processor_id()); + + pr_info("CPU%d:\n", smp_processor_id()); + if (regs) show_regs(regs); - } + else + show_stack(NULL, NULL, KERN_INFO); + schedule_work(&sysrq_showallcpus); } } -static struct sysrq_key_op sysrq_showallcpus_op = { +static const struct sysrq_key_op sysrq_showallcpus_op = { .handler = sysrq_handle_showallcpus, .help_msg = "show-backtrace-all-active-cpus(l)", .action_msg = "Show backtrace of all active CPUs", @@ -269,7 +290,7 @@ show_regs(regs); perf_event_print_debug(); } -static struct sysrq_key_op sysrq_showregs_op = { +static const struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, .help_msg = "show-registers(p)", .action_msg = "Show Regs", @@ -281,7 +302,7 @@ show_state(); show_workqueue_state(); } -static struct sysrq_key_op sysrq_showstate_op = { +static const struct sysrq_key_op sysrq_showstate_op = { .handler = sysrq_handle_showstate, .help_msg = "show-task-states(t)", .action_msg = "Show State", @@ -292,7 +313,7 @@ { show_state_filter(TASK_UNINTERRUPTIBLE); } -static struct sysrq_key_op sysrq_showstate_blocked_op = { +static const struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, .help_msg = "show-blocked-tasks(w)", .action_msg = "Show Blocked State", @@ -306,21 +327,21 @@ { ftrace_dump(DUMP_ALL); } -static struct sysrq_key_op sysrq_ftrace_dump_op = { +static const struct sysrq_key_op sysrq_ftrace_dump_op = { .handler = sysrq_ftrace_dump, .help_msg = "dump-ftrace-buffer(z)", .action_msg = "Dump ftrace buffer", .enable_mask = SYSRQ_ENABLE_DUMP, }; #else -#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) +#define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) #endif static void sysrq_handle_showmem(int key) { show_mem(0, NULL); } -static struct sysrq_key_op sysrq_showmem_op = { +static const struct sysrq_key_op sysrq_showmem_op = { .handler = sysrq_handle_showmem, .help_msg = "show-memory-usage(m)", .action_msg = "Show Memory", @@ -341,7 +362,7 @@ if (is_global_init(p)) continue; - do_send_sig_info(sig, SEND_SIG_FORCED, p, PIDTYPE_MAX); + do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); } read_unlock(&tasklist_lock); } @@ -351,7 +372,7 @@ send_sig_all(SIGTERM); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; } -static struct sysrq_key_op sysrq_term_op = { +static const struct sysrq_key_op sysrq_term_op = { .handler = sysrq_handle_term, .help_msg = "terminate-all-tasks(e)", .action_msg = "Terminate All Tasks", @@ -381,32 +402,30 @@ { schedule_work(&moom_work); } -static struct sysrq_key_op sysrq_moom_op = { +static const struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, .help_msg = "memory-full-oom-kill(f)", .action_msg = "Manual OOM execution", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -#ifdef CONFIG_BLOCK static void sysrq_handle_thaw(int key) { emergency_thaw_all(); } -static struct sysrq_key_op sysrq_thaw_op = { +static const struct sysrq_key_op sysrq_thaw_op = { .handler = sysrq_handle_thaw, .help_msg = "thaw-filesystems(j)", .action_msg = "Emergency Thaw of all frozen filesystems", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -#endif static void sysrq_handle_kill(int key) { send_sig_all(SIGKILL); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; } -static struct sysrq_key_op sysrq_kill_op = { +static const struct sysrq_key_op sysrq_kill_op = { .handler = sysrq_handle_kill, .help_msg = "kill-all-tasks(i)", .action_msg = "Kill All Tasks", @@ -417,7 +436,7 @@ { normalize_rt_tasks(); } -static struct sysrq_key_op sysrq_unrt_op = { +static const struct sysrq_key_op sysrq_unrt_op = { .handler = sysrq_handle_unrt, .help_msg = "nice-all-RT-tasks(n)", .action_msg = "Nice All RT Tasks", @@ -427,7 +446,7 @@ /* Key Operations table and lock */ static DEFINE_SPINLOCK(sysrq_key_table_lock); -static struct sysrq_key_op *sysrq_key_table[36] = { +static const struct sysrq_key_op *sysrq_key_table[62] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ @@ -484,6 +503,32 @@ /* y: May be registered on sparc64 for global register dump */ NULL, /* y */ &sysrq_ftrace_dump_op, /* z */ + NULL, /* A */ + NULL, /* B */ + NULL, /* C */ + NULL, /* D */ + NULL, /* E */ + NULL, /* F */ + NULL, /* G */ + NULL, /* H */ + NULL, /* I */ + NULL, /* J */ + NULL, /* K */ + NULL, /* L */ + NULL, /* M */ + NULL, /* N */ + NULL, /* O */ + NULL, /* P */ + NULL, /* Q */ + NULL, /* R */ + NULL, /* S */ + NULL, /* T */ + NULL, /* U */ + NULL, /* V */ + NULL, /* W */ + NULL, /* X */ + NULL, /* Y */ + NULL, /* Z */ }; /* key2index calculation, -1 on invalid index */ @@ -495,6 +540,8 @@ retval = key - '0'; else if ((key >= 'a') && (key <= 'z')) retval = key + 10 - 'a'; + else if ((key >= 'A') && (key <= 'Z')) + retval = key + 36 - 'A'; else retval = -1; return retval; @@ -503,9 +550,9 @@ /* * get and put functions for the table, exposed to modules. */ -struct sysrq_key_op *__sysrq_get_key_op(int key) +static const struct sysrq_key_op *__sysrq_get_key_op(int key) { - struct sysrq_key_op *op_p = NULL; + const struct sysrq_key_op *op_p = NULL; int i; i = sysrq_key_table_key2index(key); @@ -515,7 +562,7 @@ return op_p; } -static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) +static void __sysrq_put_key_op(int key, const struct sysrq_key_op *op_p) { int i = sysrq_key_table_key2index(key); @@ -525,9 +572,13 @@ void __handle_sysrq(int key, bool check_mask) { - struct sysrq_key_op *op_p; + const struct sysrq_key_op *op_p; int orig_log_level; + int orig_suppress_printk; int i; + + orig_suppress_printk = suppress_printk; + suppress_printk = 0; rcu_sysrq_start(); rcu_read_lock(); @@ -574,6 +625,8 @@ } rcu_read_unlock(); rcu_sysrq_end(); + + suppress_printk = orig_suppress_printk; } void handle_sysrq(int key) @@ -602,6 +655,8 @@ unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; unsigned int alt; unsigned int alt_use; + unsigned int shift; + unsigned int shift_use; bool active; bool need_reinject; bool reinjecting; @@ -653,8 +708,7 @@ state->reset_requested = true; - ksys_sync(); - kernel_restart(NULL); + orderly_reboot(); } static void sysrq_handle_reset_request(struct sysrq_state *state) @@ -729,6 +783,8 @@ /* Get reset timeout if any. */ of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms); + + of_node_put(np); } #else static void sysrq_of_get_keyreset_config(void) @@ -785,10 +841,20 @@ } break; + case KEY_LEFTSHIFT: + case KEY_RIGHTSHIFT: + if (!value) + sysrq->shift = KEY_RESERVED; + else if (value != 2) + sysrq->shift = code; + break; + case KEY_SYSRQ: if (value == 1 && sysrq->alt != KEY_RESERVED) { sysrq->active = true; sysrq->alt_use = sysrq->alt; + /* either RESERVED (for released) or actual code */ + sysrq->shift_use = sysrq->shift; /* * If nothing else will be pressed we'll need * to re-inject Alt-SysRq keysroke. @@ -811,8 +877,12 @@ default: if (sysrq->active && value && value != 2) { + unsigned char c = sysrq_xlate[code]; + sysrq->need_reinject = false; - __handle_sysrq(sysrq_xlate[code], true); + if (sysrq->shift_use != KEY_RESERVED) + c = toupper(c); + __handle_sysrq(c, true); } break; } @@ -960,8 +1030,6 @@ .id_table = sysrq_ids, }; -static bool sysrq_handler_registered; - static inline void sysrq_register_handler(void) { int error; @@ -971,16 +1039,11 @@ error = input_register_handler(&sysrq_handler); if (error) pr_err("Failed to register input handler, error %d", error); - else - sysrq_handler_registered = true; } static inline void sysrq_unregister_handler(void) { - if (sysrq_handler_registered) { - input_unregister_handler(&sysrq_handler); - sysrq_handler_registered = false; - } + input_unregister_handler(&sysrq_handler); } static int sysrq_reset_seq_param_set(const char *buffer, @@ -1046,9 +1109,10 @@ return 0; } +EXPORT_SYMBOL_GPL(sysrq_toggle_support); -static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, - struct sysrq_key_op *remove_op_p) +static int __sysrq_swap_key_ops(int key, const struct sysrq_key_op *insert_op_p, + const struct sysrq_key_op *remove_op_p) { int retval; @@ -1071,13 +1135,13 @@ return retval; } -int register_sysrq_key(int key, struct sysrq_key_op *op_p) +int register_sysrq_key(int key, const struct sysrq_key_op *op_p) { return __sysrq_swap_key_ops(key, op_p, NULL); } EXPORT_SYMBOL(register_sysrq_key); -int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) +int unregister_sysrq_key(int key, const struct sysrq_key_op *op_p) { return __sysrq_swap_key_ops(key, NULL, op_p); } @@ -1101,15 +1165,15 @@ return count; } -static const struct file_operations proc_sysrq_trigger_operations = { - .write = write_sysrq_trigger, - .llseek = noop_llseek, +static const struct proc_ops sysrq_trigger_proc_ops = { + .proc_write = write_sysrq_trigger, + .proc_lseek = noop_llseek, }; static void sysrq_init_procfs(void) { if (!proc_create("sysrq-trigger", S_IWUSR, NULL, - &proc_sysrq_trigger_operations)) + &sysrq_trigger_proc_ops)) pr_err("Failed to register proc interface\n"); } -- Gitblit v1.6.2