From patchwork Tue Jul 21 12:10:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 11675577 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 05BC5618 for ; Tue, 21 Jul 2020 12:12:32 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D30E6206E9 for ; Tue, 21 Jul 2020 12:12:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="q5sskjG0"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="TyepKXn7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D30E6206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qobpvm5uiaYrxDswS1t/8daWTW+1xobwHcs5NXIpKxU=; b=q5sskjG0mZCwbWAh8rGEQyEyEq A3a4G3/6z+Ft0QGQtXuqsp2tBtgDYU3HhXH69iOg2Cd/dlNalXZyLOOIAssGBqSNfi590GzwYjoVi thLByrOdOYUFIAWn0gjd8HaP3XG2ts8kOdjK9cfPM/Zhxy9sjfF30tPs7sdbMk5pe5CymU5q+W/Hl 6y/SPOvAutPSxEM4Ei7AuOKgr2AnZkBdzP7HoWN/NYAH2JczM+FvWcpWvOYRL7yDj/CaunJZPyOMt d5fesbiN+4yIANSNiMU2Te89OJoDe6/Oe0zhOscuROSO9hvvcvoArP+byvgoeFJzJb3MXHa5dcSCb XOWp3KPA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr6p-0000Kb-Qw; Tue, 21 Jul 2020 12:10:59 +0000 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr6n-0000Jx-9s for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 12:10:58 +0000 Received: by mail-pf1-x441.google.com with SMTP id q17so10620273pfu.8 for ; Tue, 21 Jul 2020 05:10:55 -0700 (PDT) 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=bmoIA6JVwOy+6GP1zUPLm+Haa8V9hMBSF82Ea7A25DQ=; b=TyepKXn7OaYUQtt4hFJbFIHF5h+u+fprOJj4OSkj62VZU3n8u0j9yYrT7NHtWxi/an 1b6b+9jU7D0O5dJMcoD2rqrFEj6sjq4HohRlHi1aWwa0ExNHUO6Az2x8gABX2q50szu/ ZxKtmbi++l+NcrXL+hJgpevYLiU+XRaZ6UD2IzAUwrWQg9q1I4XAONLFu92YCQHfqU/Q dQ5tPt9ebLwtmoiVmPkO6qOOZKyJ7NpqggfM5bR/3nR8jSIxytunTjxLTpQCnIVdMlpr 9/bIAOd1nr6zAEsHFPnA7mnoQ64IyInDUaDo159KyWXHggP9Q/+yfjHhXGangDK7tsJh MPug== 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=bmoIA6JVwOy+6GP1zUPLm+Haa8V9hMBSF82Ea7A25DQ=; b=Bj7NvbkPEhSsU1p1YNFzz2BsxhQskMJBL60IAC01WwEOAevRqwCQ4h+qDDf1VjI/UN e+cpu2cDKc4UlyxspJocb8QbQvXXEb1iygfOJqOZUoocL3M7KrnZs2fQw2eqsq0BVaFm jddNvcednWGh/McnJ0GBdusBNJAqikf1IpmnkrXtzA/XN6y7NJG1iSv4+7lowdR+u3iJ p5mDzp+kk6wxlMjFDVAmRx0EIFkY2c2uc2BpVpiyKGWpmf4fXzKuIYpmgo5YUG78M5Dj EU0Vk4vqLbctZSHxOWowYMazLaomcSZNcXa39Swe5s5WuRGmo5rjGZLPaA/CT62GwwdQ d78Q== X-Gm-Message-State: AOAM533aCHEb2iFeDfZS+M1jeKLP/s7bcVyAtMxpUO2mHkd9N5cfLoGR 9CgmnddQ/JWwsvVe2wivqs6Rrw== X-Google-Smtp-Source: ABdhPJx//Ilc8MIFF8alHzz3aukyRgaFhVVxqz29Ai3h7DB0QotUS2/ezSTlrD7mrAWkwoDkQznv6Q== X-Received: by 2002:aa7:9a07:: with SMTP id w7mr22724654pfj.251.1595333454186; Tue, 21 Jul 2020 05:10:54 -0700 (PDT) Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id w9sm20601992pfq.178.2020.07.21.05.10.48 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Jul 2020 05:10:53 -0700 (PDT) From: Sumit Garg To: gregkh@linuxfoundation.org, daniel.thompson@linaro.org, dianders@chromium.org, linux-serial@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [RFC 1/5] tty/sysrq: Make sysrq handler NMI aware Date: Tue, 21 Jul 2020 17:40:09 +0530 Message-Id: <1595333413-30052-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> References: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_081057_369604_2B9BB142 X-CRM114-Status: GOOD ( 19.49 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:441 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sumit Garg , jslaby@suse.com, linux-kernel@vger.kernel.org, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In a future patch we will add support to the serial core to make it possible to trigger a magic sysrq from an NMI context. Prepare for this by marking some sysrq actions as NMI safe. Safe actions will be allowed to run from NMI context whilst that cannot run from an NMI will be queued as irq_work for later processing. A particular sysrq handler is only marked as NMI safe in case the handler isn't contending for any synchronization primitives as in NMI context they are expected to cause deadlocks. Note that the debug sysrq do not contend for any synchronization primitives. It does call kgdb_breakpoint() to provoke a trap but that trap handler should be NMI safe on architectures that implement an NMI. 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(-) 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 From patchwork Tue Jul 21 12:10:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 11675579 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 24F9B618 for ; Tue, 21 Jul 2020 12:12:33 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F3368206E9 for ; Tue, 21 Jul 2020 12:12:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="UE4KKEgf"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="BuARnLyS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F3368206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cwDO+/nI2gB+lQMvbSei1kq9KapUf8/QDJkgHC73OHw=; b=UE4KKEgf4Dqzn9+EKnMoWg6tY5 l98yjG2GwVpBS1hDHcmCohP7xgHk7IUw6t2BIo3UvWn9gVwMCC9VsjyL1tgoHpy+yoEDplZ3Phu/5 zjT7YYOU9iO2VggQErMozN5mb7KeA0Kq4fb+w89LoUHHVrv0qpKUNs5yIn+RbpeLZUTe+CiaBURrj irnUw1xRE532Nz9IBXSAI6PEp2Kl0p0T7spLPavqpNdFrrGXDuIhLBnKpOh4KfHxbJ7DW7I2/wMRV PZY8mL/hN3d+KbuaVL34GXkbj9y6XqyYsrgxnoOctLDN6nAe7Y6tAOau97En20Uaeb/TgeZYXgFD5 og0+filw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr6x-0000MT-GY; Tue, 21 Jul 2020 12:11:07 +0000 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr6s-0000Kl-45 for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 12:11:03 +0000 Received: by mail-pl1-x642.google.com with SMTP id p1so10183172pls.4 for ; Tue, 21 Jul 2020 05:11:01 -0700 (PDT) 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=jQ4rDDgYanuVEiD5VSyVtoHbMEWpqen32aI8GMWnA+0=; b=BuARnLySFYXHobk+DJzYYbZapFac75rnp2cAzZUyk+Gi1xEuU1EKVS1Y1ft+eSIwcL vUQ65Nj4hj0gbP6KuHvpVQ1/mKEqee4c+RYlKvvGEkqecq5lPOYvBC/pKxqWrs/xvNuX ConaNJol+yJAMDTJi84K9crZw28bIZdQhev3sLhB3gqdVEqEs55lxbxIv8OArsnDnGfV CCpC7mpvvk9RD+YSf+d/FvJn9J02mMZZ+jD96+Ckm7JLj1B7A4Q+80Q9XsJ0Ztb2vljT r9PD1tKl8MrmBZAm8XG6xSQLyTNYFft4pqHRY1+16emo3h9Q8zs9U0cfGItOz/xXjY0v cfHA== 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=jQ4rDDgYanuVEiD5VSyVtoHbMEWpqen32aI8GMWnA+0=; b=Cy4rXcnU/cfvi+StCORKmK3VcjLoh3ASiWsi+ClU/SPG46iRT5fsM0A4HmJ1Rbetbo Yqrtjo5wYrJ3QZwHdYyKKc9zPcO3HrO67Gq+ozUYTuEfpALwBxitfIpakxjphWIiZ6jA pim8NKxoh8hMnEk9BolYQW/z2ZRWM5MxUoyc7I67CMe7R4IfgkiMWZ21KCFTfQfjuRfX FjIzY9DP2us5+vYzKEw9ZTLqRIXJ4V5jSsBfOehzDBMMHgRTCcxwso3pa6cpj3Ak3pHF br8TNAKeqmJb63vF1i0uYinUBC3IpAU/PTDR/eqvXXSEPT87os4vRMYH9VBWj8wT9zSM CF9w== X-Gm-Message-State: AOAM532J62e9EBbTYbNW9XmpAWWsmvlT2GqtgTjSnUTInCXrkC1iU6XP xgGIB8Ao0Cbvce6jdkftLbWpxczsSZY= X-Google-Smtp-Source: ABdhPJwuz8QK1fPNOpZalpAeTbf4LEUS9VjUfrRfr1RCUAvdtOBgLm3oRTOaw/15VbGU7Sm1GM7DZg== X-Received: by 2002:a17:902:a9c8:: with SMTP id b8mr22299780plr.2.1595333459711; Tue, 21 Jul 2020 05:10:59 -0700 (PDT) Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id w9sm20601992pfq.178.2020.07.21.05.10.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Jul 2020 05:10:58 -0700 (PDT) From: Sumit Garg To: gregkh@linuxfoundation.org, daniel.thompson@linaro.org, dianders@chromium.org, linux-serial@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [RFC 2/5] serial: core: Add framework to allow NMI aware serial drivers Date: Tue, 21 Jul 2020 17:40:10 +0530 Message-Id: <1595333413-30052-3-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> References: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_081102_223477_42986429 X-CRM114-Status: GOOD ( 23.25 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:642 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sumit Garg , jslaby@suse.com, linux-kernel@vger.kernel.org, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add NMI framework APIs in serial core which can be leveraged by serial drivers to have NMI driven serial transfers. These APIs are kept under CONFIG_CONSOLE_POLL as currently kgdb initializing uart in polling mode is the only known user to enable NMI driven serial port. The general idea is to intercept RX characters in NMI context, if those are specific to magic sysrq then allow corresponding handler to run in NMI context. Otherwise defer all other RX and TX operations to IRQ work queue in order to run those in normal interrupt context. Also, since magic sysrq entry APIs will need to be invoked from NMI context, so make those APIs NMI safe via deferring NMI unsafe work to IRQ work queue. Signed-off-by: Sumit Garg --- drivers/tty/serial/serial_core.c | 120 ++++++++++++++++++++++++++++++++++++++- include/linux/serial_core.h | 67 ++++++++++++++++++++++ 2 files changed, 185 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 57840cf..6342e90 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3181,8 +3181,14 @@ static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) return true; } +#ifdef CONFIG_CONSOLE_POLL + if (in_nmi()) + irq_work_queue(&port->nmi_state.sysrq_toggle_work); + else + schedule_work(&sysrq_enable_work); +#else schedule_work(&sysrq_enable_work); - +#endif port->sysrq = 0; return true; } @@ -3273,12 +3279,122 @@ int uart_handle_break(struct uart_port *port) port->sysrq = 0; } - if (port->flags & UPF_SAK) + if (port->flags & UPF_SAK) { +#ifdef CONFIG_CONSOLE_POLL + if (in_nmi()) + irq_work_queue(&port->nmi_state.sysrq_sak_work); + else + do_SAK(state->port.tty); +#else do_SAK(state->port.tty); +#endif + } return 0; } EXPORT_SYMBOL_GPL(uart_handle_break); +#ifdef CONFIG_CONSOLE_POLL +int uart_nmi_handle_char(struct uart_port *port, unsigned int status, + unsigned int overrun, unsigned int ch, + unsigned int flag) +{ + struct uart_nmi_rx_data rx_data; + + if (!in_nmi()) + return 0; + + rx_data.status = status; + rx_data.overrun = overrun; + rx_data.ch = ch; + rx_data.flag = flag; + + if (!kfifo_in(&port->nmi_state.rx_fifo, &rx_data, 1)) + ++port->icount.buf_overrun; + + return 1; +} +EXPORT_SYMBOL_GPL(uart_nmi_handle_char); + +static void uart_nmi_rx_work(struct irq_work *rx_work) +{ + struct uart_nmi_state *nmi_state = + container_of(rx_work, struct uart_nmi_state, rx_work); + struct uart_port *port = + container_of(nmi_state, struct uart_port, nmi_state); + struct uart_nmi_rx_data rx_data; + + /* + * In polling mode, serial device is initialized much prior to + * TTY port becoming active. This scenario is especially useful + * from debugging perspective such that magic sysrq or debugger + * entry would still be possible even when TTY port isn't + * active (consider a boot hang case or if a user hasn't opened + * the serial port). So we discard any other RX data apart from + * magic sysrq commands in case TTY port isn't active. + */ + if (!port->state || !tty_port_active(&port->state->port)) { + kfifo_reset(&nmi_state->rx_fifo); + return; + } + + spin_lock(&port->lock); + while (kfifo_out(&nmi_state->rx_fifo, &rx_data, 1)) + uart_insert_char(port, rx_data.status, rx_data.overrun, + rx_data.ch, rx_data.flag); + spin_unlock(&port->lock); + + tty_flip_buffer_push(&port->state->port); +} + +static void uart_nmi_tx_work(struct irq_work *tx_work) +{ + struct uart_nmi_state *nmi_state = + container_of(tx_work, struct uart_nmi_state, tx_work); + struct uart_port *port = + container_of(nmi_state, struct uart_port, nmi_state); + + spin_lock(&port->lock); + if (nmi_state->tx_irq_callback) + nmi_state->tx_irq_callback(port); + spin_unlock(&port->lock); +} + +static void uart_nmi_sak_work(struct irq_work *work) +{ + struct uart_nmi_state *nmi_state = + container_of(work, struct uart_nmi_state, sysrq_sak_work); + struct uart_port *port = + container_of(nmi_state, struct uart_port, nmi_state); + + do_SAK(port->state->port.tty); +} + +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL +static void uart_nmi_toggle_work(struct irq_work *work) +{ + schedule_work(&sysrq_enable_work); +} +#endif + +int uart_nmi_state_init(struct uart_port *port) +{ + int ret; + + ret = kfifo_alloc(&port->nmi_state.rx_fifo, 256, GFP_KERNEL); + if (ret) + return ret; + + init_irq_work(&port->nmi_state.rx_work, uart_nmi_rx_work); + init_irq_work(&port->nmi_state.tx_work, uart_nmi_tx_work); + init_irq_work(&port->nmi_state.sysrq_sak_work, uart_nmi_sak_work); +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL + init_irq_work(&port->nmi_state.sysrq_toggle_work, uart_nmi_toggle_work); +#endif + return ret; +} +EXPORT_SYMBOL_GPL(uart_nmi_state_init); +#endif + EXPORT_SYMBOL(uart_write_wakeup); EXPORT_SYMBOL(uart_register_driver); EXPORT_SYMBOL(uart_unregister_driver); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 9fd550e..84487a9 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_SERIAL_CORE_CONSOLE @@ -103,6 +105,28 @@ struct uart_icount { typedef unsigned int __bitwise upf_t; typedef unsigned int __bitwise upstat_t; +#ifdef CONFIG_CONSOLE_POLL +struct uart_nmi_rx_data { + unsigned int status; + unsigned int overrun; + unsigned int ch; + unsigned int flag; +}; + +struct uart_nmi_state { + bool active; + + struct irq_work tx_work; + void (*tx_irq_callback)(struct uart_port *port); + + struct irq_work rx_work; + DECLARE_KFIFO_PTR(rx_fifo, struct uart_nmi_rx_data); + + struct irq_work sysrq_sak_work; + struct irq_work sysrq_toggle_work; +}; +#endif + struct uart_port { spinlock_t lock; /* port lock */ unsigned long iobase; /* in/out[bwl] */ @@ -255,6 +279,9 @@ struct uart_port { struct gpio_desc *rs485_term_gpio; /* enable RS485 bus termination */ struct serial_iso7816 iso7816; void *private_data; /* generic platform data pointer */ +#ifdef CONFIG_CONSOLE_POLL + struct uart_nmi_state nmi_state; +#endif }; static inline int serial_port_in(struct uart_port *up, int offset) @@ -475,4 +502,44 @@ extern int uart_handle_break(struct uart_port *port); !((cflag) & CLOCAL)) int uart_get_rs485_mode(struct uart_port *port); + +/* + * The following are helper functions for the NMI aware serial drivers. + * Currently NMI support is only enabled under polling mode. + */ + +#ifdef CONFIG_CONSOLE_POLL +int uart_nmi_state_init(struct uart_port *port); +int uart_nmi_handle_char(struct uart_port *port, unsigned int status, + unsigned int overrun, unsigned int ch, + unsigned int flag); + +static inline bool uart_nmi_active(struct uart_port *port) +{ + return port->nmi_state.active; +} + +static inline void uart_set_nmi_active(struct uart_port *port, bool val) +{ + port->nmi_state.active = val; +} +#else +static inline int uart_nmi_handle_char(struct uart_port *port, + unsigned int status, + unsigned int overrun, + unsigned int ch, unsigned int flag) +{ + return 0; +} + +static inline bool uart_nmi_active(struct uart_port *port) +{ + return false; +} + +static inline void uart_set_nmi_active(struct uart_port *port, bool val) +{ +} +#endif + #endif /* LINUX_SERIAL_CORE_H */ From patchwork Tue Jul 21 12:10:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 11675583 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 739F814E3 for ; Tue, 21 Jul 2020 12:12:45 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4DE16206E9 for ; Tue, 21 Jul 2020 12:12:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XG+4T1pY"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="C+YljNqf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4DE16206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7N1rD6WtLUg/Zq1rMNONXs380Uq4Jn4RU1fvhM64XYI=; b=XG+4T1pYdZGXNIJp1LkIJF0zGS 3uiuhjcnMPA4rtyfHIBgHPuRfde0JtTP1VsBy2GjLO8OMTJkgcEkrf8q2HQ8PI9JJ6VQChSoBwofv f/kSHDYZP7TS0T4nPkHpFDvXlZN+YmX4LBE0PokXwpxmzkG6HXYAABzJrPZXNiPqbaJXOBb/e+Qy7 05enTI/ZdtqBcNvPaFqLm1oc+9VpbKgH0xrmFYqPsFOg1rRGDsQqd32x8oSvVHGWD8tqrIELOjqG2 wSHROSh7UJewpZkVHDFgS4LPgKm6TPCEKIEkreu7ZRQn5v/GiUU4GSELE6Tj+bDDfyeTmbWNZjXRa 4fhQvDKQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr74-0000OG-16; Tue, 21 Jul 2020 12:11:14 +0000 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr6x-0000MA-NJ for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 12:11:09 +0000 Received: by mail-pf1-x443.google.com with SMTP id q17so10620505pfu.8 for ; Tue, 21 Jul 2020 05:11:07 -0700 (PDT) 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=OGQRgVBuDs2YGom8JxN4Q6Y+XwAeTFKd4PRQsmAWmzk=; b=C+YljNqfo+m3jtYr5ucEEoBYZHGPJbJaYid6dRHAr3tg1SE4+PBla45YLdd3dzeAHV 90eRRECKtqlWsTY5czSJlAD1vbdg7ui2zXs9SHToZ6XnExMoNPkSDk+ML6y5WMAiy/ZD mDdVglWsqvth6SRd/6q3aFFQsxwYNgryrerakMMD+NV6wrDxUFLEeKNiqogb/3o2KXkd u6VZ1ra+OywG31748fw9BXQkhU0S+LSiBUwohiti/NQQReJsbeDTqHTcaP2NTmtdYEnC DTBsy6kLBZAlelpCT8CxjgLWv9tbmZYh7QoBm1TGYKc7xtGEbI5j8iw64L4vOMCRB4rF oCTg== 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=OGQRgVBuDs2YGom8JxN4Q6Y+XwAeTFKd4PRQsmAWmzk=; b=HTiYSp5n1p/pxuIQ1hkOvXGJr/pnNcvgTEX8LGEAGxIst8g3dh1l8QUhWgsj+qh92x MYzJSoph+ae7JKm6ExcOpruDx5t7b4PObXwrCJ2bdJ4dWGzTHr/t8AjB+g1wb8TBUzLm pvzGVX9t8k7iERwDuN+mbiUhpxQzXG/IGjpFAPYQS9wUEq4Xto2499S7jSXqfsqC36kI zp4jmH0/xMnqDKAan9P/HgV9kpNve4IXUGvPrRT4MLgtXI+wKnL+3LWUjRkcUavSQhxL WrCE8D0mFlYkyoOXR2wEhUl2eavTZa7QbDUXA/14OSe1qoh6txRHaOlu2PidB+daf5ip s8/g== X-Gm-Message-State: AOAM532P0kSxLNMd50iO8mi9sihocKjAuD99hPD0/MMsAmvBQwOfvGMc MjX0EVCKt4Wr0Z3un15zM5y9Zg== X-Google-Smtp-Source: ABdhPJwbPLE5qE6oDrg12B+GPfjB19fSVE5EYiyAwJo6+g7xrMU3f6F7QpxgLLkrhSFzZ1GWjG8yLw== X-Received: by 2002:a63:f254:: with SMTP id d20mr15590929pgk.119.1595333465291; Tue, 21 Jul 2020 05:11:05 -0700 (PDT) Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id w9sm20601992pfq.178.2020.07.21.05.11.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Jul 2020 05:11:04 -0700 (PDT) From: Sumit Garg To: gregkh@linuxfoundation.org, daniel.thompson@linaro.org, dianders@chromium.org, linux-serial@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [RFC 3/5] serial: amba-pl011: Re-order APIs definition Date: Tue, 21 Jul 2020 17:40:11 +0530 Message-Id: <1595333413-30052-4-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> References: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_081107_818014_633186BE X-CRM114-Status: GOOD ( 21.60 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:443 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sumit Garg , jslaby@suse.com, linux-kernel@vger.kernel.org, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org A future patch will need to call pl011_hwinit() and pl011_enable_interrupts() before they are currently defined. Move them closer to the front of the file. There is no change in the implementation of either function. Signed-off-by: Sumit Garg --- drivers/tty/serial/amba-pl011.c | 148 ++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8efd7c2..0983c5e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1581,6 +1581,80 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&uap->port.lock, flags); } +static int pl011_hwinit(struct uart_port *port) +{ + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + int retval; + + /* Optionaly enable pins to be muxed in and configured */ + pinctrl_pm_select_default_state(port->dev); + + /* + * Try to enable the clock producer. + */ + retval = clk_prepare_enable(uap->clk); + if (retval) + return retval; + + uap->port.uartclk = clk_get_rate(uap->clk); + + /* Clear pending error and receive interrupts */ + pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | + UART011_FEIS | UART011_RTIS | UART011_RXIS, + uap, REG_ICR); + + /* + * Save interrupts enable mask, and enable RX interrupts in case if + * the interrupt is used for NMI entry. + */ + uap->im = pl011_read(uap, REG_IMSC); + pl011_write(UART011_RTIM | UART011_RXIM, uap, REG_IMSC); + + if (dev_get_platdata(uap->port.dev)) { + struct amba_pl011_data *plat; + + plat = dev_get_platdata(uap->port.dev); + if (plat->init) + plat->init(); + } + return 0; +} + +/* + * Enable interrupts, only timeouts when using DMA + * if initial RX DMA job failed, start in interrupt mode + * as well. + */ +static void pl011_enable_interrupts(struct uart_amba_port *uap) +{ + unsigned int i; + + spin_lock_irq(&uap->port.lock); + + /* Clear out any spuriously appearing RX interrupts */ + pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); + + /* + * RXIS is asserted only when the RX FIFO transitions from below + * to above the trigger threshold. If the RX FIFO is already + * full to the threshold this can't happen and RXIS will now be + * stuck off. Drain the RX FIFO explicitly to fix this: + */ + for (i = 0; i < uap->fifosize * 2; ++i) { + if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE) + break; + + pl011_read(uap, REG_DR); + } + + uap->im = UART011_RTIM; + if (!pl011_dma_rx_running(uap)) + uap->im |= UART011_RXIM; + pl011_write(uap->im, uap, REG_IMSC); + spin_unlock_irq(&uap->port.lock); +} + #ifdef CONFIG_CONSOLE_POLL static void pl011_quiesce_irqs(struct uart_port *port) @@ -1639,46 +1713,6 @@ static void pl011_put_poll_char(struct uart_port *port, #endif /* CONFIG_CONSOLE_POLL */ -static int pl011_hwinit(struct uart_port *port) -{ - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); - int retval; - - /* Optionaly enable pins to be muxed in and configured */ - pinctrl_pm_select_default_state(port->dev); - - /* - * Try to enable the clock producer. - */ - retval = clk_prepare_enable(uap->clk); - if (retval) - return retval; - - uap->port.uartclk = clk_get_rate(uap->clk); - - /* Clear pending error and receive interrupts */ - pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | - UART011_FEIS | UART011_RTIS | UART011_RXIS, - uap, REG_ICR); - - /* - * Save interrupts enable mask, and enable RX interrupts in case if - * the interrupt is used for NMI entry. - */ - uap->im = pl011_read(uap, REG_IMSC); - pl011_write(UART011_RTIM | UART011_RXIM, uap, REG_IMSC); - - if (dev_get_platdata(uap->port.dev)) { - struct amba_pl011_data *plat; - - plat = dev_get_platdata(uap->port.dev); - if (plat->init) - plat->init(); - } - return 0; -} - static bool pl011_split_lcrh(const struct uart_amba_port *uap) { return pl011_reg_to_offset(uap, REG_LCRH_RX) != @@ -1707,40 +1741,6 @@ static int pl011_allocate_irq(struct uart_amba_port *uap) return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap); } -/* - * Enable interrupts, only timeouts when using DMA - * if initial RX DMA job failed, start in interrupt mode - * as well. - */ -static void pl011_enable_interrupts(struct uart_amba_port *uap) -{ - unsigned int i; - - spin_lock_irq(&uap->port.lock); - - /* Clear out any spuriously appearing RX interrupts */ - pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); - - /* - * RXIS is asserted only when the RX FIFO transitions from below - * to above the trigger threshold. If the RX FIFO is already - * full to the threshold this can't happen and RXIS will now be - * stuck off. Drain the RX FIFO explicitly to fix this: - */ - for (i = 0; i < uap->fifosize * 2; ++i) { - if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE) - break; - - pl011_read(uap, REG_DR); - } - - uap->im = UART011_RTIM; - if (!pl011_dma_rx_running(uap)) - uap->im |= UART011_RXIM; - pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irq(&uap->port.lock); -} - static int pl011_startup(struct uart_port *port) { struct uart_amba_port *uap = From patchwork Tue Jul 21 12:10:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 11675585 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8E64214E3 for ; Tue, 21 Jul 2020 12:12:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 68724206E9 for ; Tue, 21 Jul 2020 12:12:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="H24GBDTl"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="qCxiWVCI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 68724206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=v4bUSKCPmZOEnCwRcvi6AJqwTjnueDPxY6nzMFFlvzs=; b=H24GBDTleb0PJjQjjqMT/IP7Gk 9VuD2j5DOJw5SzoPXbkCRrzyoarkMKh1ahDgJaynWVk3YFakznQihSZ+GKwS18uaGEJVFnt/DIbuq 7BopVtdCXLFx+k7PV9PglH29PJNNx9Ojq+lhK75jF/wDDsRzHg7jkXBJFYKQB66yNl9Ob2GpbG5ME JbAJG9HZUw933A37hHLlMAgN0cd3k7tge+HGFxT7ohBNnjQvrc2zBs4Y/SWcyOz4+4sVY+8T505pV Pn0eZbL8GTisfTSRhcP4r+1f/bMpD1n/L9Iu8m3sKYimzjMpZ5V377NvS3uQuspEDFJyaVUIbc78k WMiTe68w==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr7D-0000S6-3g; Tue, 21 Jul 2020 12:11:23 +0000 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr73-0000Ns-GW for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 12:11:14 +0000 Received: by mail-pg1-x541.google.com with SMTP id j19so11835052pgm.11 for ; Tue, 21 Jul 2020 05:11:12 -0700 (PDT) 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=2zOkNlooR1zcsl5ai3d/r17122nHEKv/dFvwHU/KZrA=; b=qCxiWVCIYBZyxLsMeE0w7kCkNJoBZ7QRMGqB8iz9+cZylR3Kxiuii46cbejMIY5/Np ZPzpH/PyZvdzSoaoO7jzVg7fQcXnSQx4/lfSr/0aek5vJ/moI57rKq5+4cqL+06Q6siA ziJkw20K+BOosurBJ8w5GtJj6skjC3rNixycBb+zVpuP1yXWrvoEsRM3SArliy201rSc Kmlz87fkvx+pqm6TXR7sILSVPWtN5AMhcvfyLkpHxVnnib/39NDu7LBfAoHjxHNspceS kmhG+kH5t7cmNe14hfKOHg7LeuJT4Q0m0CwyhqWLQqnc3T6DfETzD4UG11CpF2kCND1/ Dc5w== 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=2zOkNlooR1zcsl5ai3d/r17122nHEKv/dFvwHU/KZrA=; b=nmSUsSWtDUUDReNACCQIb6X3n1FAzeRsEyOb9IrFdObDXUXUZrimcPjupszB11TDHz 4qbjmuvAa5ttk9T/0rkC4FOgK6kkZ2bj5kuMlAK9I+XKoTNxWSvJcSLL2XyshXgRisJ2 JQbsOHUUo39pGpp0SYLezy0d/PGkv974rjTBaZvyAXm+jmxaoDofSmT8/0tBhXKT97wG X9LUgq3t7SYNdln8qn3bN1cMwmhmKA9/9f+xO2/GXaMdpiZPdO5A5dxCQAAap8V8aqL7 NZ6kzuFnn+lgcgRi5R/sXoCFxhm12Ope27XSshwKzFYD2gG6Hu4Zv7EHfd3TkO93iRuV AiGg== X-Gm-Message-State: AOAM533bqQbbc/7zbVrhKWVuYTAK16vtB+IH0SGoLJEUtzQFd3ZCEElM arqcll5tKGyrYJiufXnfJypatg== X-Google-Smtp-Source: ABdhPJwKUmsn6lRMXYTYzTogmHp0PD64aIq6+1XW2ha8ClQcPj9F4Yp1/qWxe7LuhU7j6OSsyTNzkg== X-Received: by 2002:a05:6a00:2292:: with SMTP id f18mr24239679pfe.192.1595333471193; Tue, 21 Jul 2020 05:11:11 -0700 (PDT) Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id w9sm20601992pfq.178.2020.07.21.05.11.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Jul 2020 05:11:10 -0700 (PDT) From: Sumit Garg To: gregkh@linuxfoundation.org, daniel.thompson@linaro.org, dianders@chromium.org, linux-serial@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [RFC 4/5] serial: amba-pl011: Enable NMI aware uart port Date: Tue, 21 Jul 2020 17:40:12 +0530 Message-Id: <1595333413-30052-5-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> References: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_081113_620636_C9B4CC38 X-CRM114-Status: GOOD ( 22.58 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:541 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sumit Garg , jslaby@suse.com, linux-kernel@vger.kernel.org, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Allow serial device interrupt to be requested as an NMI during initialization in polling mode. If the irqchip doesn't support serial device interrupt as an NMI then fallback to it being as a normal IRQ. Currently this NMI aware uart port only supports NMI driven programmed IO operation whereas DMA operation isn't supported. And while operating in NMI mode, RX always remains active irrespective of whether corresponding TTY port is active or not. So we directly bail out of startup, shutdown and rx_stop APIs if NMI mode is active. Also, get rid of modification to interrupts enable mask in pl011_hwinit() as now we have a proper way to enable interrupts for NMI entry using pl011_enable_interrupts(). Signed-off-by: Sumit Garg --- drivers/tty/serial/amba-pl011.c | 124 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 0983c5e..5df1c07 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include "amba-pl011.h" @@ -347,6 +349,10 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) if (uart_handle_sysrq_char(&uap->port, ch & 255)) continue; + if (uart_nmi_handle_char(&uap->port, ch, UART011_DR_OE, ch, + flag)) + continue; + uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); } @@ -1316,6 +1322,9 @@ static void pl011_stop_rx(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); + if (uart_nmi_active(port)) + return; + uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| UART011_PEIM|UART011_BEIM|UART011_OEIM); pl011_write(uap->im, uap, REG_IMSC); @@ -1604,13 +1613,6 @@ static int pl011_hwinit(struct uart_port *port) UART011_FEIS | UART011_RTIS | UART011_RXIS, uap, REG_ICR); - /* - * Save interrupts enable mask, and enable RX interrupts in case if - * the interrupt is used for NMI entry. - */ - uap->im = pl011_read(uap, REG_IMSC); - pl011_write(UART011_RTIM | UART011_RXIM, uap, REG_IMSC); - if (dev_get_platdata(uap->port.dev)) { struct amba_pl011_data *plat; @@ -1711,6 +1713,96 @@ static void pl011_put_poll_char(struct uart_port *port, pl011_write(ch, uap, REG_DR); } +static irqreturn_t pl011_nmi_int(int irq, void *dev_id) +{ + struct uart_amba_port *uap = dev_id; + unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; + int handled = 0; + + status = pl011_read(uap, REG_MIS); + if (status) { + do { + check_apply_cts_event_workaround(uap); + + pl011_write(status, uap, REG_ICR); + + if (status & (UART011_RTIS|UART011_RXIS)) { + pl011_fifo_to_tty(uap); + irq_work_queue(&uap->port.nmi_state.rx_work); + } + + if (status & UART011_TXIS) + irq_work_queue(&uap->port.nmi_state.tx_work); + + if (pass_counter-- == 0) + break; + + status = pl011_read(uap, REG_MIS); + } while (status != 0); + handled = 1; + } + + return IRQ_RETVAL(handled); +} + +static int pl011_allocate_nmi(struct uart_amba_port *uap) +{ + int ret; + + irq_set_status_flags(uap->port.irq, IRQ_NOAUTOEN); + ret = request_nmi(uap->port.irq, pl011_nmi_int, IRQF_PERCPU, + "uart-pl011", uap); + if (ret) { + irq_clear_status_flags(uap->port.irq, IRQ_NOAUTOEN); + return ret; + } + + enable_irq(uap->port.irq); + + return ret; +} + +static void pl011_tx_irq_callback(struct uart_port *port) +{ + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + + spin_lock(&port->lock); + pl011_tx_chars(uap, true); + spin_unlock(&port->lock); +} + +static int pl011_poll_init(struct uart_port *port) +{ + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + int retval; + + retval = pl011_hwinit(port); + if (retval) + goto clk_dis; + + /* In case NMI isn't supported, fallback to normal interrupt mode */ + retval = pl011_allocate_nmi(uap); + if (retval) + return 0; + + retval = uart_nmi_state_init(port); + if (retval) + goto clk_dis; + + port->nmi_state.tx_irq_callback = pl011_tx_irq_callback; + uart_set_nmi_active(port, true); + + pl011_enable_interrupts(uap); + + return 0; + + clk_dis: + clk_disable_unprepare(uap->clk); + return retval; +} + #endif /* CONFIG_CONSOLE_POLL */ static bool pl011_split_lcrh(const struct uart_amba_port *uap) @@ -1736,8 +1828,6 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) static int pl011_allocate_irq(struct uart_amba_port *uap) { - pl011_write(uap->im, uap, REG_IMSC); - return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap); } @@ -1748,6 +1838,9 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + if (uart_nmi_active(port)) + return 0; + retval = pl011_hwinit(port); if (retval) goto clk_dis; @@ -1790,6 +1883,9 @@ static int sbsa_uart_startup(struct uart_port *port) container_of(port, struct uart_amba_port, port); int retval; + if (uart_nmi_active(port)) + return 0; + retval = pl011_hwinit(port); if (retval) return retval; @@ -1859,6 +1955,9 @@ static void pl011_shutdown(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); + if (uart_nmi_active(port)) + return; + pl011_disable_interrupts(uap); pl011_dma_shutdown(uap); @@ -1891,6 +1990,9 @@ static void sbsa_uart_shutdown(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); + if (uart_nmi_active(port)) + return; + pl011_disable_interrupts(uap); free_irq(uap->port.irq, uap); @@ -2142,7 +2244,7 @@ static const struct uart_ops amba_pl011_pops = { .config_port = pl011_config_port, .verify_port = pl011_verify_port, #ifdef CONFIG_CONSOLE_POLL - .poll_init = pl011_hwinit, + .poll_init = pl011_poll_init, .poll_get_char = pl011_get_poll_char, .poll_put_char = pl011_put_poll_char, #endif @@ -2173,7 +2275,7 @@ static const struct uart_ops sbsa_uart_pops = { .config_port = pl011_config_port, .verify_port = pl011_verify_port, #ifdef CONFIG_CONSOLE_POLL - .poll_init = pl011_hwinit, + .poll_init = pl011_poll_init, .poll_get_char = pl011_get_poll_char, .poll_put_char = pl011_put_poll_char, #endif From patchwork Tue Jul 21 12:10:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 11675589 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C2DFB618 for ; Tue, 21 Jul 2020 12:12:55 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8DFBD206E9 for ; Tue, 21 Jul 2020 12:12:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="vYvn13Df"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="uf70pNth" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8DFBD206E9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1QI8vxSHTFiR74wmfFuToXbn/DHVqs/heljhhMH4Nw4=; b=vYvn13DfpYas6HcTH6adMeQ7d BJp/LepujA/BmEC5xq0hBxlKKBxZOj7V78vA7y1eAjv9Jdx9PrmhWEZl90UURmvP+s89gGdYS4+bh uUv1SZWnjtVJ9YO5VLQlvbE5UxCPKOGY7sbiuWITBcYStq9v1ETPLOKYkDFwizLCI+Gngnq3AWPcb Ce3femg+Kj5k/HatQXsD32wuL61XsS+1SbWLY5Dtif2ltIk/Zprc6Q7RdhmS26hmbBCs20ixvgSS4 9YrM9yICojZaWDWANKe2/oWIdTMe7YCz5XIoav83iVswqdVvuKERXgG7iW5dKCihXlZyxJIafAOdG cPkZHazAg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr7K-0000Ue-G6; Tue, 21 Jul 2020 12:11:30 +0000 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxr79-0000Qd-7X for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 12:11:26 +0000 Received: by mail-pf1-x441.google.com with SMTP id 1so10644665pfn.9 for ; Tue, 21 Jul 2020 05:11:18 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=N4Vrr3RPHrWaZucTwZmFhL/vg7dtTdfGT3O+wG1Ixzw=; b=uf70pNthNkaG3TDajmNXQMzUZC357fX+gxRyGvjVoSt7QCQD+VlLfXEpUgB7chSAz6 FuBv3g5/v5cCY5sSHmWYxMWVGAcX/6yDmSmrb+oKCinGzeScKnAwpUZ1P+tEKAnRYfs7 Ja0AJZGiOm2s51IyFYTYMx8IDbE4GLdwb3civ6b5D0rKMcUzzulkbxVSEtYE6V95wGUm 7ha67V/Mww5u18Pk2tOxvaKnnyy6RxjLgpmbLlXCXHSMQpfu7ZV1qj97i1Nw1Xg1LfkO aay91kXJy6qnhoNRyr53om2Qs7jjUp+jzFAonpY8FVRxVINqOMymAN9HH4l0ENsgeQf6 mQbA== 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:mime-version:content-transfer-encoding; bh=N4Vrr3RPHrWaZucTwZmFhL/vg7dtTdfGT3O+wG1Ixzw=; b=EdZ7PrJpeL0m5cj1A+lBjuHNSXSn/X0RKYZmbWZw9gG8nXx48K60A9vK5KJ3sXTp0e kr5YQje2ufU5oaBIx/0VC9Yn8zDd9hC30gK2aFBydX5wdVQ1puAvo3G0W9axmg4020Ez eBkiTG/drIPhVvf7W2b5uwCogi5C0VOpszSSPZPpcucgTJwYr/CINTVpl+xi1WNoukOz vQDRnI16DBscQur49namvL35z7sYhN6XP2tUSGqce7dtOGexnf5izW/XNthADSRdxrCV WVR+86MePTePVa35lJsGUgtPRoqbfveNBNrDx1Xlf8KXZlZTEsYFfjJhikThPPCnof4a FoZw== X-Gm-Message-State: AOAM53204gyPMNwoG6w+D7agNJaiFVX1PqkqlSqFJJ+grSD3wlxv62eP Nze7UvpASHw1ylRY6TincZsh8w== X-Google-Smtp-Source: ABdhPJzUr3AOufOgS8kYacmYw2lEJYaoNCrAwivO0iMkoijWQgmxOSdj3Ydl+zm0ckA2gH2pdb+CWA== X-Received: by 2002:a65:63c8:: with SMTP id n8mr22380565pgv.232.1595333477168; Tue, 21 Jul 2020 05:11:17 -0700 (PDT) Received: from localhost.localdomain ([117.210.211.74]) by smtp.gmail.com with ESMTPSA id w9sm20601992pfq.178.2020.07.21.05.11.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Jul 2020 05:11:16 -0700 (PDT) From: Sumit Garg To: gregkh@linuxfoundation.org, daniel.thompson@linaro.org, dianders@chromium.org, linux-serial@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [RFC 5/5] serial: Remove KGDB NMI serial driver Date: Tue, 21 Jul 2020 17:40:13 +0530 Message-Id: <1595333413-30052-6-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> References: <1595333413-30052-1-git-send-email-sumit.garg@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_081119_461575_ED2A6F27 X-CRM114-Status: GOOD ( 27.81 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:441 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sumit Garg , jslaby@suse.com, linux-kernel@vger.kernel.org, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org This driver provided a special ttyNMI0 port to enable NMI debugging capabilities for kgdb but it remained in silos with the serial core/drivers which made it a bit odd to enable using serial device interrupt and hence remained unused. But now with the serial core/drivers becoming NMI aware which in turn provides NMI debugging capabilities via magic sysrq, there is no specific reason to keep this special driver. So remove it instead. Signed-off-by: Sumit Garg --- drivers/tty/serial/Kconfig | 19 --- drivers/tty/serial/Makefile | 1 - drivers/tty/serial/kgdb_nmi.c | 383 ------------------------------------------ drivers/tty/serial/kgdboc.c | 8 - include/linux/kgdb.h | 10 -- 5 files changed, 421 deletions(-) delete mode 100644 drivers/tty/serial/kgdb_nmi.c diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 780908d..625d283 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -176,25 +176,6 @@ config SERIAL_ATMEL_TTYAT Say Y if you have an external 8250/16C550 UART. If unsure, say N. -config SERIAL_KGDB_NMI - bool "Serial console over KGDB NMI debugger port" - depends on KGDB_SERIAL_CONSOLE - help - This special driver allows you to temporary use NMI debugger port - as a normal console (assuming that the port is attached to KGDB). - - Unlike KDB's disable_nmi command, with this driver you are always - able to go back to the debugger using KGDB escape sequence ($3#33). - This is because this console driver processes the input in NMI - context, and thus is able to intercept the magic sequence. - - Note that since the console interprets input and uses polling - communication methods, for things like PPP you still must fully - detach debugger port from the KGDB NMI (i.e. disable_nmi), and - use raw console. - - If unsure, say N. - config SERIAL_MESON tristate "Meson serial port support" depends on ARCH_MESON diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index d056ee6..9ea6263 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -93,5 +93,4 @@ obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o -obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c deleted file mode 100644 index 6004c0c..0000000 --- a/drivers/tty/serial/kgdb_nmi.c +++ /dev/null @@ -1,383 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * KGDB NMI serial console - * - * Copyright 2010 Google, Inc. - * Arve Hjønnevåg - * Colin Cross - * Copyright 2012 Linaro Ltd. - * Anton Vorontsov - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int kgdb_nmi_knock = 1; -module_param_named(knock, kgdb_nmi_knock, int, 0600); -MODULE_PARM_DESC(knock, "if set to 1 (default), the special '$3#33' command " \ - "must be used to enter the debugger; when set to 0, " \ - "hitting return key is enough to enter the debugger; " \ - "when set to -1, the debugger is entered immediately " \ - "upon NMI"); - -static char *kgdb_nmi_magic = "$3#33"; -module_param_named(magic, kgdb_nmi_magic, charp, 0600); -MODULE_PARM_DESC(magic, "magic sequence to enter NMI debugger (default $3#33)"); - -static atomic_t kgdb_nmi_num_readers = ATOMIC_INIT(0); - -static int kgdb_nmi_console_setup(struct console *co, char *options) -{ - arch_kgdb_ops.enable_nmi(1); - - /* The NMI console uses the dbg_io_ops to issue console messages. To - * avoid duplicate messages during kdb sessions we must inform kdb's - * I/O utilities that messages sent to the console will automatically - * be displayed on the dbg_io. - */ - dbg_io_ops->cons = co; - - return 0; -} - -static void kgdb_nmi_console_write(struct console *co, const char *s, uint c) -{ - int i; - - for (i = 0; i < c; i++) - dbg_io_ops->write_char(s[i]); -} - -static struct tty_driver *kgdb_nmi_tty_driver; - -static struct tty_driver *kgdb_nmi_console_device(struct console *co, int *idx) -{ - *idx = co->index; - return kgdb_nmi_tty_driver; -} - -static struct console kgdb_nmi_console = { - .name = "ttyNMI", - .setup = kgdb_nmi_console_setup, - .write = kgdb_nmi_console_write, - .device = kgdb_nmi_console_device, - .flags = CON_PRINTBUFFER | CON_ANYTIME, - .index = -1, -}; - -/* - * This is usually the maximum rate on debug ports. We make fifo large enough - * to make copy-pasting to the terminal usable. - */ -#define KGDB_NMI_BAUD 115200 -#define KGDB_NMI_FIFO_SIZE roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ) - -struct kgdb_nmi_tty_priv { - struct tty_port port; - struct timer_list timer; - STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo; -}; - -static struct tty_port *kgdb_nmi_port; - -static void kgdb_tty_recv(int ch) -{ - struct kgdb_nmi_tty_priv *priv; - char c = ch; - - if (!kgdb_nmi_port || ch < 0) - return; - /* - * Can't use port->tty->driver_data as tty might be not there. Timer - * will check for tty and will get the ref, but here we don't have to - * do that, and actually, we can't: we're in NMI context, no locks are - * possible. - */ - priv = container_of(kgdb_nmi_port, struct kgdb_nmi_tty_priv, port); - kfifo_in(&priv->fifo, &c, 1); -} - -static int kgdb_nmi_poll_one_knock(void) -{ - static int n; - int c = -1; - const char *magic = kgdb_nmi_magic; - size_t m = strlen(magic); - bool printch = false; - - c = dbg_io_ops->read_char(); - if (c == NO_POLL_CHAR) - return c; - - if (!kgdb_nmi_knock && (c == '\r' || c == '\n')) { - return 1; - } else if (c == magic[n]) { - n = (n + 1) % m; - if (!n) - return 1; - printch = true; - } else { - n = 0; - } - - if (atomic_read(&kgdb_nmi_num_readers)) { - kgdb_tty_recv(c); - return 0; - } - - if (printch) { - kdb_printf("%c", c); - return 0; - } - - kdb_printf("\r%s %s to enter the debugger> %*s", - kgdb_nmi_knock ? "Type" : "Hit", - kgdb_nmi_knock ? magic : "", (int)m, ""); - while (m--) - kdb_printf("\b"); - return 0; -} - -/** - * kgdb_nmi_poll_knock - Check if it is time to enter the debugger - * - * "Serial ports are often noisy, especially when muxed over another port (we - * often use serial over the headset connector). Noise on the async command - * line just causes characters that are ignored, on a command line that blocked - * execution noise would be catastrophic." -- Colin Cross - * - * So, this function implements KGDB/KDB knocking on the serial line: we won't - * enter the debugger until we receive a known magic phrase (which is actually - * "$3#33", known as "escape to KDB" command. There is also a relaxed variant - * of knocking, i.e. just pressing the return key is enough to enter the - * debugger. And if knocking is disabled, the function always returns 1. - */ -bool kgdb_nmi_poll_knock(void) -{ - if (kgdb_nmi_knock < 0) - return true; - - while (1) { - int ret; - - ret = kgdb_nmi_poll_one_knock(); - if (ret == NO_POLL_CHAR) - return false; - else if (ret == 1) - break; - } - return true; -} - -/* - * The tasklet is cheap, it does not cause wakeups when reschedules itself, - * instead it waits for the next tick. - */ -static void kgdb_nmi_tty_receiver(struct timer_list *t) -{ - struct kgdb_nmi_tty_priv *priv = from_timer(priv, t, timer); - char ch; - - priv->timer.expires = jiffies + (HZ/100); - add_timer(&priv->timer); - - if (likely(!atomic_read(&kgdb_nmi_num_readers) || - !kfifo_len(&priv->fifo))) - return; - - while (kfifo_out(&priv->fifo, &ch, 1)) - tty_insert_flip_char(&priv->port, ch, TTY_NORMAL); - tty_flip_buffer_push(&priv->port); -} - -static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct kgdb_nmi_tty_priv *priv = - container_of(port, struct kgdb_nmi_tty_priv, port); - - kgdb_nmi_port = port; - priv->timer.expires = jiffies + (HZ/100); - add_timer(&priv->timer); - - return 0; -} - -static void kgdb_nmi_tty_shutdown(struct tty_port *port) -{ - struct kgdb_nmi_tty_priv *priv = - container_of(port, struct kgdb_nmi_tty_priv, port); - - del_timer(&priv->timer); - kgdb_nmi_port = NULL; -} - -static const struct tty_port_operations kgdb_nmi_tty_port_ops = { - .activate = kgdb_nmi_tty_activate, - .shutdown = kgdb_nmi_tty_shutdown, -}; - -static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty) -{ - struct kgdb_nmi_tty_priv *priv; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - INIT_KFIFO(priv->fifo); - timer_setup(&priv->timer, kgdb_nmi_tty_receiver, 0); - tty_port_init(&priv->port); - priv->port.ops = &kgdb_nmi_tty_port_ops; - tty->driver_data = priv; - - ret = tty_port_install(&priv->port, drv, tty); - if (ret) { - pr_err("%s: can't install tty port: %d\n", __func__, ret); - goto err; - } - return 0; -err: - tty_port_destroy(&priv->port); - kfree(priv); - return ret; -} - -static void kgdb_nmi_tty_cleanup(struct tty_struct *tty) -{ - struct kgdb_nmi_tty_priv *priv = tty->driver_data; - - tty->driver_data = NULL; - tty_port_destroy(&priv->port); - kfree(priv); -} - -static int kgdb_nmi_tty_open(struct tty_struct *tty, struct file *file) -{ - struct kgdb_nmi_tty_priv *priv = tty->driver_data; - unsigned int mode = file->f_flags & O_ACCMODE; - int ret; - - ret = tty_port_open(&priv->port, tty, file); - if (!ret && (mode == O_RDONLY || mode == O_RDWR)) - atomic_inc(&kgdb_nmi_num_readers); - - return ret; -} - -static void kgdb_nmi_tty_close(struct tty_struct *tty, struct file *file) -{ - struct kgdb_nmi_tty_priv *priv = tty->driver_data; - unsigned int mode = file->f_flags & O_ACCMODE; - - if (mode == O_RDONLY || mode == O_RDWR) - atomic_dec(&kgdb_nmi_num_readers); - - tty_port_close(&priv->port, tty, file); -} - -static void kgdb_nmi_tty_hangup(struct tty_struct *tty) -{ - struct kgdb_nmi_tty_priv *priv = tty->driver_data; - - tty_port_hangup(&priv->port); -} - -static int kgdb_nmi_tty_write_room(struct tty_struct *tty) -{ - /* Actually, we can handle any amount as we use polled writes. */ - return 2048; -} - -static int kgdb_nmi_tty_write(struct tty_struct *tty, const unchar *buf, int c) -{ - int i; - - for (i = 0; i < c; i++) - dbg_io_ops->write_char(buf[i]); - return c; -} - -static const struct tty_operations kgdb_nmi_tty_ops = { - .open = kgdb_nmi_tty_open, - .close = kgdb_nmi_tty_close, - .install = kgdb_nmi_tty_install, - .cleanup = kgdb_nmi_tty_cleanup, - .hangup = kgdb_nmi_tty_hangup, - .write_room = kgdb_nmi_tty_write_room, - .write = kgdb_nmi_tty_write, -}; - -int kgdb_register_nmi_console(void) -{ - int ret; - - if (!arch_kgdb_ops.enable_nmi) - return 0; - - kgdb_nmi_tty_driver = alloc_tty_driver(1); - if (!kgdb_nmi_tty_driver) { - pr_err("%s: cannot allocate tty\n", __func__); - return -ENOMEM; - } - kgdb_nmi_tty_driver->driver_name = "ttyNMI"; - kgdb_nmi_tty_driver->name = "ttyNMI"; - kgdb_nmi_tty_driver->num = 1; - kgdb_nmi_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - kgdb_nmi_tty_driver->subtype = SERIAL_TYPE_NORMAL; - kgdb_nmi_tty_driver->flags = TTY_DRIVER_REAL_RAW; - kgdb_nmi_tty_driver->init_termios = tty_std_termios; - tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios, - KGDB_NMI_BAUD, KGDB_NMI_BAUD); - tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops); - - ret = tty_register_driver(kgdb_nmi_tty_driver); - if (ret) { - pr_err("%s: can't register tty driver: %d\n", __func__, ret); - goto err_drv_reg; - } - - register_console(&kgdb_nmi_console); - - return 0; -err_drv_reg: - put_tty_driver(kgdb_nmi_tty_driver); - return ret; -} -EXPORT_SYMBOL_GPL(kgdb_register_nmi_console); - -int kgdb_unregister_nmi_console(void) -{ - int ret; - - if (!arch_kgdb_ops.enable_nmi) - return 0; - arch_kgdb_ops.enable_nmi(0); - - ret = unregister_console(&kgdb_nmi_console); - if (ret) - return ret; - - ret = tty_unregister_driver(kgdb_nmi_tty_driver); - if (ret) - return ret; - put_tty_driver(kgdb_nmi_tty_driver); - - return 0; -} -EXPORT_SYMBOL_GPL(kgdb_unregister_nmi_console); diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 84ffede..e959e72 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -158,8 +158,6 @@ static void cleanup_kgdboc(void) if (configured != 1) return; - if (kgdb_unregister_nmi_console()) - return; kgdboc_unregister_kbd(); kgdb_unregister_io_module(&kgdboc_io_ops); } @@ -210,16 +208,10 @@ static int configure_kgdboc(void) if (err) goto noconfig; - err = kgdb_register_nmi_console(); - if (err) - goto nmi_con_failed; - configured = 1; return 0; -nmi_con_failed: - kgdb_unregister_io_module(&kgdboc_io_ops); noconfig: kgdboc_unregister_kbd(); configured = 0; diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 529116b..2e8c5de 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -294,16 +294,6 @@ extern const struct kgdb_arch arch_kgdb_ops; extern unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs); -#ifdef CONFIG_SERIAL_KGDB_NMI -extern int kgdb_register_nmi_console(void); -extern int kgdb_unregister_nmi_console(void); -extern bool kgdb_nmi_poll_knock(void); -#else -static inline int kgdb_register_nmi_console(void) { return 0; } -static inline int kgdb_unregister_nmi_console(void) { return 0; } -static inline bool kgdb_nmi_poll_knock(void) { return true; } -#endif - extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); extern struct kgdb_io *dbg_io_ops;