From patchwork Fri Jul 10 13:12:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 235231 Delivered-To: patches@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp442595ilg; Fri, 10 Jul 2020 06:12:35 -0700 (PDT) X-Received: by 2002:a63:3ece:: with SMTP id l197mr39770673pga.313.1594386754907; Fri, 10 Jul 2020 06:12:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594386754; cv=none; d=google.com; s=arc-20160816; b=uPcWvTztVexAvgw+bAA5HXJLT32A4P2XkSoH4ZoTzHQ570K55fB36NHhA9ba+R4Qa+ SmSubz7ZAOxn0QerbNNuT8WcDow9/YWElKca75dmhk9oeNqMY7TrX381/+b+FZlJrXtA HUsX5apLUg1YuZBEpzojGiZuz1ra3kRQTCAtVjbtee7mQb5JHo7iLxwICQrQB/wlZbQF DyeBH1kLNDVB5Bj8MEXeECHHKkoESVs4JciIkympxMU5P92cKqCJdGxyJ1wcDjqGZMWs 9KzqvtHj6qeNntzNFlmAZKHBkzBlAuHf1k6CN6NA3F4zYz5qxrEKi8zrGpEZQaV6odFo 8KYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wxHIhBMETpDFFxgUbCHxQv41vIYY+Vv4oIYlRuwNjXQ=; b=t5uXpmTzLp7secFfJNFJCX0wdeqIrlcCueA51C47DoJm2tDkxm/vVVlMFoAgoJZxrN EUxhhW51k/maJ4E4C8JILlg0ExMBnrV/FmtkdUcCcnXyyT7HCh+D0McpSrMJnDkSbdd9 QwVZhYj+Wt8qG7Yp5j4O8rHYnh+moxj3ctG19dB7crc4k2X5xWmpxW097hsjTH5uOz5s e764DSh4jkTlc4+dPkW4oSWZ7d4aDG2QQp/8JycuhJ5d5E2B/tF8FdJ8MgEVhUTOrE5q EyIw8Xaxhj9Z9RjsZH3QIccB53ZYqyx7akXGfiE3o4UJ8JtM3v3bSXb/SPnl0Mg0WOci /Qiw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=i48LXWmy; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id ay8sor7796917pjb.36.2020.07.10.06.12.34 for (Google Transport Security); Fri, 10 Jul 2020 06:12:34 -0700 (PDT) Received-SPF: pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=i48LXWmy; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wxHIhBMETpDFFxgUbCHxQv41vIYY+Vv4oIYlRuwNjXQ=; b=i48LXWmywPjwueW6WbYBLES8sSEoS0bt2WE7VlYB+tNcjhWcUXMVQMxvU0hxYGvYmq dlFCOI5hs+JESQz6YLlkRkGGBfGnccJzPpOfXp/6rBA8ZbmeL8pi7XLTpUUg9mqdFinV 34fpu7qP2yf07vS68nCRQ0UwVfdh2ui3WmS3QX9w3MZ77NZ0rP637+YqmU8rsiLHLf5W vLQmC0RoyK0gcabDEorPYEmcIj9twhj4VPjnxlL/4AG4qOkAJjkw219qEBUxjYirsKPi U3rcdI0wDmmcTUAQHv7A7BS96jax6Y3LGNKfRI3SehYIx9KSoh9fYV1GutcX3mh4PENI bR+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wxHIhBMETpDFFxgUbCHxQv41vIYY+Vv4oIYlRuwNjXQ=; b=dTLavTMvV4HRs52LJkzjCu5g2sAWeSRQudWc5deoAjcUnjF1yh8E9vnqIC7mjWSPGb kpfdyf7q17Muphx9XlFSk5/Hx2liidy3Yc4uXyHPZbut++wfdwjkvVyvhPMiM3t9D6dA O3kJqy6Vv6m2dMZPiKBncjsAiQYnededzUoWeFFl+Rdvuga/O7M8h1NwqyjDMKn+HdKO FhjvjcVdQe+RA/Y6s4OtS1P7qwC09XT1DLoGzKX4xQn8LNTxk9sUFpuEUTVqljU8u5l0 gsz3CCRRfmZPAO0+I1o3E2OpF4NOp11+PJT7iC87VMmbTlqDwP/+ZMGxQ/GSnUb5ZnSg PThQ== X-Gm-Message-State: AOAM533mH+LgPfUpf8TM0fl3TCEeHzF1cUmbsmAt/j5CbJXkn1ysuHJo AOS2HX4NC3+bwsvGu/c7hRCjtbk1 X-Google-Smtp-Source: ABdhPJygFyifscAJSewj5TKrCqxZoG6YJoWjgiS3S0KUU0cuRu6eFihASV9HMsDh3UNy7PazSEP8xg== X-Received: by 2002:a17:90a:26ac:: with SMTP id m41mr5466921pje.169.1594386754494; Fri, 10 Jul 2020 06:12:34 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([117.210.211.230]) by smtp.gmail.com with ESMTPSA id d25sm5553279pgn.2.2020.07.10.06.12.31 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Jul 2020 06:12:33 -0700 (PDT) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [RFC INTERNAL v2 1/4] tty/sysrq: Make sysrq handler NMI aware Date: Fri, 10 Jul 2020 18:42:02 +0530 Message-Id: <1594386725-10346-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1594386725-10346-1-git-send-email-sumit.garg@linaro.org> References: <1594386725-10346-1-git-send-email-sumit.garg@linaro.org> With the advent of pseudo NMIs on arm64 its been possible to raise serial device interrupt as an NMI in polling mode. With that its now possible to do a magic sysrq in NMI context rather than in normal IRQ context. So make sysrq handler NMI aware and allow system requests to be marked as NMI safe which can run directly in NMI context while categorized as not being NMI safe will be queued as irq_work for later processing in normal interrupt context. This feature is especially helpful in case the primary CPU is stuck in deadlock with interrupts disabled won't honour serial device interrupt. So with sysrq running in NMI context is helpful to debug such scenarios. Signed-off-by: Sumit Garg --- drivers/tty/sysrq.c | 36 +++++++++++++++++++++++++++++++++++- include/linux/sysrq.h | 1 + kernel/debug/debug_core.c | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 7c95afa9..97393c7 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include #include @@ -111,6 +113,7 @@ static const struct sysrq_key_op sysrq_loglevel_op = { .help_msg = "loglevel(0-9)", .action_msg = "Changing Loglevel", .enable_mask = SYSRQ_ENABLE_LOG, + .nmi_safe = true, }; #ifdef CONFIG_VT @@ -157,6 +160,7 @@ static const struct sysrq_key_op sysrq_crash_op = { .help_msg = "crash(c)", .action_msg = "Trigger a crash", .enable_mask = SYSRQ_ENABLE_DUMP, + .nmi_safe = true, }; static void sysrq_handle_reboot(int key) @@ -170,6 +174,7 @@ static const struct sysrq_key_op sysrq_reboot_op = { .help_msg = "reboot(b)", .action_msg = "Resetting", .enable_mask = SYSRQ_ENABLE_BOOT, + .nmi_safe = true, }; const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; @@ -217,6 +222,7 @@ static const struct sysrq_key_op sysrq_showlocks_op = { .handler = sysrq_handle_showlocks, .help_msg = "show-all-locks(d)", .action_msg = "Show Locks Held", + .nmi_safe = true, }; #else #define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL) @@ -289,6 +295,7 @@ static const struct sysrq_key_op sysrq_showregs_op = { .help_msg = "show-registers(p)", .action_msg = "Show Regs", .enable_mask = SYSRQ_ENABLE_DUMP, + .nmi_safe = true, }; static void sysrq_handle_showstate(int key) @@ -326,6 +333,7 @@ static const struct sysrq_key_op sysrq_ftrace_dump_op = { .help_msg = "dump-ftrace-buffer(z)", .action_msg = "Dump ftrace buffer", .enable_mask = SYSRQ_ENABLE_DUMP, + .nmi_safe = true, }; #else #define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) @@ -538,6 +546,26 @@ static void __sysrq_put_key_op(int key, const struct sysrq_key_op *op_p) sysrq_key_table[i] = op_p; } +#define SYSRQ_NMI_FIFO_SIZE 64 +static DEFINE_KFIFO(sysrq_nmi_fifo, int, SYSRQ_NMI_FIFO_SIZE); + +static void sysrq_do_nmi_work(struct irq_work *work) +{ + struct sysrq_key_op *op_p; + int key; + + if (!kfifo_len(&sysrq_nmi_fifo)) + return; + + while (kfifo_out(&sysrq_nmi_fifo, &key, 1)) { + op_p = __sysrq_get_key_op(key); + if (op_p) + op_p->handler(key); + } +} + +static DEFINE_IRQ_WORK(sysrq_nmi_work, sysrq_do_nmi_work); + void __handle_sysrq(int key, bool check_mask) { const struct sysrq_key_op *op_p; @@ -568,7 +596,13 @@ void __handle_sysrq(int key, bool check_mask) if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { pr_info("%s\n", op_p->action_msg); console_loglevel = orig_log_level; - op_p->handler(key); + + if (in_nmi() && !op_p->nmi_safe) { + kfifo_in(&sysrq_nmi_fifo, &key, 1); + irq_work_queue(&sysrq_nmi_work); + } else { + op_p->handler(key); + } } else { pr_info("This sysrq operation is disabled.\n"); console_loglevel = orig_log_level; diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 3a582ec..630b5b9 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -34,6 +34,7 @@ struct sysrq_key_op { const char * const help_msg; const char * const action_msg; const int enable_mask; + const bool nmi_safe; }; #ifdef CONFIG_MAGIC_SYSRQ diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 9e59347..2b51173 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -943,6 +943,7 @@ static const struct sysrq_key_op sysrq_dbg_op = { .handler = sysrq_handle_dbg, .help_msg = "debug(g)", .action_msg = "DEBUG", + .nmi_safe = true, }; #endif