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: 246635 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp2858707ilg; Tue, 21 Jul 2020 05:10:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxeuVLXzB5pGD9O1cgSGCzNPbUQWYcl2V23u7xaTOdNKoHMsBLjjcfe3l88rWieJlyk/qqQ X-Received: by 2002:aa7:da90:: with SMTP id q16mr24790733eds.44.1595333455804; Tue, 21 Jul 2020 05:10:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595333455; cv=none; d=google.com; s=arc-20160816; b=vm5hCPycxaMEluzdWx5GDbOWe1OAQcsg4VG4YAvLQN3KzN/KMHwXdVxbec82E/LVjJ vR8j7LeChkFqmMoKrrirxjTg8kFCmuvlxzWJh2kl5TI9P2+lIIDCdpC4AbQzzKL0Oejj tre0OCd7EwzQfWWlnRxVSTG96pyWCd1PkHksabgnT4TE91rAp2LOsdpsLoHjVPiHeRPD qf0rE/pfYQJTABqH5mnh2/pyhgiBP+Qo/HLu/pnVJKy3/ovuSqMCiWisJzu7OwMd+l4M eK8lzZ01NCr6De1KGd8LD2vEr2AJiCf6r0q8iE3s0DNG8mjvjV6ikGU0mmrSxAZG602C x8/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=bmoIA6JVwOy+6GP1zUPLm+Haa8V9hMBSF82Ea7A25DQ=; b=vZv//qQg2TgtiF76JQIRdPb4RwfDpCLxOM7XLCitTVXsP6nSoSgiP93ldXYOLasKkh Xp1HjMSJ4L2J7zHZv8OIwhfr6+b284T8n3gKtqYFhL02qaWbrZeHRTZ5WBD7HYBve4HC zrHxDS8IUxAFyb1IeTni/u4uqjtzYDiK1Cyr8HGUmewbf6/C69MZyB+c0oBuQz7Fp1yp bakFfrjhE8xQeIEfPV4A9t5kmq4mrKmm85FHXeDu2Y/Bcd4gdiHtSK08kF/IHgXeCysa e0nUVTn/ctvCJNgLP3Kh3k0TshaIr/7BS15aZYLCEtABRNxBjBHNJRR3fg+VhI79jep0 l+oQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TyepKXn7; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e20si12056597edv.26.2020.07.21.05.10.55; Tue, 21 Jul 2020 05:10:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TyepKXn7; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728716AbgGUMKz (ORCPT + 2 others); Tue, 21 Jul 2020 08:10:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726904AbgGUMKy (ORCPT ); Tue, 21 Jul 2020 08:10:54 -0400 Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A392BC061794 for ; Tue, 21 Jul 2020 05:10:54 -0700 (PDT) Received: by mail-pf1-x441.google.com with SMTP id z3so10633767pfn.12 for ; Tue, 21 Jul 2020 05:10:54 -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=N+nrBgqJy4DBIkMnfUCHyH+2txxsaCLKWqWuYgZiyUIDedtA35uJ9Abb8xHijbZwfR 2kxPcchK8Ue93VbpkhyFowLx+7vJSmSjJTtx+yOVzbpt7ogHr2QkT7d/PBbD5hUucKOK eYPNoLWku63WXhMGEgCYyCQCLlSFMA8ZYn4dw5Uout8LsZuP22NI5fgg7nZjfjxS7x/5 vOLSGtskgHE8+qCoeJpGctVNPzFZ+Z4nrEwd4O5yDDyNoIA/M+uqGMaMC5iHSEq1A1Ej CSm1y31Sr+dCfP3jejqyCWA4WWNSIVVM4MHFasnckDNXsLIsg4mYfeDjp3S3vqwFk4pB lp5A== X-Gm-Message-State: AOAM531kd14XZW2yqVrHIrjdQDQ2u9/FhK9jDLflfRo4ruyyjVv25cC8 p4l7Nj1blCPRc1sE8asMFX29EQ== 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 Cc: jslaby@suse.com, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sumit Garg 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> Sender: linux-serial-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.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(-) -- 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 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: 246636 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp2858779ilg; Tue, 21 Jul 2020 05:11:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw6POEhPUatKJCTqV9WREPezPMlzPfnqoQQklzvgZzBykzPmjG+bC8j7Ij0JFK9ik/nUQdm X-Received: by 2002:a17:906:1402:: with SMTP id p2mr23981430ejc.126.1595333461657; Tue, 21 Jul 2020 05:11:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595333461; cv=none; d=google.com; s=arc-20160816; b=YrtIGE2jh9kFj2GjuiFm5JWdt6scbAC+VEmmMhv/Ar3/xVmdl7D7G5qm5QuVKJjVTl 03vKxWKe4UVCQhgS9oOMkj3cTKSo5w0qc9LsMX7hiSwTbU5JuuZu2BMXBoMf7WYQQ6RN 0TZBSDWEsS5kt1QdWT3TTFEcQhDuGNxuCD/upFXRfpjl/QzgZ+57kmWQjsV3eZ3JQPmv 3854aij5cSmEdoNtqoqymoEukYgmKFfwNOJxtVfRuJiv1MJ4HZZDes4k7jkApLVqCZOr vKLEfQjbHZQOuaSjqaUjo5TwRKQH0AW9JevEFfvwF2rbVRUY/bzZ3sVAKE+X3Ti0tJAG mQrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=jQ4rDDgYanuVEiD5VSyVtoHbMEWpqen32aI8GMWnA+0=; b=dGAbyiZfKVYha4awKIzg+4ITUoJneOsQVUricXJhpzfQFXyPaZ1By5pOXkWlh+Tfr6 p1rPXs3eVfho+OFGVMez8MfmePg4bquZNT6mpsHO4kVGWR4q+sJNf+OloaEal4T3kFGy LnS4/BLLP8HyNgvirpnNwLegEAHvZhqj37FLjYRxtV2RUw2kVI7IkAdFjnCjlSZLv2ZT E2g/oJ5DAo6Dk4D4QiKvo9WJJGM2p93NzKn0qGEbCIu+toduBk8f3DcFdzO9O+XsoQhW CZH6muGgs29HhDlrwRHMqGskUdlMe6NXBQN+rSHoqsoyN2D/GiOhVyYKFhNUfBXJYmkb OOxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BuARnLyS; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f12si12232425eje.309.2020.07.21.05.11.01; Tue, 21 Jul 2020 05:11:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BuARnLyS; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729009AbgGUMLB (ORCPT + 2 others); Tue, 21 Jul 2020 08:11:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728714AbgGUMLA (ORCPT ); Tue, 21 Jul 2020 08:11:00 -0400 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DC8EC0619D9 for ; Tue, 21 Jul 2020 05:11:00 -0700 (PDT) Received: by mail-pl1-x643.google.com with SMTP id b9so10182707plx.6 for ; Tue, 21 Jul 2020 05:11:00 -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=mitnixc+mUfp7el/nXU6y0LqrboIdrBVnBDURW5lNJssGxCcuZcdzZJPXxoyAxe3Wm 5g0SCAK3/LUjnqEnpNVNUFVVQRIKVAPJ6JCPSdZ+SxU+xWzkx9W1Dsq6/9/30F5eZEGD cmz9TVbAob4QtBRT/W98H2Usnb4t2ZEY1oQQiPO1O6XxW9YTh27bsz02GyEop/8SF+7O WM6nxWuqnyaEUW9XR6AHzS2omIGMvi1chrQxCEAONsKkIHxdivRzhtnjh9QiWRZBjkCr hN3RLQ1gkiEr0rgdkZAFu8HsxIF8pJ14EDuNAOsrftOOa0ZCadYtIrlc9zAwEl97pUX8 osow== X-Gm-Message-State: AOAM532IGrxYb3JmLO7PTSGPtEFlb0vs/j2wuTVDDi14VYlRwXdoA1tV Z0CMMbhWk+/2rH0kHqCZn5Wqdg== 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 Cc: jslaby@suse.com, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sumit Garg 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> Sender: linux-serial-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.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(-) -- 2.7.4 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: 246638 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp2858847ilg; Tue, 21 Jul 2020 05:11:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwnsf+sgg5Dlm1JtYC6Bk/8GfXq16k+xXM/+w/MinAo3bRx8c3Ow5eVdUDO/KPGpRSvYwfy X-Received: by 2002:a17:906:1357:: with SMTP id x23mr26537095ejb.148.1595333467093; Tue, 21 Jul 2020 05:11:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595333467; cv=none; d=google.com; s=arc-20160816; b=H00Mgvw6oPJf8guuw6vVAlF4ib9s1rJTn56CEbKcSkTNUZjZBbHFl4E7m4+PlB/7/V 79dR2EIO/QOqPzAT0WkpHjxq1nSyQvN00iMGhTK3SDHckgMbiB65eIXyijxBJrqqanbd tSRZD/0/LjWZ0eKjp0IR3cxbBcM5be/PhjzEU+nALQrvgUQWLJTSMA2RnLw8tw9jBJz/ Mx7lo6NHOx3lmM6mHjuB8x5mAABzFMy78qelBdgHBBVM5ZLMivUZmFJOHSiPD+HAnL0O 0ZLWVAhxfj68zhLZtgH6jZslPz+QZxKO8eOW5s/G1SbZfEpbkEtjGrkyukaPyOEu0Ygd I/lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=OGQRgVBuDs2YGom8JxN4Q6Y+XwAeTFKd4PRQsmAWmzk=; b=tdIANUT4RrmeyddwE67wpqL7vbqg5spFCQ+88GCejKTVthusKW6+gs/wnByAZWK/Nf n8lLCnliRlVHUjDEXbIZZGA/0YTSb0PBtonn59Nwtbq4MMDqS283sLlU5CmyI1mh9KnB k0uAAtUHIQFEjBnDXb23ugXCV247XHEZ4+IzbC3rq+5XJTlw0ESoe0xvquvuNGQpnGe3 WOXj0E9oWwHTHMUJJxFUcSTXnDn6cvnN1U8e5LYAF+szOCrSDAkW7NZla5qWurPbWKsR 2U+TT9R4ryD2R45g3xdrWop2W5HD+qAXc3zdv1F6LZB73kar11gcUr/xpj3/B6a+1xEQ vW5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=C+YljNqf; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f12si12232425eje.309.2020.07.21.05.11.06; Tue, 21 Jul 2020 05:11:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=C+YljNqf; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729782AbgGUMLG (ORCPT + 2 others); Tue, 21 Jul 2020 08:11:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729718AbgGUMLF (ORCPT ); Tue, 21 Jul 2020 08:11:05 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1AD5C0619D9 for ; Tue, 21 Jul 2020 05:11:05 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id z5so11860217pgb.6 for ; Tue, 21 Jul 2020 05:11:05 -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=ZwMT1ZGhKYeQjmaRejAeyqx655dsT5dxzJFp4tEDcX5yLdhgpCz8SSfgriLQ5cORNs d8fZdusJjAsuAxFIdsKSl4cH9Z5iqVF5Wo0CB6gowYuMS0dzI4OnG0SUVhdvLt/udUoP bywnqpHGCtcpBYHd68SvVIvb++K5n9qGCXYMa5T269WeYxRaZdnN6TCcpAkX4EYuiVoX L75QUaPTeQv4GCgA5EH/NE8/sMLJfME04DpAFVRkyE12ZbYF9KpmPnK6BpMyXq0sXPbB cUVD1s/pAGkttaHxfzL5pN7fPVqIJiSgvulrPiIwwFVuBgN5HkKpNAgTSl2HEwBzoJsr 6bOg== X-Gm-Message-State: AOAM533WI80uZM6L3BjN/398XD1818pYh1UzrPVeQ2mVUF8TKUV6BIJD lFLS/yypePVuljSt10TyPQRAMg== 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 Cc: jslaby@suse.com, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sumit Garg 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> Sender: linux-serial-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.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(-) -- 2.7.4 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: 246640 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp2858923ilg; Tue, 21 Jul 2020 05:11:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzDar6utgMNTxJDjVh2ldedBXf/xELZnb3Q0MVnk0fNE0n4ZhnKccxmKoO+O0VjdpC5FgwN X-Received: by 2002:a17:906:e51:: with SMTP id q17mr26456252eji.218.1595333472966; Tue, 21 Jul 2020 05:11:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595333472; cv=none; d=google.com; s=arc-20160816; b=VJrDIT2iJYZyyPLX4LrpwvQ9Iool1BiodbQdLYgZ/j8ibBrJYYsseRY0nUQeLrGleW 4MkXZ63Y69NNQPWUkmKcr9u7cOQu/QUQaZcmb31g1QHkb0xApi36gMe0nqw2cVmNzvcD 91RBFwIEhqlFfq2wYcbU2GDVat/UCQzGhquQbYCidk+Gtx0oS5qT5FOOrSoc1mtf2HId 5l/fAb4d8Bq8BHOrrkWB5MLXbxZqOXmrrUemrRrAuVZJFAvGhoSQ9+SH749RKogUm2Sb GQQY9GoncLi7duB4j9oSNwANOFIaMDFBC12ezaj4y4mOkDAM6L+HNYIp8KDZzWC9d0qa HeBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=2zOkNlooR1zcsl5ai3d/r17122nHEKv/dFvwHU/KZrA=; b=dOf1lMB1U8ZFe+Cu1XkXoSLf2HHBTOSH0bk50xAOan+TvSwNzk3HXZEsKC2ZwtLSaD Aeiq7FlFN+TeznDCrCPtuK4p/jliR+Fe9L50HWfypHl9wAUZm9c+4Wjze/KF2Cm8tDQp h7ua1oQBUk1Cm3w3momlTVNb6ZP+zCSuVr5Ck0lapmsLcjYk+i5kZiE82rIYsrdXBsq5 naJYjj0TrGJnf2aQuOBji/6SvvEhuErhomvFKqZxg/ugAJhzkBtoIK1mKKpA4fy6J8vq sruVXw/Np9I++PPqv5vrQl8wc55QNX0oYD3qRRaG2+oYsy889MP6duDQU4xFHlyQGWKe HUOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qCxiWVCI; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id i24si6398119eds.223.2020.07.21.05.11.12; Tue, 21 Jul 2020 05:11:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qCxiWVCI; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728711AbgGUMLM (ORCPT + 2 others); Tue, 21 Jul 2020 08:11:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727106AbgGUMLL (ORCPT ); Tue, 21 Jul 2020 08:11:11 -0400 Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA5FFC061794 for ; Tue, 21 Jul 2020 05:11:11 -0700 (PDT) Received: by mail-pg1-x541.google.com with SMTP id d4so11853596pgk.4 for ; Tue, 21 Jul 2020 05:11:11 -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=GcUtGJYVBEVMQcnEu3p5Ybxqam3bBQmFufm4vMIAZuj5XIXVrIEDQRzsGRVyO6nInH 7fvj1zxYBu7apOrBeKI7dpZfGxi0+8SfoAiKd1HJcFB0FUi0H6XFONk57WfHomT65sU0 YKoyPeoOciclH1hnBLqOS7cbSQ2Ux1Ba91O5EY0uZUkAjV7IZbOiu/rNKRBcmB31fOVS 5egb/iUcB+5faBiMygUpzFcAbY3vVFuYAzS/eSPDCypZfAY3kyvYxv4uX8dBSkTqXOKl 9Kmk1D5PbCd460NIAxa2G6PLfw8Wiv0C2ZPxVK5AZnfldf5pXr53DWXOT89n2DaNufx2 /Zjw== X-Gm-Message-State: AOAM530/otMsuKiHx8zGy6/segSJy+S2z+Zbdh2Q/bvWSuoekpXYP0cZ qyWw0mK4NzxFPvtbW0C5BAOXxWo32qM= 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 Cc: jslaby@suse.com, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sumit Garg 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> Sender: linux-serial-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.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(-) -- 2.7.4 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: 246641 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp2858994ilg; Tue, 21 Jul 2020 05:11:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx5ICQ3qDdq50i6Ty77x0Zf9Mn9Ctyf96KH1FC7YZQAjFZ6Tt0Pf9F1ooxUurcf/Wcjb+jm X-Received: by 2002:aa7:db53:: with SMTP id n19mr26070565edt.338.1595333479205; Tue, 21 Jul 2020 05:11:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595333479; cv=none; d=google.com; s=arc-20160816; b=zwI23Fp9nOyQDUVg+pTrd9nBWVz8Vg9Bl2KdADQT233klek5tDqtUxdHOfjHQXy65A iSpjZ9WLerXY3PRrfxP6Iz1j8Q191IF88YsjQIX6ffRn6/QHGD0riMIR4zhWSA6zQHNg vh+ySQXUbzBRIsUhHTHPCeB2rcr4HfdXyp0k5Qwsp/QOdZ3dXAVoZ65vbbKe75dVc7hB nSff2ATTZnc1VJ5NJF6GpMwISO4VE8kYKVErO8FrPKgyf5N6IhbeXtZ/+zKN4MLR5COs 3T/fZJFejzpKNbhEKIBATpfacVhXU/4s+xPa+0DhwbHVN7axsQhmjhYJqHQTmN/QmQ2I RgNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=N4Vrr3RPHrWaZucTwZmFhL/vg7dtTdfGT3O+wG1Ixzw=; b=bhvtFyMyfIbSzqQY7JnmoSUG8c8WGCLZiDNOm+d80ADwlidPJuwiZimIftb6E9I+Gw dC9z/mNSlO3lXzUyjctvyj/2LnwclxmLaVsj4B09biTTIb0qhsnXsJVeGZ0GoviUgtoR IJgdm0Modafv93+ETpkf6hlnfsKax9y8UdyAJw6hsEb2Cj/piAnp1sOY6lbWAvrveq5j g7dYrXHG8wolaF0nH/YPG8hilYp8BE6K3gEpZkW7Gez4Ax8ZyV1ksrBZo73DKuU+mQSk ivWSQK3MD+UgQgTnBgOOmwpWaIVdi+uONKURgZeZX7Pk2prPg7U5tWzq+ul+3hZ8BgDa RnQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uf70pNth; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dr11si10088434ejc.752.2020.07.21.05.11.18; Tue, 21 Jul 2020 05:11:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uf70pNth; spf=pass (google.com: domain of linux-serial-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-serial-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729913AbgGUMLS (ORCPT + 2 others); Tue, 21 Jul 2020 08:11:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728692AbgGUMLR (ORCPT ); Tue, 21 Jul 2020 08:11:17 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C16FFC061794 for ; Tue, 21 Jul 2020 05:11:17 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id 207so10643808pfu.3 for ; Tue, 21 Jul 2020 05:11:17 -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=MOtfAVgb6+d2ttj+snybhpi9zQkLef5/coZiLnciuWMQRljN87knFpUSPWt3/QhxHL aQMHICbNCOAOTNQp98zsOi208TssCJO7pSWvXPVPyS8jCsVNviq1wNcxc3GtOm6d0Dm+ rriRxPhF6JIVOgooKLSsDIy1fYo4CVN52OkfJbduNZ/kWnEXMutL1cejptWymxF5RyoT c+LTJBdXmAG3bZAK8Ih0i45sHWS/HEdp3Vtly12t000bmPRiyiBrLabqRJu8yxDpbsCY F9ItWD7FWfgh1wTt688DdA53ySVZOi8AtuIam1qD+HktmEdgnE968Z77NPVZj6ZxHCzR uE+A== X-Gm-Message-State: AOAM532F/ybcRo79NaXfrbb96hvNCc1nR9rnFUnFfTjVXbjrQIPcxTIP qiVGCfahkg5SP3zkQcUtEz+zsw== 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 Cc: jslaby@suse.com, linux@armlinux.org.uk, jason.wessel@windriver.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sumit Garg 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 Sender: linux-serial-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.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 -- 2.7.4 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;