From patchwork Fri Jul 17 06:20:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 235671 Delivered-To: patches@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1428496ilg; Thu, 16 Jul 2020 23:21:24 -0700 (PDT) X-Received: by 2002:a05:6a00:5c:: with SMTP id i28mr6898215pfk.274.1594966884170; Thu, 16 Jul 2020 23:21:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594966884; cv=none; d=google.com; s=arc-20160816; b=hglqSFujVNgJBT8tQcyKpkcd9+HjsU06JkjfmupiZfsJE113pjxudyYzYyhT9cf5Po bnQlWCW3Tuu1suYTe+TlX67eW6eie/GrfxNCEVq/C8XAjeHjleDkXo2uvq22Qzx3gGrQ l/F/oLW5xFccnR+A8ADg3Sl+CZOMkM0U5Bka7x9skeDGnJLJXwBjaQQogsAxgpDafMWe 7QIP0j7jjjfdLPM+tggGLgDP6diMQdwWEE8GVbNY9qwPEzl8p9b0WvQntwQ+wOzqISoa hngsa9pBfCSKdzoMnL3oO2D/pXTydRbx+2S6zbnSz9papMlHSmGSJ6j9WA2iR+ePzOfV /8JQ== 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=x2rRdyrqcs5j/ENnPgmQrTRvOxeqyPVdO9GsylRc+04=; b=vbIDghURl3fDoQkwkyHlqH1e7GYJ/3byFC5nMg3BPUeDN9slax7CkA+31IAt4uRwB5 PiB8kffUGhQHQf3WgCp+3J+qdRfLFSue+P4cg6dUyP7WHklsU5IzX+V2SpEW8RVe2KHe 1s7BKDog5aWnbcT6H8suh9ysA6MsI1lJYm0CPieTtmyvario9xl+4u5UY2taUMxmP+2Y MJNS8B5eTXPkMYkrA/A1JCO7jHFBxWwvufQ5OSd5nX2VpRm5Bl+4PyZJaCmJHPu6Tpe4 N60XFtlN+opdAKoluJos+xfhp5WfGcxWHXe3US1BvJhyRsQhiBTh5hDdR48bmK+SqEP3 RYeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=rJKLTvCD; 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 a1sor3014746pju.31.2020.07.16.23.21.24 for (Google Transport Security); Thu, 16 Jul 2020 23:21:24 -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=rJKLTvCD; 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=x2rRdyrqcs5j/ENnPgmQrTRvOxeqyPVdO9GsylRc+04=; b=rJKLTvCDdmifK8HKVFkzSIt0MQeJjsfM45eMogTE+80I/SM92mS/pgPXIV1fG3IJGJ HB/bJZiD1nnqdBwi0HWwV6XJc9mAUOS1yUE0lyNDZgIYPxDXCx4/h7Y1q7ZAOqqnkjkP othT8qjXcPAAGzvYTCjZQKrg0StniJtnWmThZkQ6F+jCAv1aZ+LEmbjBtnytjjKX02r6 SgReQn7fitdXbOXZy523t4FgWrWkQOHWgnduu2/2zLq8on+quxfmGCrpsEoLG2D5XfMz 1vG9Kg0lHcMenvCVFQJLuYF4ccht63/8bVH9l/T4t3YL77VBCXgWU+Vi+Qg6CwE9HlMU hBxw== 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=x2rRdyrqcs5j/ENnPgmQrTRvOxeqyPVdO9GsylRc+04=; b=AHOS3SOv4JcCYtM76Dec40x6xkq91gm9vmqdS0cyQSr3dh/diBgVf/P9AAkIaTWm8s TBzBukINH4nORkWxn01kL6GTAx7eYki2fgMSQkDqWp8pT3ScvvvivmvPEUtnFbVE/M3H CczuhwS5V313kC5HRQ9ZFU1JMnlZ9igCYyr/e6V9e0OQmhPq4PD0ANSoHxw9l3gavr83 x0FG3FNM3+PPJqpmFsgQHR1VHbOxeQTeVbQooWFe0yH8q/QGyTFESTdbsoNxy9335w/f cjBWk3ycwwTbWj3Qikve8Tklv91zmD84rw/jviZkg2j2lbUSds05mQ8xXMG4ovoz1mjR FVaA== X-Gm-Message-State: AOAM532y809f7R67gbQUIcbrXQtWh+s5rOUfygXXOwsxCf5Tv6/aSkAt 5S54GYPi5TNeLvyd7ItuLutJf2tG X-Google-Smtp-Source: ABdhPJzMHcMN5qD/8QHauvP3wlr3VBnnKVD0HazCdg28j7wqAC/QhbUgxfJKX2i92K09dH4iCtMn9Q== X-Received: by 2002:a17:90a:3223:: with SMTP id k32mr8403144pjb.121.1594966883781; Thu, 16 Jul 2020 23:21:23 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id b4sm6630466pfo.137.2020.07.16.23.21.20 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Jul 2020 23:21:23 -0700 (PDT) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [RFC INTERNAL v3 1/4] tty/sysrq: Make sysrq handler NMI aware Date: Fri, 17 Jul 2020 11:50:54 +0530 Message-Id: <1594966857-5215-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1594966857-5215-1-git-send-email-sumit.garg@linaro.org> References: <1594966857-5215-1-git-send-email-sumit.garg@linaro.org> With the advent of pseudo NMIs on arm64 it should be possible to request serial device interrupt as an NMI rather than IRQ. Having NMI driven serial RX will make it possible to do a magic sysrq in NMI context rather than in normal IRQ context. So as a preparatory step, make sysrq handler NMI aware and allow system requests to be marked as NMI safe which can run directly in NMI context while others being categorized as not NMI safe will be queued as irq_work for later processing in normal interrupt context. A particular sysrq handler is only marked as NMI safe in case the handler isn't contending for any synchronization primimitives as in NMI context they are expected to cause deadlocks. Note: Here kernel debugger (kgdb) is an exception which is a kind of stop the world debugger and designed to run in NMI context. This feature is especially helpful in case the primary CPU is stuck in deadlock with interrupts disabled and doesn't honour serial device interrupt. So having sysrq running in NMI context is helpful to debug such scenarios. Signed-off-by: Sumit Garg --- drivers/tty/sysrq.c | 33 ++++++++++++++++++++++++++++++++- include/linux/sysrq.h | 1 + kernel/debug/debug_core.c | 1 + 3 files changed, 34 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 7c95afa9..8017e33 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,23 @@ 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) +{ + const struct sysrq_key_op *op_p; + int key; + + 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 +593,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