From patchwork Fri Sep 21 22:16:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611107 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2614C112B for ; Fri, 21 Sep 2018 22:34:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15BF32D796 for ; Fri, 21 Sep 2018 22:34:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 09F822D79F; Fri, 21 Sep 2018 22:34:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 441802D796 for ; Fri, 21 Sep 2018 22:34:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=WU71m1qq4zXFiADCZbWHC+/x8vKfs6HoPlOVFfB2Ppg=; b=gMnuJWIi0dGQps He+Z540bPbuxiNBo3PR0e1Pz0RnYaX6O5W7HWCpmrfo/INN7Dgqhq1weXIZr+y0m0Y3KAyQed65om 8+8JDSozAyZVq+PtrVFGCwEfxdqUAVgG1M6UirEWo4oY1CSfC7hDe98+X5XMn7Mhp6UYVqQOMQB+G l97ZRI13mI0w9PT9kmHeO/9SmORFF0i3SzN8nVAbfDDMq7SY8+07Gcu3iauhxwFi2/PVb72hudQtx 9jp8fnX5EgZDzeJhH0iUmkodmIKmwJofrhKpt4BYm9yXEXo9lQetZ+YH/RliAtuFa6cZw4IZl2nBO SC0XYetdO0XQv2+rhKzQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzo-00058A-B3; Fri, 21 Sep 2018 22:33:56 +0000 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TkK-0004Rj-Ud for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:06 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7A71018A; Fri, 21 Sep 2018 15:17:46 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 660AC3F557; Fri, 21 Sep 2018 15:17:43 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 01/18] ACPI / APEI: Move the estatus queue code up, and under its own ifdef Date: Fri, 21 Sep 2018 23:16:48 +0100 Message-Id: <20180921221705.6478-2-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151757_063056_2134FDAB X-CRM114-Status: GOOD ( 21.28 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP To support asynchronous NMI-like notifications on arm64 we need to use the estatus-queue. These patches refactor it to allow multiple APEI notification types to use it. First we move the estatus-queue code higher in the file so that any notify_foo() handler can make use of it. This patch moves code around ... and makes the following trivial change: Freshen the dated comment above ghes_estatus_llist. printk() is no longer the issue, its the helpers like memory_failure_queue() that still aren't nmi safe. Signed-off-by: James Morse Reviewed-by: Punit Agrawal Reviewed-by: Borislav Petkov Tested-by: Tyler Baicar --- drivers/acpi/apei/ghes.c | 265 ++++++++++++++++++++------------------- 1 file changed, 137 insertions(+), 128 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 02c6fd9caff7..f5732e6b5be8 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -545,6 +545,16 @@ static int ghes_print_estatus(const char *pfx, return 0; } +static void __ghes_panic(struct ghes *ghes) +{ + __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus); + + /* reboot to log the error! */ + if (!panic_timeout) + panic_timeout = ghes_panic_timeout; + panic("Fatal hardware error!"); +} + /* * GHES error status reporting throttle, to report more kinds of * errors, instead of just most frequently occurred errors. @@ -672,6 +682,133 @@ static void ghes_estatus_cache_add( rcu_read_unlock(); } +#ifdef CONFIG_HAVE_ACPI_APEI_NMI +/* + * Handlers for CPER records may not be NMI safe. For example, + * memory_failure_queue() takes spinlocks and calls schedule_work_on(). + * In any NMI-like handler, memory from ghes_estatus_pool is used to save + * estatus, and added to the ghes_estatus_llist. irq_work_queue() causes + * ghes_proc_in_irq() to run in IRQ context where each estatus in + * ghes_estatus_llist is processed. Each NMI-like error source must grow + * the ghes_estatus_pool to ensure memory is available. + * + * Memory from the ghes_estatus_pool is also used with the ghes_estatus_cache + * to suppress frequent messages. + */ +static struct llist_head ghes_estatus_llist; +static struct irq_work ghes_proc_irq_work; + +static void ghes_print_queued_estatus(void) +{ + struct llist_node *llnode; + struct ghes_estatus_node *estatus_node; + struct acpi_hest_generic *generic; + struct acpi_hest_generic_status *estatus; + + llnode = llist_del_all(&ghes_estatus_llist); + /* + * Because the time order of estatus in list is reversed, + * revert it back to proper order. + */ + llnode = llist_reverse_order(llnode); + while (llnode) { + estatus_node = llist_entry(llnode, struct ghes_estatus_node, + llnode); + estatus = GHES_ESTATUS_FROM_NODE(estatus_node); + generic = estatus_node->generic; + ghes_print_estatus(NULL, generic, estatus); + llnode = llnode->next; + } +} + +/* Save estatus for further processing in IRQ context */ +static void __process_error(struct ghes *ghes) +{ +#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG + u32 len, node_len; + struct ghes_estatus_node *estatus_node; + struct acpi_hest_generic_status *estatus; + + if (ghes_estatus_cached(ghes->estatus)) + return; + + len = cper_estatus_len(ghes->estatus); + node_len = GHES_ESTATUS_NODE_LEN(len); + + estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len); + if (!estatus_node) + return; + + estatus_node->ghes = ghes; + estatus_node->generic = ghes->generic; + estatus = GHES_ESTATUS_FROM_NODE(estatus_node); + memcpy(estatus, ghes->estatus, len); + llist_add(&estatus_node->llnode, &ghes_estatus_llist); +#endif +} + +static unsigned long ghes_esource_prealloc_size( + const struct acpi_hest_generic *generic) +{ + unsigned long block_length, prealloc_records, prealloc_size; + + block_length = min_t(unsigned long, generic->error_block_length, + GHES_ESTATUS_MAX_SIZE); + prealloc_records = max_t(unsigned long, + generic->records_to_preallocate, 1); + prealloc_size = min_t(unsigned long, block_length * prealloc_records, + GHES_ESOURCE_PREALLOC_MAX_SIZE); + + return prealloc_size; +} + +static void ghes_estatus_pool_shrink(unsigned long len) +{ + ghes_estatus_pool_size_request -= PAGE_ALIGN(len); +} + +static void ghes_proc_in_irq(struct irq_work *irq_work) +{ + struct llist_node *llnode, *next; + struct ghes_estatus_node *estatus_node; + struct acpi_hest_generic *generic; + struct acpi_hest_generic_status *estatus; + u32 len, node_len; + + llnode = llist_del_all(&ghes_estatus_llist); + /* + * Because the time order of estatus in list is reversed, + * revert it back to proper order. + */ + llnode = llist_reverse_order(llnode); + while (llnode) { + next = llnode->next; + estatus_node = llist_entry(llnode, struct ghes_estatus_node, + llnode); + estatus = GHES_ESTATUS_FROM_NODE(estatus_node); + len = cper_estatus_len(estatus); + node_len = GHES_ESTATUS_NODE_LEN(len); + ghes_do_proc(estatus_node->ghes, estatus); + if (!ghes_estatus_cached(estatus)) { + generic = estatus_node->generic; + if (ghes_print_estatus(NULL, generic, estatus)) + ghes_estatus_cache_add(generic, estatus); + } + gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, + node_len); + llnode = next; + } +} + +static void ghes_nmi_init_cxt(void) +{ + init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); +} + +#else +static inline void ghes_nmi_init_cxt(void) { } +#endif /* CONFIG_HAVE_ACPI_APEI_NMI */ + static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) { int rc; @@ -687,16 +824,6 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) return apei_write(val, &gv2->read_ack_register); } -static void __ghes_panic(struct ghes *ghes) -{ - __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus); - - /* reboot to log the error! */ - if (!panic_timeout) - panic_timeout = ghes_panic_timeout; - panic("Fatal hardware error!"); -} - static int ghes_proc(struct ghes *ghes) { int rc; @@ -828,17 +955,6 @@ static inline void ghes_sea_remove(struct ghes *ghes) { } #endif /* CONFIG_ACPI_APEI_SEA */ #ifdef CONFIG_HAVE_ACPI_APEI_NMI -/* - * printk is not safe in NMI context. So in NMI handler, we allocate - * required memory from lock-less memory allocator - * (ghes_estatus_pool), save estatus into it, put them into lock-less - * list (ghes_estatus_llist), then delay printk into IRQ context via - * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record - * required pool size by all NMI error source. - */ -static struct llist_head ghes_estatus_llist; -static struct irq_work ghes_proc_irq_work; - /* * NMI may be triggered on any CPU, so ghes_in_nmi is used for * having only one concurrent reader. @@ -847,88 +963,6 @@ static atomic_t ghes_in_nmi = ATOMIC_INIT(0); static LIST_HEAD(ghes_nmi); -static void ghes_proc_in_irq(struct irq_work *irq_work) -{ - struct llist_node *llnode, *next; - struct ghes_estatus_node *estatus_node; - struct acpi_hest_generic *generic; - struct acpi_hest_generic_status *estatus; - u32 len, node_len; - - llnode = llist_del_all(&ghes_estatus_llist); - /* - * Because the time order of estatus in list is reversed, - * revert it back to proper order. - */ - llnode = llist_reverse_order(llnode); - while (llnode) { - next = llnode->next; - estatus_node = llist_entry(llnode, struct ghes_estatus_node, - llnode); - estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - len = cper_estatus_len(estatus); - node_len = GHES_ESTATUS_NODE_LEN(len); - ghes_do_proc(estatus_node->ghes, estatus); - if (!ghes_estatus_cached(estatus)) { - generic = estatus_node->generic; - if (ghes_print_estatus(NULL, generic, estatus)) - ghes_estatus_cache_add(generic, estatus); - } - gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, - node_len); - llnode = next; - } -} - -static void ghes_print_queued_estatus(void) -{ - struct llist_node *llnode; - struct ghes_estatus_node *estatus_node; - struct acpi_hest_generic *generic; - struct acpi_hest_generic_status *estatus; - - llnode = llist_del_all(&ghes_estatus_llist); - /* - * Because the time order of estatus in list is reversed, - * revert it back to proper order. - */ - llnode = llist_reverse_order(llnode); - while (llnode) { - estatus_node = llist_entry(llnode, struct ghes_estatus_node, - llnode); - estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - generic = estatus_node->generic; - ghes_print_estatus(NULL, generic, estatus); - llnode = llnode->next; - } -} - -/* Save estatus for further processing in IRQ context */ -static void __process_error(struct ghes *ghes) -{ -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - u32 len, node_len; - struct ghes_estatus_node *estatus_node; - struct acpi_hest_generic_status *estatus; - - if (ghes_estatus_cached(ghes->estatus)) - return; - - len = cper_estatus_len(ghes->estatus); - node_len = GHES_ESTATUS_NODE_LEN(len); - - estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len); - if (!estatus_node) - return; - - estatus_node->ghes = ghes; - estatus_node->generic = ghes->generic; - estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - memcpy(estatus, ghes->estatus, len); - llist_add(&estatus_node->llnode, &ghes_estatus_llist); -#endif -} - static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) { struct ghes *ghes; @@ -967,26 +1001,6 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) return ret; } -static unsigned long ghes_esource_prealloc_size( - const struct acpi_hest_generic *generic) -{ - unsigned long block_length, prealloc_records, prealloc_size; - - block_length = min_t(unsigned long, generic->error_block_length, - GHES_ESTATUS_MAX_SIZE); - prealloc_records = max_t(unsigned long, - generic->records_to_preallocate, 1); - prealloc_size = min_t(unsigned long, block_length * prealloc_records, - GHES_ESOURCE_PREALLOC_MAX_SIZE); - - return prealloc_size; -} - -static void ghes_estatus_pool_shrink(unsigned long len) -{ - ghes_estatus_pool_size_request -= PAGE_ALIGN(len); -} - static void ghes_nmi_add(struct ghes *ghes) { unsigned long len; @@ -1018,14 +1032,9 @@ static void ghes_nmi_remove(struct ghes *ghes) ghes_estatus_pool_shrink(len); } -static void ghes_nmi_init_cxt(void) -{ - init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); -} #else /* CONFIG_HAVE_ACPI_APEI_NMI */ static inline void ghes_nmi_add(struct ghes *ghes) { } static inline void ghes_nmi_remove(struct ghes *ghes) { } -static inline void ghes_nmi_init_cxt(void) { } #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ static int ghes_probe(struct platform_device *ghes_dev) From patchwork Fri Sep 21 22:16:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611109 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6950D112B for ; Fri, 21 Sep 2018 22:34:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 58FE12D796 for ; Fri, 21 Sep 2018 22:34:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D69F2D79F; Fri, 21 Sep 2018 22:34:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8F39C2D796 for ; Fri, 21 Sep 2018 22:34:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=nKICIbDM4PnhrXCCyDsQ+DzhSbMxhl5aljy7EgZypHU=; b=smKp1p2uih+awb Z+HUv/cm0zOYxyRXlFKClLkoTHyI5cpuCjn6NCbhMioWRp8GquscrrFmSi+HUlv/WEIs7vkwCtZrL vpJtlGPmUtpTCHFmf/Qc+VRw5znux1zacpqTIRKWh6RtFsRTw7L2KgCipeAlQbLChJP6UqXBUhfj2 uQ6bOdZwW7BR2js9pLUI3sBpkRwlIIKGUoAVVbT1KH0pEE/0LRRHX/vfwfzHDv7ZnfpRUlNLfSd/Y pET2skmf9G7MLlTHkgqIa5l4A2B2mNrupG52zUfGvfFjGITsD0FLQ+ZffJSL9pb5m+o6j0DVT+aG2 wi+w3pVU3fmYWtjmxJ2Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U0C-0005NQ-KM; Fri, 21 Sep 2018 22:34:20 +0000 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TkL-0004UZ-05 for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:11 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D31AE15AD; Fri, 21 Sep 2018 15:17:51 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BC9763F557; Fri, 21 Sep 2018 15:17:48 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 02/18] ACPI / APEI: Generalise the estatus queue's add/remove and notify code Date: Fri, 21 Sep 2018 23:16:49 +0100 Message-Id: <20180921221705.6478-3-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151757_118471_E4C3B834 X-CRM114-Status: GOOD ( 17.51 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Refactor the estatus queue's pool grow/shrink code and notification routine from NOTIFY_NMI's handlers. This will allow another notification method to use the estatus queue without duplicating this code. This patch adds rcu_read_lock()/rcu_read_unlock() around the list list_for_each_entry_rcu() walker. These aren't strictly necessary as the whole nmi_enter/nmi_exit() window is a spooky RCU read-side critical section. The existing ghes_estatus_pool_shrink() is folded into the new ghes_estatus_queue_shrink_pool() as only the queue uses it. _in_nmi_notify_one() is separate from the rcu-list walker for a later caller that doesn't need to walk a list. Signed-off-by: James Morse Reviewed-by: Punit Agrawal Tested-by: Tyler Baicar --- Changes since v3: * Removed dupicate or redundant paragraphs in commit message. * Fixed the style of a zero check Changes since v1: * Tidied up _in_nmi_notify_one(). --- drivers/acpi/apei/ghes.c | 100 +++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 35 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index f5732e6b5be8..29d863ff2f87 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -747,6 +747,51 @@ static void __process_error(struct ghes *ghes) #endif } +static int _in_nmi_notify_one(struct ghes *ghes) +{ + int sev; + + if (ghes_read_estatus(ghes, 1)) { + ghes_clear_estatus(ghes); + return -ENOENT; + } + + sev = ghes_severity(ghes->estatus->error_severity); + if (sev >= GHES_SEV_PANIC) { +#ifdef CONFIG_X86 + oops_begin(); +#endif + ghes_print_queued_estatus(); + __ghes_panic(ghes); + } + + if (!(ghes->flags & GHES_TO_CLEAR)) + return 0; + + __process_error(ghes); + ghes_clear_estatus(ghes); + + return 0; +} + +static int ghes_estatus_queue_notified(struct list_head *rcu_list) +{ + int ret = -ENOENT; + struct ghes *ghes; + + rcu_read_lock(); + list_for_each_entry_rcu(ghes, rcu_list, list) { + if (!_in_nmi_notify_one(ghes)) + ret = 0; + } + rcu_read_unlock(); + + if (IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && !ret) + irq_work_queue(&ghes_proc_irq_work); + + return ret; +} + static unsigned long ghes_esource_prealloc_size( const struct acpi_hest_generic *generic) { @@ -762,11 +807,24 @@ static unsigned long ghes_esource_prealloc_size( return prealloc_size; } -static void ghes_estatus_pool_shrink(unsigned long len) +/* After removing a queue user, we can shrink the pool */ +static void ghes_estatus_queue_shrink_pool(struct ghes *ghes) { + unsigned long len; + + len = ghes_esource_prealloc_size(ghes->generic); ghes_estatus_pool_size_request -= PAGE_ALIGN(len); } +/* Before adding a queue user, grow the pool */ +static void ghes_estatus_queue_grow_pool(struct ghes *ghes) +{ + unsigned long len; + + len = ghes_esource_prealloc_size(ghes->generic); + ghes_estatus_pool_expand(len); +} + static void ghes_proc_in_irq(struct irq_work *irq_work) { struct llist_node *llnode, *next; @@ -965,48 +1023,22 @@ static LIST_HEAD(ghes_nmi); static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) { - struct ghes *ghes; - int sev, ret = NMI_DONE; + int ret = NMI_DONE; if (!atomic_add_unless(&ghes_in_nmi, 1, 1)) return ret; - list_for_each_entry_rcu(ghes, &ghes_nmi, list) { - if (ghes_read_estatus(ghes, 1)) { - ghes_clear_estatus(ghes); - continue; - } else { - ret = NMI_HANDLED; - } - - sev = ghes_severity(ghes->estatus->error_severity); - if (sev >= GHES_SEV_PANIC) { - oops_begin(); - ghes_print_queued_estatus(); - __ghes_panic(ghes); - } + if (!ghes_estatus_queue_notified(&ghes_nmi)) + ret = NMI_HANDLED; - if (!(ghes->flags & GHES_TO_CLEAR)) - continue; - - __process_error(ghes); - ghes_clear_estatus(ghes); - } - -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - if (ret == NMI_HANDLED) - irq_work_queue(&ghes_proc_irq_work); -#endif atomic_dec(&ghes_in_nmi); return ret; } static void ghes_nmi_add(struct ghes *ghes) { - unsigned long len; + ghes_estatus_queue_grow_pool(ghes); - len = ghes_esource_prealloc_size(ghes->generic); - ghes_estatus_pool_expand(len); mutex_lock(&ghes_list_mutex); if (list_empty(&ghes_nmi)) register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes"); @@ -1016,8 +1048,6 @@ static void ghes_nmi_add(struct ghes *ghes) static void ghes_nmi_remove(struct ghes *ghes) { - unsigned long len; - mutex_lock(&ghes_list_mutex); list_del_rcu(&ghes->list); if (list_empty(&ghes_nmi)) @@ -1028,8 +1058,8 @@ static void ghes_nmi_remove(struct ghes *ghes) * freed after NMI handler finishes. */ synchronize_rcu(); - len = ghes_esource_prealloc_size(ghes->generic); - ghes_estatus_pool_shrink(len); + + ghes_estatus_queue_shrink_pool(ghes); } #else /* CONFIG_HAVE_ACPI_APEI_NMI */ From patchwork Fri Sep 21 22:16:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611105 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 974AC112B for ; Fri, 21 Sep 2018 22:33:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 846342D796 for ; Fri, 21 Sep 2018 22:33:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 785E82D79F; Fri, 21 Sep 2018 22:33:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DE3572D796 for ; Fri, 21 Sep 2018 22:33:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=FsjOUl8ImNUpeR2j4ErYY6q1dRc5qO32c6Utr/Ba+fU=; b=nOgt1LtBS0B+ol IAcN8+68iXkjAMweDBMQzSurfgDGjW0BytFPYkXm0oO52Ye4c/yK4xU5CmGUYamKsMAt8Hec+Y6Am tPykP+OwzbEmy2PyyCTlQbLBkoBMAiXK9kvtjUx0ByxztOxcQTVPo2yO3Ol1NeBaCalnPX3+Uew7N C/uuDgk4FgmUELOD+4gfskBet1AvMml1cCtHgxWRVV8xeFtBjXoTM1kOoOXofCiuYwEB+itGnsz/p 9vlrnUeLFiVH/tCEPpgOjWXYL1D3+kVXZgdlZg1fZB5+utueFCie/bLKgVB1qb1LHuJto2yrY/KYA izXgBcsRTRRN0+gYoxTw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TzR-000502-JJ; Fri, 21 Sep 2018 22:33:33 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TkK-0004X1-Uf for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:05 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 525E31596; Fri, 21 Sep 2018 15:17:56 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3DFC83F557; Fri, 21 Sep 2018 15:17:53 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 03/18] ACPI / APEI: don't wait to serialise with oops messages when panic()ing Date: Fri, 21 Sep 2018 23:16:50 +0100 Message-Id: <20180921221705.6478-4-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151757_020908_86F3ECB6 X-CRM114-Status: GOOD ( 10.96 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP oops_begin() exists to group printk() messages with the oops message printed by die(). To reach this caller we know that platform firmware took this error first, then notified the OS via NMI with a 'panic' severity. Don't wait for another CPU to release the die-lock before we can panic(), our only goal is to print this fatal error and panic(). This code is always called in_nmi(), and since 42a0bb3f7138 ("printk/nmi: generic solution for safe printk in NMI"), it has been safe to call printk() from this context. Messages are batched in a per-cpu buffer and printed via irq-work, or a call back from panic(). Link: https://patchwork.kernel.org/patch/10313555/ Acked-by: Borislav Petkov Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 29d863ff2f87..d7c46236b353 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -758,9 +757,6 @@ static int _in_nmi_notify_one(struct ghes *ghes) sev = ghes_severity(ghes->estatus->error_severity); if (sev >= GHES_SEV_PANIC) { -#ifdef CONFIG_X86 - oops_begin(); -#endif ghes_print_queued_estatus(); __ghes_panic(ghes); } From patchwork Fri Sep 21 22:16:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611079 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B1D4114BD for ; Fri, 21 Sep 2018 22:19:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A23182DDC8 for ; Fri, 21 Sep 2018 22:19:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 945D82DDD4; Fri, 21 Sep 2018 22:19:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E82532DDC8 for ; Fri, 21 Sep 2018 22:19:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=in9Xo7Qu3Tylt1TSd2fiT1m0jrAS7hkjW2N5Opgp1jc=; b=B/NWIxRAWTBts8 1d8M0G+dZUi1uxTjwsn9eQEVOvD5/Yh1jm4Gwp4o5CHGzWQf81JzyAM7nkfPnf+BGXV8RuDJcMOT5 63kTcU/KXG4sXKkwiSCNdMfXWKp1mSML6f14rOyft30AC4RZwIhK8PMCqi8zpxGcb4AKtqqqGDj2v 5M4NDW8IZRBJqGP2aA3mQanL1hvPA01aAG4cdQhlFV0C9HApmDV+doCWltEBb698e74qNVX0cmWN9 mbbwKAjNQ2IIzRdcbpbSx+EW53GNU5pK2H/EIyeNc3qPAS1sq9J9VncmyYo+F1EPy7nNbpb39xsu6 jtGAyPyxEIypXk+FUZag==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tlu-0005Gr-WB; Fri, 21 Sep 2018 22:19:35 +0000 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TkY-0004Zb-Rz for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:52 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5528C15BE; Fri, 21 Sep 2018 15:18:00 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 404DE3F557; Fri, 21 Sep 2018 15:17:57 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 04/18] ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue Date: Fri, 21 Sep 2018 23:16:51 +0100 Message-Id: <20180921221705.6478-5-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151810_933887_9C52BBE5 X-CRM114-Status: GOOD ( 15.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Now that the estatus queue can be used by more than one notification method, we can move notifications that have NMI-like behaviour over to it, and start abstracting GHES's single in_nmi() path. Switch NOTIFY_SEA over to use the estatus queue. This makes it behave in the same way as x86's NOTIFY_NMI. Signed-off-by: James Morse Reviewed-by: Punit Agrawal Tested-by: Tyler Baicar --- drivers/acpi/apei/ghes.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index d7c46236b353..150fb184c7cb 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -58,6 +58,10 @@ #define GHES_PFX "GHES: " +#if defined(CONFIG_HAVE_ACPI_APEI_NMI) || defined(CONFIG_ACPI_APEI_SEA) +#define WANT_NMI_ESTATUS_QUEUE 1 +#endif + #define GHES_ESTATUS_MAX_SIZE 65536 #define GHES_ESOURCE_PREALLOC_MAX_SIZE 65536 @@ -681,7 +685,7 @@ static void ghes_estatus_cache_add( rcu_read_unlock(); } -#ifdef CONFIG_HAVE_ACPI_APEI_NMI +#ifdef WANT_NMI_ESTATUS_QUEUE /* * Handlers for CPER records may not be NMI safe. For example, * memory_failure_queue() takes spinlocks and calls schedule_work_on(). @@ -861,7 +865,7 @@ static void ghes_nmi_init_cxt(void) #else static inline void ghes_nmi_init_cxt(void) { } -#endif /* CONFIG_HAVE_ACPI_APEI_NMI */ +#endif /* WANT_NMI_ESTATUS_QUEUE */ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) { @@ -977,20 +981,13 @@ static LIST_HEAD(ghes_sea); */ int ghes_notify_sea(void) { - struct ghes *ghes; - int ret = -ENOENT; - - rcu_read_lock(); - list_for_each_entry_rcu(ghes, &ghes_sea, list) { - if (!ghes_proc(ghes)) - ret = 0; - } - rcu_read_unlock(); - return ret; + return ghes_estatus_queue_notified(&ghes_sea); } static void ghes_sea_add(struct ghes *ghes) { + ghes_estatus_queue_grow_pool(ghes); + mutex_lock(&ghes_list_mutex); list_add_rcu(&ghes->list, &ghes_sea); mutex_unlock(&ghes_list_mutex); @@ -1002,6 +999,8 @@ static void ghes_sea_remove(struct ghes *ghes) list_del_rcu(&ghes->list); mutex_unlock(&ghes_list_mutex); synchronize_rcu(); + + ghes_estatus_queue_shrink_pool(ghes); } #else /* CONFIG_ACPI_APEI_SEA */ static inline void ghes_sea_add(struct ghes *ghes) { } From patchwork Fri Sep 21 22:16:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611141 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 74CB5112B for ; Fri, 21 Sep 2018 22:38:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 641B02CC44 for ; Fri, 21 Sep 2018 22:38:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 576F02CFA1; Fri, 21 Sep 2018 22:38:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D151E2CC44 for ; Fri, 21 Sep 2018 22:38:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=LvlIPsTIbiARZrsp0XFQ1uqJHJMGfCyNmPBM/aZKqVg=; b=WjErCPxDDtgiMz 0tGbX6khvi8/6a2C/DOaJH9zw7J57RIr8JY3cOz7lTItO5IBhGzIWfpJ0JUlcnrdJ8Shgb5SuNvOm SiL0yuUV6ddjEegUFG1E0wOuGXy2AFxuwisS5tz2+pN7Cqkur3gmYiVGDpdwbUq+o7b3wbSUHEJT0 O+vKiQDbzsXoHIn4yTTZsbYgMxJMTaOeWi3G/fFx/45UkDahjq0pbAQF9sRbeAnZJlDmOxPx7W8Id d/vfHdYpr2QWGRuLuRAGoU9cl6vja5MGGMNZuVY9BUs2xzcT7VDzrRjeTVMZKWNhg8Xfh+fKa1145 RdFbTDfI0L22L3BJyX/w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U3s-0007xl-LZ; Fri, 21 Sep 2018 22:38:08 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzz-0004vp-PT for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:34:07 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Cy2z5ioh7lrkiGogBYRabgSup7PludHtyjIyxhDrobI=; b=je5+UIk/RKXyC2W4DDDC6urC0r 84NyL12/TOPVeyvF9ni5Uds6BD/+POJoeXxIM45mkSvPQFnqbLhp5o8dViVu1JigpM2sIcwei1yOd NzqmQhynj2+4ZFzMksSLtlnmZjhd6XfcwEqSJkaUWo+zFUGYD8h4MMHrzTetc+0ePgErcpB617Gr9 aoG7TesAWFpb2Ndy3Lax0drDQPj4E+1vIu8QCdKvreV6ntVE0GwUGm2WL8xfuxdhB3M/khFzvigTj H2iVfMexDtOXW6qtvlD/u3PLCBpcaNCpJCz7DKOahou1z+JqmEl/IjjfXx1ACU8WBaMeNSjexakl3 r2LRIa7A==; Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tke-0003rg-Rp for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:18 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DD2FF15BF; Fri, 21 Sep 2018 15:18:04 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C80763F557; Fri, 21 Sep 2018 15:18:01 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 05/18] ACPI / APEI: Make estatus queue a Kconfig symbol Date: Fri, 21 Sep 2018 23:16:52 +0100 Message-Id: <20180921221705.6478-6-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231817_259603_79757080 X-CRM114-Status: GOOD ( 12.59 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Now that there are two users of the estatus queue, and likely to be more, make it a Kconfig symbol selected by the appropriate notification. We can move the ARCH_HAVE_NMI_SAFE_CMPXCHG checks in here too. Signed-off-by: James Morse --- drivers/acpi/apei/Kconfig | 6 ++++++ drivers/acpi/apei/ghes.c | 12 +++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 52ae5438edeb..2b191e09b647 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -4,6 +4,7 @@ config HAVE_ACPI_APEI config HAVE_ACPI_APEI_NMI bool + select ACPI_APEI_GHES_ESTATUS_QUEUE config ACPI_APEI bool "ACPI Platform Error Interface (APEI)" @@ -33,6 +34,10 @@ config ACPI_APEI_GHES by firmware to produce more valuable hardware error information for Linux. +config ACPI_APEI_GHES_ESTATUS_QUEUE + bool + depends on ACPI_APEI_GHES && ARCH_HAVE_NMI_SAFE_CMPXCHG + config ACPI_APEI_PCIEAER bool "APEI PCIe AER logging/recovering support" depends on ACPI_APEI && PCIEAER @@ -43,6 +48,7 @@ config ACPI_APEI_PCIEAER config ACPI_APEI_SEA bool "APEI Synchronous External Abort logging/recovering support" depends on ARM64 && ACPI_APEI_GHES + select ACPI_APEI_GHES_ESTATUS_QUEUE default y help This option should be enabled if the system supports diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 150fb184c7cb..2880547e13b8 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -58,10 +58,6 @@ #define GHES_PFX "GHES: " -#if defined(CONFIG_HAVE_ACPI_APEI_NMI) || defined(CONFIG_ACPI_APEI_SEA) -#define WANT_NMI_ESTATUS_QUEUE 1 -#endif - #define GHES_ESTATUS_MAX_SIZE 65536 #define GHES_ESOURCE_PREALLOC_MAX_SIZE 65536 @@ -685,7 +681,7 @@ static void ghes_estatus_cache_add( rcu_read_unlock(); } -#ifdef WANT_NMI_ESTATUS_QUEUE +#ifdef CONFIG_ACPI_APEI_GHES_ESTATUS_QUEUE /* * Handlers for CPER records may not be NMI safe. For example, * memory_failure_queue() takes spinlocks and calls schedule_work_on(). @@ -727,7 +723,6 @@ static void ghes_print_queued_estatus(void) /* Save estatus for further processing in IRQ context */ static void __process_error(struct ghes *ghes) { -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG u32 len, node_len; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic_status *estatus; @@ -747,7 +742,6 @@ static void __process_error(struct ghes *ghes) estatus = GHES_ESTATUS_FROM_NODE(estatus_node); memcpy(estatus, ghes->estatus, len); llist_add(&estatus_node->llnode, &ghes_estatus_llist); -#endif } static int _in_nmi_notify_one(struct ghes *ghes) @@ -786,7 +780,7 @@ static int ghes_estatus_queue_notified(struct list_head *rcu_list) } rcu_read_unlock(); - if (IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && !ret) + if (!ret) irq_work_queue(&ghes_proc_irq_work); return ret; @@ -865,7 +859,7 @@ static void ghes_nmi_init_cxt(void) #else static inline void ghes_nmi_init_cxt(void) { } -#endif /* WANT_NMI_ESTATUS_QUEUE */ +#endif /* CONFIG_ACPI_APEI_GHES_ESTATUS_QUEUE */ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) { From patchwork Fri Sep 21 22:16:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611081 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7352314BD for ; Fri, 21 Sep 2018 22:20:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61D652DDD4 for ; Fri, 21 Sep 2018 22:20:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 554812E0C6; Fri, 21 Sep 2018 22:20:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9FA522DDD4 for ; Fri, 21 Sep 2018 22:20:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=rTLmidvb4QxHW8oxNHRX4lelCzeg+sCUmmNAj8GwIxo=; b=WeDMyfPDOdbifn 0frHg1rIqAMEYJdMkpLqnm+hDSdwlNCptgO4WIjgxaa898iF3c/5Tf00lYw5LPke8v0TLpM6DGsXj kUphl4yyV8HT+hkS8CBiGM0gO/yw0oNqBRfXpuO7Egn96zwhWx5dGEp2o4CToxckExPxEmyZ7sF05 ZipBSBYBMlTi3mrcQhGp/lZIMnk+elcHI/fkZi7P1YNdwfRRghuN+2a9JqCWvItgHJzWIJy4uJVhE KD06FuPV9WoQ6wePQ/T4CUxy2gWXgKnsitV6hEw0HnrIGQO0NvxokWvleXNmCaJTZ646mqlfBPe52 ds4W6NBAofF1qqPzzjeA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tmi-00061j-2t; Fri, 21 Sep 2018 22:20:24 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TkY-0004fG-S0 for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:19:00 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 662C718A; Fri, 21 Sep 2018 15:18:09 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5173B3F557; Fri, 21 Sep 2018 15:18:06 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 06/18] KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing Date: Fri, 21 Sep 2018 23:16:53 +0100 Message-Id: <20180921221705.6478-7-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151810_947785_3D0B78F9 X-CRM114-Status: GOOD ( 19.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP To split up APEIs in_nmi() path, we need any nmi-like callers to always be in_nmi(). KVM shouldn't have to know about this, pull the RAS plumbing out into a header file. Currently guest synchronous external aborts are claimed as RAS notifications by handle_guest_sea(), which is hidden in the arch codes mm/fault.c. 32bit gets a dummy declaration in system_misc.h. There is going to be more of this in the future if/when we support the SError-based firmware-first notification mechanism and/or kernel-first notifications for both synchronous external abort and SError. Each of these will come with some Kconfig symbols and a handful of header files. Create a header file for all this. This patch gives handle_guest_sea() a 'kvm_' prefix, and moves the declarations to kvm_ras.h as preparation for a future patch that moves the ACPI-specific RAS code out of mm/fault.c. Signed-off-by: James Morse Reviewed-by: Punit Agrawal Acked-by: Marc Zyngier Tested-by: Tyler Baicar --- arch/arm/include/asm/kvm_ras.h | 14 ++++++++++++++ arch/arm/include/asm/system_misc.h | 5 ----- arch/arm64/include/asm/kvm_ras.h | 11 +++++++++++ arch/arm64/include/asm/system_misc.h | 2 -- arch/arm64/mm/fault.c | 2 +- virt/kvm/arm/mmu.c | 4 ++-- 6 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 arch/arm/include/asm/kvm_ras.h create mode 100644 arch/arm64/include/asm/kvm_ras.h diff --git a/arch/arm/include/asm/kvm_ras.h b/arch/arm/include/asm/kvm_ras.h new file mode 100644 index 000000000000..aaff56bf338f --- /dev/null +++ b/arch/arm/include/asm/kvm_ras.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 - Arm Ltd + +#ifndef __ARM_KVM_RAS_H__ +#define __ARM_KVM_RAS_H__ + +#include + +static inline int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr) +{ + return -1; +} + +#endif /* __ARM_KVM_RAS_H__ */ diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h index 8e76db83c498..66f6a3ae68d2 100644 --- a/arch/arm/include/asm/system_misc.h +++ b/arch/arm/include/asm/system_misc.h @@ -38,11 +38,6 @@ static inline void harden_branch_predictor(void) extern unsigned int user_debug; -static inline int handle_guest_sea(phys_addr_t addr, unsigned int esr) -{ - return -1; -} - #endif /* !__ASSEMBLY__ */ #endif /* __ASM_ARM_SYSTEM_MISC_H */ diff --git a/arch/arm64/include/asm/kvm_ras.h b/arch/arm64/include/asm/kvm_ras.h new file mode 100644 index 000000000000..5f72b07b7912 --- /dev/null +++ b/arch/arm64/include/asm/kvm_ras.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 - Arm Ltd + +#ifndef __ARM64_KVM_RAS_H__ +#define __ARM64_KVM_RAS_H__ + +#include + +int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr); + +#endif /* __ARM64_KVM_RAS_H__ */ diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h index 28893a0b141d..48ded3628a89 100644 --- a/arch/arm64/include/asm/system_misc.h +++ b/arch/arm64/include/asm/system_misc.h @@ -45,8 +45,6 @@ extern void __show_regs(struct pt_regs *); extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); -int handle_guest_sea(phys_addr_t addr, unsigned int esr); - #endif /* __ASSEMBLY__ */ #endif /* __ASM_SYSTEM_MISC_H */ diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 50b30ff30de4..1a30d7a8c9bf 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -725,7 +725,7 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 63" }, }; -int handle_guest_sea(phys_addr_t addr, unsigned int esr) +int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr) { return ghes_notify_sea(); } diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index ed162a6c57c5..100c8f2d67ac 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -27,10 +27,10 @@ #include #include #include +#include #include #include #include -#include #include "trace.h" @@ -1699,7 +1699,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) * For RAS the host kernel may handle this abort. * There is no need to pass the error into the guest. */ - if (!handle_guest_sea(fault_ipa, kvm_vcpu_get_hsr(vcpu))) + if (!kvm_handle_guest_sea(fault_ipa, kvm_vcpu_get_hsr(vcpu))) return 1; if (unlikely(!is_iabt)) { From patchwork Fri Sep 21 22:16:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611083 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84A9C5A4 for ; Fri, 21 Sep 2018 22:21:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 740892DDD4 for ; Fri, 21 Sep 2018 22:21:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 67E9E2E1EC; Fri, 21 Sep 2018 22:21:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B5F302DDD4 for ; Fri, 21 Sep 2018 22:21:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=pKx4j/Q0qqo5Znn3wGi0vPZz+TbC8PNqf1RzJ0IalQU=; b=QpoRmMiJlOMf3R MSLL1VWrrds6ckdQeZs7ui1sG64LLtbV5kwvM62y5dqa0nHj7y+X5G/xPv/O6I5Y2vPjAK1cDudbt RiFs7ptbx/0qNkVHaskKQws2Ba6Fb8yyvMYiC/X2nnNtt35iXdw2l9tRiIroPEeKbd6ctnJVw9r+8 cqq4ZJ0h86UoA++8L29A42NhkIx9DPkOeb3f3emeAzFrxbv5TCxuh3WOY6/9hfuZgyt8Ofpox/ivX zTZ1qyh895ZIbKfDiZy5772nWLriajw7kLZpJh3LjvreXj9kBvMkzZdnp9g9havSTJBApRgvyl0ZS CcGs+C8rLBuA08pkQK3Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TnP-00076K-Or; Fri, 21 Sep 2018 22:21:07 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tkm-0004iH-B0 for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:20:19 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0012A15AD; Fri, 21 Sep 2018 15:18:13 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DEE6E3F557; Fri, 21 Sep 2018 15:18:10 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 07/18] arm64: KVM/mm: Move SEA handling behind a single 'claim' interface Date: Fri, 21 Sep 2018 23:16:54 +0100 Message-Id: <20180921221705.6478-8-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151824_439540_D4A496C8 X-CRM114-Status: GOOD ( 21.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP To split up APEIs in_nmi() path, we need the nmi-like callers to always be in_nmi(). Add a helper to do the work and claim the notification. When KVM or the arch code takes an exception that might be a RAS notification, it asks the APEI firmware-first code whether it wants to claim the exception. We can then go on to see if (a future) kernel-first mechanism wants to claim the notification, before falling through to the existing default behaviour. The NOTIFY_SEA code was merged before we had multiple, possibly interacting, NMI-like notifications and the need to consider kernel first in the future. Make the 'claiming' behaviour explicit. As we're restructuring the APEI code to allow multiple NMI-like notifications, any notification that might interrupt interrupts-masked code must always be wrapped in nmi_enter()/nmi_exit(). This allows APEI to use in_nmi() to use the right fixmap entries. We mask SError over this window to prevent an asynchronous RAS error arriving and tripping 'nmi_enter()'s BUG_ON(in_nmi()). Signed-off-by: James Morse Acked-by: Marc Zyngier Tested-by: Tyler Baicar --- Why does apei_claim_sea() take a pt_regs? This gets used later to take APEI by the hand through NMI->IRQ context, depending on what we interrupted. Changes since v4: * Made irqs-unmasked comment a lockdep assert. Changes since v3: * Removed spurious whitespace change * Updated comment in acpi.c to cover SError masking Changes since v2: * Added dummy definition for !ACPI and culled IS_ENABLED() checks. squash: make 'call with irqs unmaksed' a lockdep assert, much better --- arch/arm64/include/asm/acpi.h | 4 ++++ arch/arm64/include/asm/daifflags.h | 1 + arch/arm64/include/asm/kvm_ras.h | 16 +++++++++++++++- arch/arm64/kernel/acpi.c | 29 +++++++++++++++++++++++++++++ arch/arm64/mm/fault.c | 24 +++++------------------- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index 709208dfdc8b..f722d2d6bf2b 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -139,6 +140,9 @@ static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) { return __acpi_get_mem_attribute(addr); } +int apei_claim_sea(struct pt_regs *regs); +#else +static inline int apei_claim_sea(struct pt_regs *regs) { return -ENOENT; } #endif /* CONFIG_ACPI_APEI */ #ifdef CONFIG_ACPI_NUMA diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h index 22e4c83de5a5..cbd753855bf3 100644 --- a/arch/arm64/include/asm/daifflags.h +++ b/arch/arm64/include/asm/daifflags.h @@ -20,6 +20,7 @@ #define DAIF_PROCCTX 0 #define DAIF_PROCCTX_NOIRQ PSR_I_BIT +#define DAIF_ERRCTX (PSR_I_BIT | PSR_A_BIT) /* mask/save/unmask/restore all exceptions, including interrupts. */ static inline void local_daif_mask(void) diff --git a/arch/arm64/include/asm/kvm_ras.h b/arch/arm64/include/asm/kvm_ras.h index 5f72b07b7912..5b56e7e297b1 100644 --- a/arch/arm64/include/asm/kvm_ras.h +++ b/arch/arm64/include/asm/kvm_ras.h @@ -4,8 +4,22 @@ #ifndef __ARM64_KVM_RAS_H__ #define __ARM64_KVM_RAS_H__ +#include +#include #include -int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr); +#include + +/* + * Was this synchronous external abort a RAS notification? + * Returns '0' for errors handled by some RAS subsystem, or -ENOENT. + */ +static inline int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr) +{ + /* apei_claim_sea(NULL) expects to mask interrupts itself */ + lockdep_assert_irqs_enabled(); + + return apei_claim_sea(NULL); +} #endif /* __ARM64_KVM_RAS_H__ */ diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index ed46dc188b22..a9b8bba014b5 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -28,8 +28,10 @@ #include #include +#include #include #include +#include #include #include @@ -257,3 +259,30 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr) return __pgprot(PROT_NORMAL_NC); return __pgprot(PROT_DEVICE_nGnRnE); } + +/* + * Claim Synchronous External Aborts as a firmware first notification. + * + * Used by KVM and the arch do_sea handler. + * @regs may be NULL when called from process context. + */ +int apei_claim_sea(struct pt_regs *regs) +{ + int err = -ENOENT; + unsigned long current_flags = arch_local_save_flags(); + + if (!IS_ENABLED(CONFIG_ACPI_APEI_SEA)) + return err; + + /* + * SEA can interrupt SError, mask it and describe this as an NMI so + * that APEI defers the handling. + */ + local_daif_restore(DAIF_ERRCTX); + nmi_enter(); + err = ghes_notify_sea(); + nmi_exit(); + local_daif_restore(current_flags); + + return err; +} diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 1a30d7a8c9bf..2c38776bb71f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -18,6 +18,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -33,6 +34,7 @@ #include #include +#include #include #include #include @@ -45,8 +47,6 @@ #include #include -#include - struct fault_info { int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); @@ -631,19 +631,10 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) inf = esr_to_fault_info(esr); /* - * Synchronous aborts may interrupt code which had interrupts masked. - * Before calling out into the wider kernel tell the interested - * subsystems. + * Return value ignored as we rely on signal merging. + * Future patches will make this more robust. */ - if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) { - if (interrupts_enabled(regs)) - nmi_enter(); - - ghes_notify_sea(); - - if (interrupts_enabled(regs)) - nmi_exit(); - } + apei_claim_sea(regs); clear_siginfo(&info); info.si_signo = inf->sig; @@ -725,11 +716,6 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 63" }, }; -int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr) -{ - return ghes_notify_sea(); -} - asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { From patchwork Fri Sep 21 22:16:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611139 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FD1A14DA for ; Fri, 21 Sep 2018 22:37:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F6092D7AD for ; Fri, 21 Sep 2018 22:37:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 420E22D7C9; Fri, 21 Sep 2018 22:37:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 992E82D7AD for ; Fri, 21 Sep 2018 22:37:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=NsPBZETbT9Tc0/xFl/SCUlSdpZ/3155boq1nY0PtWrk=; b=oRlMXdWT5xfOdg KByfVx39RzxY0emu8rb05QIEzc+LLZNvBNaNz0XnImvw4AZ1uMzfdsSosJ5DZdeXpfA1krANzGSnY a/+xPPs+5cvtlIocYyB0109INXbUbuKHADbEFKPAITwrECGKGpuT/D3DQCIKZ48t74QWd/VcPDCUm rhcOHBJeYPIuh6IJ8aHvIa9yPRUuJuay/jmH6c6asJoPZrV8gzzT77t008xfSEaxG9PxhbGnChZw7 Q5aW5GW3gjBqI4KmD52AgiLNtsKQm+rEGxkSb8FEJ/QSmeLmR3XOODQjbp4FatFbmZyQLohRgRY7M EUZSur02vfqC/hNpaI9g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U35-0007hW-01; Fri, 21 Sep 2018 22:37:19 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzx-0004vp-9I for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:34:05 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=x3Q4K7d1ZHm69LZFDvUW0P+oTOW3REEurmS8OsSR3lU=; b=eGxWGbdtH1/+37p5R2dN9IAh+/ 3vNhaxxmyCtTatGrLo3F0yE3zoZ48wY0h88RDM2iTR0GrPepEBbbryEyi0gTQqAwCTIdjfNM4DkSQ Ma0X0F8F9igp1lzyfQHeZTD1BFiVmT2QNi48WUWYdxJJfPv5TQDJO1VPy/13VknoIrQta9kQE7LOr m8IlGbo/IqLHEDbP3HpqPv3VZ8hTaQZdpjcjO/KrDB44HxZn2Ar7XYDOkZhPTU4WgPc8E6/n9N95c GUsJDxHznOVAaN61NmwNq2k6xV25vOAMR26ihj2ANsn63OQ/eR1/waw6RxV1nGIDYUL9zFGaiMsRV V1G+UgXw==; Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tkr-0003tS-1C for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:30 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3FDAF1596; Fri, 21 Sep 2018 15:18:18 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2AF6B3F557; Fri, 21 Sep 2018 15:18:15 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 08/18] ACPI / APEI: Move locking to the notification helper Date: Fri, 21 Sep 2018 23:16:55 +0100 Message-Id: <20180921221705.6478-9-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231829_349632_1005EBDF X-CRM114-Status: GOOD ( 20.92 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP ghes_copy_tofrom_phys() takes different locks depending on in_nmi(). This doesn't work when we have multiple NMI-like notifications, that can interrupt each other. Now that NOTIFY_SEA is always called as an NMI, move the lock-taking to the notification helper. The helper will always know which lock to take. This avoids ghes_copy_tofrom_phys() taking a guess based on in_nmi(). This splits NOTIFY_NMI and NOTIFY_SEA to use different locks. All the other notifications use ghes_proc(), and are called in process or IRQ context. Move the spin_lock_irqsave() around their ghes_proc() calls. Signed-off-by: James Morse Reviewed-by: Borislav Petkov --- Changes since v5: * Moved locking further out, to allow no-irq-masking in the future. drivers/acpi/apei/ghes.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 2880547e13b8..ed8669a6c100 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -113,12 +113,13 @@ static DEFINE_MUTEX(ghes_list_mutex); * from BIOS to Linux can be determined only in NMI, IRQ or timer * handler, but general ioremap can not be used in atomic context, so * the fixmap is used instead. - * - * These 2 spinlocks are used to prevent the fixmap entries from being used - * simultaneously. */ -static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); -static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); + +/* + * Used by ghes_proc() to prevent non-NMI notifications from interacting. + * This also protects the FIX_APEI_GHES_IRQ fixmap slot. + */ +static DEFINE_SPINLOCK(ghes_notify_lock_irq); static struct gen_pool *ghes_estatus_pool; static unsigned long ghes_estatus_pool_size_request; @@ -291,7 +292,6 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, int from_phys) { void __iomem *vaddr; - unsigned long flags = 0; int in_nmi = in_nmi(); u64 offset; u32 trunk; @@ -299,10 +299,8 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, while (len > 0) { offset = paddr - (paddr & PAGE_MASK); if (in_nmi) { - raw_spin_lock(&ghes_ioremap_lock_nmi); vaddr = ghes_ioremap_pfn_nmi(paddr >> PAGE_SHIFT); } else { - spin_lock_irqsave(&ghes_ioremap_lock_irq, flags); vaddr = ghes_ioremap_pfn_irq(paddr >> PAGE_SHIFT); } trunk = PAGE_SIZE - offset; @@ -316,10 +314,8 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, buffer += trunk; if (in_nmi) { ghes_iounmap_nmi(); - raw_spin_unlock(&ghes_ioremap_lock_nmi); } else { ghes_iounmap_irq(); - spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); } } } @@ -928,8 +924,11 @@ static void ghes_add_timer(struct ghes *ghes) static void ghes_poll_func(struct timer_list *t) { struct ghes *ghes = from_timer(ghes, t, timer); + unsigned long flags; + spin_lock_irqsave(&ghes_notify_lock_irq, flags); ghes_proc(ghes); + spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); if (!(ghes->flags & GHES_EXITING)) ghes_add_timer(ghes); } @@ -937,9 +936,12 @@ static void ghes_poll_func(struct timer_list *t) static irqreturn_t ghes_irq_func(int irq, void *data) { struct ghes *ghes = data; + unsigned long flags; int rc; + spin_lock_irqsave(&ghes_notify_lock_irq, flags); rc = ghes_proc(ghes); + spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); if (rc) return IRQ_NONE; @@ -950,14 +952,17 @@ static int ghes_notify_hed(struct notifier_block *this, unsigned long event, void *data) { struct ghes *ghes; + unsigned long flags; int ret = NOTIFY_DONE; + spin_lock_irqsave(&ghes_notify_lock_irq, flags); rcu_read_lock(); list_for_each_entry_rcu(ghes, &ghes_hed, list) { if (!ghes_proc(ghes)) ret = NOTIFY_OK; } rcu_read_unlock(); + spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); return ret; } @@ -968,6 +973,7 @@ static struct notifier_block ghes_notifier_hed = { #ifdef CONFIG_ACPI_APEI_SEA static LIST_HEAD(ghes_sea); +static DEFINE_RAW_SPINLOCK(ghes_notify_lock_sea); /* * Return 0 only if one of the SEA error sources successfully reported an error @@ -975,7 +981,13 @@ static LIST_HEAD(ghes_sea); */ int ghes_notify_sea(void) { - return ghes_estatus_queue_notified(&ghes_sea); + int rv; + + raw_spin_lock(&ghes_notify_lock_sea); + rv = ghes_estatus_queue_notified(&ghes_sea); + raw_spin_unlock(&ghes_notify_lock_sea); + + return rv; } static void ghes_sea_add(struct ghes *ghes) @@ -1009,6 +1021,7 @@ static inline void ghes_sea_remove(struct ghes *ghes) { } static atomic_t ghes_in_nmi = ATOMIC_INIT(0); static LIST_HEAD(ghes_nmi); +static DEFINE_RAW_SPINLOCK(ghes_notify_lock_nmi); static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) { @@ -1017,8 +1030,10 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) if (!atomic_add_unless(&ghes_in_nmi, 1, 1)) return ret; + raw_spin_lock(&ghes_notify_lock_nmi); if (!ghes_estatus_queue_notified(&ghes_nmi)) ret = NMI_HANDLED; + raw_spin_unlock(&ghes_notify_lock_nmi); atomic_dec(&ghes_in_nmi); return ret; @@ -1060,6 +1075,7 @@ static int ghes_probe(struct platform_device *ghes_dev) { struct acpi_hest_generic *generic; struct ghes *ghes = NULL; + unsigned long flags; int rc = -EINVAL; @@ -1162,7 +1178,9 @@ static int ghes_probe(struct platform_device *ghes_dev) ghes_edac_register(ghes, &ghes_dev->dev); /* Handle any pending errors right away */ + spin_lock_irqsave(&ghes_notify_lock_irq, flags); ghes_proc(ghes); + spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); return 0; From patchwork Fri Sep 21 22:16:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611161 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1781B913 for ; Fri, 21 Sep 2018 22:41:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05DE42DC8C for ; Fri, 21 Sep 2018 22:41:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ED8C72DCB4; Fri, 21 Sep 2018 22:41:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 67C3A2DC8C for ; Fri, 21 Sep 2018 22:41:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=AOul6OUCEbBtn+InC36DwILh3+JzLE1TvLS2KKmHkAI=; b=GyspSjlLY1NCaX ZHbchCHWuSTgZr9xz8gU8iT3l2BOMKsQ0+yJiD4iIkZPVspFxIKbG+avggJoI9+/asELM3xj5yX9+ GRm4EuZlnmgkwLyliILVxKKcOZhAiGmQj7XVlNblx1Z4l5bFqifTxxC++u9BCCRayDg+QEZC4OKWk q1GjwqBFU0rl6uO5LBDAhOpQuooxiKo8/WSZ/aacZU6/iyGXKr+aEzQ46D6y7du3NeQM6QIprKZVP h6E0jJjCiEoOR5ptkXfaPvQeL1h+SbFFKkxHH5Zd2Zi21GcwlO/nuSOTgXni+RKFJAJqa4P3FHMLI ihdQy01kNr0myA/V9efg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U7P-00028i-El; Fri, 21 Sep 2018 22:41:47 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U4s-0008In-4K for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:39:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=sAXZUylohXuZm+5P1yu+MS9VYyc1gfUewYxv0kdlr4I=; b=tEdYB+7RhfOmN5uwgqLNPxf0db aa5iOBTt0dYX8Z/P8wkqlBwKZiqmFOctZ6Cm48ExdQlkEosKqdkldu3Y4XLStqhv07Vy+OwwACn3j LnH0vlUso/X+FbOVEjNwGAFJSFLaPrrS/nyx/szcHTWle78m173VsHU8sSsDwQ5IKjsNFy7uxAseg iZ8nPkeQyCmQYtMoAn3810FBYH6mKI132G137+OIEMlsYnmezoNEyuu7LACczIc+5ld/5Tbr4yU/W ZqEsxcAA8Kfr9/tT/W1JdO8bH9ikUBU4Oesgc0JSnIFI5Jd4MTLzgrtzc0AFWM2Nyb3C7epYAP1Fj niWe4pCQ==; Received: from foss.arm.com ([217.140.101.70]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tkz-0002AY-6J for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:38 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E7A5015BF; Fri, 21 Sep 2018 15:18:22 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D2B323F557; Fri, 21 Sep 2018 15:18:19 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 09/18] ACPI / APEI: Let the notification helper specify the fixmap slot Date: Fri, 21 Sep 2018 23:16:56 +0100 Message-Id: <20180921221705.6478-10-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_181837_369298_D1917E2F X-CRM114-Status: GOOD ( 19.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP ghes_copy_tofrom_phys() uses a different fixmap slot depending on in_nmi(). This doesn't work when we have multiple NMI-like notifications, that can interrupt each other. As with the locking, move the chosen fixmap_idx to the notification helper. This only matters for NMI-like notifications, anything calling ghes_proc() can use the IRQ fixmap slot as its already holding an irqsave spinlock. This lets us collapse the ghes_ioremap_pfn_*() helpers. Signed-off-by: James Morse Reviewed-by: Borislav Petkov --- The fixmap-idx and vaddr are passed back to ghes_unmap() to allow ioremap() to be used in process context in the future. --- drivers/acpi/apei/ghes.c | 76 ++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index ed8669a6c100..adf7fd402813 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -129,38 +130,24 @@ static atomic_t ghes_estatus_cache_alloced; static int ghes_panic_timeout __read_mostly = 30; -static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) +static void __iomem *ghes_map(u64 pfn, int fixmap_idx) { phys_addr_t paddr; pgprot_t prot; - paddr = pfn << PAGE_SHIFT; + paddr = PFN_PHYS(pfn); prot = arch_apei_get_mem_attribute(paddr); - __set_fixmap(FIX_APEI_GHES_NMI, paddr, prot); + __set_fixmap(fixmap_idx, paddr, prot); - return (void __iomem *) fix_to_virt(FIX_APEI_GHES_NMI); + return (void __iomem *) __fix_to_virt(fixmap_idx); } -static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) +static void ghes_unmap(int fixmap_idx, void __iomem *vaddr) { - phys_addr_t paddr; - pgprot_t prot; - - paddr = pfn << PAGE_SHIFT; - prot = arch_apei_get_mem_attribute(paddr); - __set_fixmap(FIX_APEI_GHES_IRQ, paddr, prot); - - return (void __iomem *) fix_to_virt(FIX_APEI_GHES_IRQ); -} - -static void ghes_iounmap_nmi(void) -{ - clear_fixmap(FIX_APEI_GHES_NMI); -} + int _idx = virt_to_fix((unsigned long)vaddr); -static void ghes_iounmap_irq(void) -{ - clear_fixmap(FIX_APEI_GHES_IRQ); + WARN_ON_ONCE(fixmap_idx != _idx); + clear_fixmap(fixmap_idx); } static int ghes_estatus_pool_init(void) @@ -289,20 +276,15 @@ static inline int ghes_severity(int severity) } static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, - int from_phys) + int from_phys, int fixmap_idx) { void __iomem *vaddr; - int in_nmi = in_nmi(); u64 offset; u32 trunk; while (len > 0) { offset = paddr - (paddr & PAGE_MASK); - if (in_nmi) { - vaddr = ghes_ioremap_pfn_nmi(paddr >> PAGE_SHIFT); - } else { - vaddr = ghes_ioremap_pfn_irq(paddr >> PAGE_SHIFT); - } + vaddr = ghes_map(PHYS_PFN(paddr), fixmap_idx); trunk = PAGE_SIZE - offset; trunk = min(trunk, len); if (from_phys) @@ -312,15 +294,11 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, len -= trunk; paddr += trunk; buffer += trunk; - if (in_nmi) { - ghes_iounmap_nmi(); - } else { - ghes_iounmap_irq(); - } + ghes_unmap(fixmap_idx, vaddr); } } -static int ghes_read_estatus(struct ghes *ghes, int silent) +static int ghes_read_estatus(struct ghes *ghes, int silent, int fixmap_idx) { struct acpi_hest_generic *g = ghes->generic; u64 buf_paddr; @@ -339,7 +317,7 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) return -ENOENT; ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, - sizeof(*ghes->estatus), 1); + sizeof(*ghes->estatus), 1, fixmap_idx); if (!ghes->estatus->block_status) return -ENOENT; @@ -356,7 +334,7 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) goto err_read_block; ghes_copy_tofrom_phys(ghes->estatus + 1, buf_paddr + sizeof(*ghes->estatus), - len - sizeof(*ghes->estatus), 1); + len - sizeof(*ghes->estatus), 1, fixmap_idx); if (cper_estatus_check(ghes->estatus)) goto err_read_block; rc = 0; @@ -368,13 +346,13 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) return rc; } -static void ghes_clear_estatus(struct ghes *ghes) +static void ghes_clear_estatus(struct ghes *ghes, int fixmap_idx) { ghes->estatus->block_status = 0; if (!(ghes->flags & GHES_TO_CLEAR)) return; ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, - sizeof(ghes->estatus->block_status), 0); + sizeof(ghes->estatus->block_status), 0, fixmap_idx); ghes->flags &= ~GHES_TO_CLEAR; } @@ -740,12 +718,12 @@ static void __process_error(struct ghes *ghes) llist_add(&estatus_node->llnode, &ghes_estatus_llist); } -static int _in_nmi_notify_one(struct ghes *ghes) +static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) { int sev; - if (ghes_read_estatus(ghes, 1)) { - ghes_clear_estatus(ghes); + if (ghes_read_estatus(ghes, 1, fixmap_idx)) { + ghes_clear_estatus(ghes, fixmap_idx); return -ENOENT; } @@ -759,19 +737,19 @@ static int _in_nmi_notify_one(struct ghes *ghes) return 0; __process_error(ghes); - ghes_clear_estatus(ghes); + ghes_clear_estatus(ghes, fixmap_idx); return 0; } -static int ghes_estatus_queue_notified(struct list_head *rcu_list) +static int ghes_estatus_queue_notified(struct list_head *rcu_list, int fixmap_idx) { int ret = -ENOENT; struct ghes *ghes; rcu_read_lock(); list_for_each_entry_rcu(ghes, rcu_list, list) { - if (!_in_nmi_notify_one(ghes)) + if (!_in_nmi_notify_one(ghes, fixmap_idx)) ret = 0; } rcu_read_unlock(); @@ -876,7 +854,7 @@ static int ghes_proc(struct ghes *ghes) { int rc; - rc = ghes_read_estatus(ghes, 0); + rc = ghes_read_estatus(ghes, 0, FIX_APEI_GHES_IRQ); if (rc) goto out; @@ -891,7 +869,7 @@ static int ghes_proc(struct ghes *ghes) ghes_do_proc(ghes, ghes->estatus); out: - ghes_clear_estatus(ghes); + ghes_clear_estatus(ghes, FIX_APEI_GHES_IRQ); if (rc == -ENOENT) return rc; @@ -984,7 +962,7 @@ int ghes_notify_sea(void) int rv; raw_spin_lock(&ghes_notify_lock_sea); - rv = ghes_estatus_queue_notified(&ghes_sea); + rv = ghes_estatus_queue_notified(&ghes_sea, FIX_APEI_GHES_NMI); raw_spin_unlock(&ghes_notify_lock_sea); return rv; @@ -1031,7 +1009,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) return ret; raw_spin_lock(&ghes_notify_lock_nmi); - if (!ghes_estatus_queue_notified(&ghes_nmi)) + if (!ghes_estatus_queue_notified(&ghes_nmi, FIX_APEI_GHES_NMI)) ret = NMI_HANDLED; raw_spin_unlock(&ghes_notify_lock_nmi); From patchwork Fri Sep 21 22:16:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611163 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 914CD913 for ; Fri, 21 Sep 2018 22:42:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B8CC2DCA1 for ; Fri, 21 Sep 2018 22:42:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D7BF2DD2D; Fri, 21 Sep 2018 22:42:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D10B42DCA1 for ; Fri, 21 Sep 2018 22:42:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=8eaL6u74c0k6bGvSeuH60IVZH+8rp9+I3vAY/4jqC2U=; b=gqGPXHw/qqz9q3 PUXrQ3HiGMnwumNgMgM1918HJ5c9AUr1lb11jnBH3buaI5KvRzZpduT5wvFPHoiUA2czXFK/Awg55 xssKxyWJSd5zNh7YrddgkC5RXhA4lOXsKJw2cS/jmqeCFkwmMpzUGXFUXuSqmQh9GdQr8HUYoKkli gtAgYgbcTpydBRSvSJGqWDATb3Vxku007DAR+B2zmxHFkBSMxfy4ofHGNT9ZDnxuw41GOWAvG46Ec Cv3YkTB3dLwmcBgLAkzzL+K4w4ibjStKKVz6UKuiOnUTBU8Mqjp4igmQCz6qSVXzIOnOX8qAglgCL 8ul0vrM0BNdoVKtYEmOg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U82-0002P5-3D; Fri, 21 Sep 2018 22:42:26 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U4t-0008In-Tz for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:39:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ZMaGmi8+i1xyXO2zgDdxrVcghcXZ3SFBxxQwybJs7mQ=; b=hW/fAikzawQOgfgOgAJa6p9FHm tKRrCpKcBWI16JDF+biJUcb6kV337YlIsHt/wRzIckBEqfUqCmVDtdveaL2cz0xYrhnPe5oUqvB5j OgBoSih2qQCqxQqwHclEqhMJTm50rpduPV4TEgvjnXURB8zpwyxTEiB594vP0nmxb4LkEcc24A4HU nZtHSMoToKnuwdfVEL3ST2rUdbZbGvjtzn8tc+zw1XEzBIcQSfD1+zm19BX6ylfhMHzb8Zlpofy/F uhTSYPbCKpw0p/1TfqF+1mAdNaDXEhfEas1dJPDhNoZiV9rDIevwFQTLfQVP6oH4Vi4hBVEqUIwq7 WK6FnZOg==; Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tkz-0002Ac-5b for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:38 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1C3E01684; Fri, 21 Sep 2018 15:18:27 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 071723F557; Fri, 21 Sep 2018 15:18:23 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 10/18] ACPI / APEI: preparatory split of ghes->estatus Date: Fri, 21 Sep 2018 23:16:57 +0100 Message-Id: <20180921221705.6478-11-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_181837_398006_C2015E17 X-CRM114-Status: GOOD ( 19.07 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The NMI-like notifications scribble over ghes->estatus, before copying it somewhere else. If this interrupts the ghes_probe() code calling ghes_proc() on each struct ghes, the data is corrupted. We want the NMI-like notifications to use a queued estatus entry from the beginning. To that end, break up any use of "ghes->estatus" so that all functions take the estatus as an argument. This patch is just moving code around, no change in behaviour. Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 82 ++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index adf7fd402813..586689cbc0fd 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -298,7 +298,9 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, } } -static int ghes_read_estatus(struct ghes *ghes, int silent, int fixmap_idx) +static int ghes_read_estatus(struct ghes *ghes, + struct acpi_hest_generic_status *estatus, + int silent, int fixmap_idx) { struct acpi_hest_generic *g = ghes->generic; u64 buf_paddr; @@ -316,26 +318,26 @@ static int ghes_read_estatus(struct ghes *ghes, int silent, int fixmap_idx) if (!buf_paddr) return -ENOENT; - ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, - sizeof(*ghes->estatus), 1, fixmap_idx); - if (!ghes->estatus->block_status) + ghes_copy_tofrom_phys(estatus, buf_paddr, + sizeof(*estatus), 1, fixmap_idx); + if (!estatus->block_status) return -ENOENT; ghes->buffer_paddr = buf_paddr; ghes->flags |= GHES_TO_CLEAR; rc = -EIO; - len = cper_estatus_len(ghes->estatus); - if (len < sizeof(*ghes->estatus)) + len = cper_estatus_len(estatus); + if (len < sizeof(*estatus)) goto err_read_block; if (len > ghes->generic->error_block_length) goto err_read_block; - if (cper_estatus_check_header(ghes->estatus)) + if (cper_estatus_check_header(estatus)) goto err_read_block; - ghes_copy_tofrom_phys(ghes->estatus + 1, - buf_paddr + sizeof(*ghes->estatus), - len - sizeof(*ghes->estatus), 1, fixmap_idx); - if (cper_estatus_check(ghes->estatus)) + ghes_copy_tofrom_phys(estatus + 1, + buf_paddr + sizeof(*estatus), + len - sizeof(*estatus), 1, fixmap_idx); + if (cper_estatus_check(estatus)) goto err_read_block; rc = 0; @@ -346,13 +348,15 @@ static int ghes_read_estatus(struct ghes *ghes, int silent, int fixmap_idx) return rc; } -static void ghes_clear_estatus(struct ghes *ghes, int fixmap_idx) +static void ghes_clear_estatus(struct ghes *ghes, + struct acpi_hest_generic_status *estatus, + int fixmap_idx) { - ghes->estatus->block_status = 0; + estatus->block_status = 0; if (!(ghes->flags & GHES_TO_CLEAR)) return; - ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, - sizeof(ghes->estatus->block_status), 0, fixmap_idx); + ghes_copy_tofrom_phys(estatus, ghes->buffer_paddr, + sizeof(estatus->block_status), 0, fixmap_idx); ghes->flags &= ~GHES_TO_CLEAR; } @@ -518,9 +522,10 @@ static int ghes_print_estatus(const char *pfx, return 0; } -static void __ghes_panic(struct ghes *ghes) +static void __ghes_panic(struct ghes *ghes, + struct acpi_hest_generic_status *estatus) { - __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus); + __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus); /* reboot to log the error! */ if (!panic_timeout) @@ -695,16 +700,17 @@ static void ghes_print_queued_estatus(void) } /* Save estatus for further processing in IRQ context */ -static void __process_error(struct ghes *ghes) +static void __process_error(struct ghes *ghes, + struct acpi_hest_generic_status *ghes_estatus) { u32 len, node_len; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic_status *estatus; - if (ghes_estatus_cached(ghes->estatus)) + if (ghes_estatus_cached(ghes_estatus)) return; - len = cper_estatus_len(ghes->estatus); + len = cper_estatus_len(ghes_estatus); node_len = GHES_ESTATUS_NODE_LEN(len); estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len); @@ -714,35 +720,37 @@ static void __process_error(struct ghes *ghes) estatus_node->ghes = ghes; estatus_node->generic = ghes->generic; estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - memcpy(estatus, ghes->estatus, len); + memcpy(estatus, ghes_estatus, len); llist_add(&estatus_node->llnode, &ghes_estatus_llist); } static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) { int sev; + struct acpi_hest_generic_status *estatus = ghes->estatus; - if (ghes_read_estatus(ghes, 1, fixmap_idx)) { - ghes_clear_estatus(ghes, fixmap_idx); + if (ghes_read_estatus(ghes, estatus, 1, fixmap_idx)) { + ghes_clear_estatus(ghes, estatus, fixmap_idx); return -ENOENT; } - sev = ghes_severity(ghes->estatus->error_severity); + sev = ghes_severity(estatus->error_severity); if (sev >= GHES_SEV_PANIC) { ghes_print_queued_estatus(); - __ghes_panic(ghes); + __ghes_panic(ghes, estatus); } if (!(ghes->flags & GHES_TO_CLEAR)) return 0; - __process_error(ghes); - ghes_clear_estatus(ghes, fixmap_idx); + __process_error(ghes, estatus); + ghes_clear_estatus(ghes, estatus, fixmap_idx); return 0; } -static int ghes_estatus_queue_notified(struct list_head *rcu_list, int fixmap_idx) +static int ghes_estatus_queue_notified(struct list_head *rcu_list, + int fixmap_idx) { int ret = -ENOENT; struct ghes *ghes; @@ -853,23 +861,23 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) static int ghes_proc(struct ghes *ghes) { int rc; + struct acpi_hest_generic_status *estatus = ghes->estatus; - rc = ghes_read_estatus(ghes, 0, FIX_APEI_GHES_IRQ); + rc = ghes_read_estatus(ghes, estatus, 0, FIX_APEI_GHES_IRQ); if (rc) goto out; - if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) { - __ghes_panic(ghes); - } + if (ghes_severity(estatus->error_severity) >= GHES_SEV_PANIC) + __ghes_panic(ghes, estatus); - if (!ghes_estatus_cached(ghes->estatus)) { - if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) - ghes_estatus_cache_add(ghes->generic, ghes->estatus); + if (!ghes_estatus_cached(estatus)) { + if (ghes_print_estatus(NULL, ghes->generic, estatus)) + ghes_estatus_cache_add(ghes->generic, estatus); } - ghes_do_proc(ghes, ghes->estatus); + ghes_do_proc(ghes, estatus); out: - ghes_clear_estatus(ghes, FIX_APEI_GHES_IRQ); + ghes_clear_estatus(ghes, estatus, FIX_APEI_GHES_IRQ); if (rc == -ENOENT) return rc; From patchwork Fri Sep 21 22:16:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611159 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E3E9913 for ; Fri, 21 Sep 2018 22:41:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BD9F2DC8C for ; Fri, 21 Sep 2018 22:41:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2BDF32DCB4; Fri, 21 Sep 2018 22:41:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B1E8A2DC8C for ; Fri, 21 Sep 2018 22:41:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=GHVWytlmdNDNJg2/7Abjy5c1AhnsFaxc269/RoWkVlI=; b=PBYxLfHsA2l5Lz Efzml7tswC65klyoOYI1qoGmHxd8lhM9EhxdjyLlr8sthNMOLG0YeUj+E3VziAfatZ3tCg1F3189A g0V6/91nAuX+lqGfaICfsGorq1xiMCZp/MrQt0RCdaRmsq7weJhsn1UM8yumBrG4U7wp4LoPtzO4+ 1Yi79oBlN5lhHOcgJ41DXA3FcC9RqPZpVd/iSbHJRqQ9OKd2j0qpMRBRypns/1W3tV3k+CzBGbK6m LnzkQiMnYXNWXt4osBYTMPF+T+2NFDyfJsYTRcOofR7qDvQKZ6lrcxh/7wggfn4PItkZiRLDQbjje wkFU7o/DF4iabPkZqvxw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U6n-0001sk-7n; Fri, 21 Sep 2018 22:41:09 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U4q-0008In-G4 for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:39:08 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=l5JGnkBBXH8lQz6scfVyIXH0qZPR0stWI9sdTV4O/R0=; b=ky7vOeVjx8uOoxtJWDq1n5dsc6 d7itWROvKdbVVJug2hjFRUII7NnshnGgeHlXqlHAqqjgRZaVOapEQfCyhL0tMRFmvIToQi46GovQr RMIxTy6rIKxztre5N+HUagdO4cSYb6P5ROcgNnS7B/D3rptLP7skTHkDnTU7B+OrZSRS4Z1OAZ9dq io6uNWct/hqXQvcX8g/1digodgOBwc2DKSNB61sTVOOtGZsj4Kzc5Ccz1ksDipGqIMl3lNVE5cN5M 1+uc4wUJUm47e5inhXnBrzQDHy57gTMgIjE9QwM7PMSuaxMKopopVEi5fyQXEWwC0DNrklpcmeDfy FWrcY1gg==; Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tl8-0002B4-7k for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:47 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4C0051596; Fri, 21 Sep 2018 15:18:35 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3765B3F557; Fri, 21 Sep 2018 15:18:32 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 11/18] ACPI / APEI: Remove silent flag from ghes_read_estatus() Date: Fri, 21 Sep 2018 23:16:58 +0100 Message-Id: <20180921221705.6478-12-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_181846_402158_52C7D428 X-CRM114-Status: GOOD ( 15.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Subsequent patches will split up ghes_read_estatus(), at which point passing around the 'silent' flag gets annoying. This is to suppress prink() messages, which prior to 42a0bb3f7138 ("printk/nmi: generic solution for safe printk in NMI"), were unsafe in NMI context. We don't need to do this anymore, remove the flag. printk() messages are batched in a per-cpu buffer and printed via irq-work, or a call back from panic(). Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 586689cbc0fd..ba5344d26a39 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -300,7 +300,7 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, static int ghes_read_estatus(struct ghes *ghes, struct acpi_hest_generic_status *estatus, - int silent, int fixmap_idx) + int fixmap_idx) { struct acpi_hest_generic *g = ghes->generic; u64 buf_paddr; @@ -309,7 +309,7 @@ static int ghes_read_estatus(struct ghes *ghes, rc = apei_read(&buf_paddr, &g->error_status_address); if (rc) { - if (!silent && printk_ratelimit()) + if (printk_ratelimit()) pr_warning(FW_WARN GHES_PFX "Failed to read error status block address for hardware error source: %d.\n", g->header.source_id); @@ -342,7 +342,7 @@ static int ghes_read_estatus(struct ghes *ghes, rc = 0; err_read_block: - if (rc && !silent && printk_ratelimit()) + if (rc && printk_ratelimit()) pr_warning(FW_WARN GHES_PFX "Failed to read error status block!\n"); return rc; @@ -729,7 +729,7 @@ static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) int sev; struct acpi_hest_generic_status *estatus = ghes->estatus; - if (ghes_read_estatus(ghes, estatus, 1, fixmap_idx)) { + if (ghes_read_estatus(ghes, estatus, fixmap_idx)) { ghes_clear_estatus(ghes, estatus, fixmap_idx); return -ENOENT; } @@ -863,7 +863,7 @@ static int ghes_proc(struct ghes *ghes) int rc; struct acpi_hest_generic_status *estatus = ghes->estatus; - rc = ghes_read_estatus(ghes, estatus, 0, FIX_APEI_GHES_IRQ); + rc = ghes_read_estatus(ghes, estatus, FIX_APEI_GHES_IRQ); if (rc) goto out; From patchwork Fri Sep 21 22:16:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611125 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 03A17112B for ; Fri, 21 Sep 2018 22:36:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6BB72D7A3 for ; Fri, 21 Sep 2018 22:36:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DA9E82D7B8; Fri, 21 Sep 2018 22:36:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4C3862D7A3 for ; Fri, 21 Sep 2018 22:36:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=o+U+ZOuqp6IgPtX1uMsKVop+4cwq02V0LR4XrX2B/Ys=; b=Ov4SxWt2OrFY+6 e6fQHJx8BFyHbwsL4nxF+ju2/EWWiqKovnF4uiHU3PE2nr5NMiBv42DAX8Ibq/IfvmKx0sLD5KGf8 iAR5Ffwc5fglSRSgHWuzqsAsnXr3CVqtSITRETIInkc3Lvefj5MD8RcpBZVCLtMuxM1WO2tpjC54X nlYlSFa6lK6/MI91VwJLoM0A2QvdUQWL0SV52XM8VdF8R1vdsJZkEyE05AlU7qJFOs96VKpCOv/7T KbhSkjOiknXt6s8p7hegabjoWvPpcPJoY9sGL/rpeG0+paFK8oMGQ7vgEgzD0IhY8huDrcYmCqsGF b2nOTiXSKSGOYS9S3imA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U2E-0007QV-9A; Fri, 21 Sep 2018 22:36:26 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzt-0004vp-MV for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:34:01 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=W8xhfjYK2/1TcXsdgpXmSCTO/ZH8hhDC4qYWAF8qWtY=; b=K9ZCRKfncZuDt9npleWKvFQzNd AdAUQN726lTxIxh3WxAVrnXEHQTlM95CsdQpJ6sWAUR94z4VFbKzH/1aBpsqZAUKqO7FwiTfBQpUs 3sKqyBqLG0W7Rmp9xtjMzs7J/sD9zl0bRnLsk2s9hVRvQUnj6DSWPvwMSWhhDzJcZbV71jl24S1ZS wGP2TYZ+vF1miCZ0DCuTuLaWLWnPClCukLE+l7qgMbKlv5ZCkiwAN4ZAtPiRGkmnvQxzcEJVug/CY biRSs8bkG6feHpL7wQG66qQW0Vxkdr5J1cEocYjna4wK5QSfCfY7JFN50L1Q97ZAqixl6Q4SkLzI/ 3316nu3Q==; Received: from foss.arm.com ([217.140.101.70]) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlD-0003vr-2H for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:53 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 23AAE15BF; Fri, 21 Sep 2018 15:18:40 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 0F1FF3F557; Fri, 21 Sep 2018 15:18:36 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 12/18] ACPI / APEI: Don't store CPER records physical address in struct ghes Date: Fri, 21 Sep 2018 23:16:59 +0100 Message-Id: <20180921221705.6478-13-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231851_391565_BAAFF2B2 X-CRM114-Status: GOOD ( 15.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP When CPER records are found the address of the records is stashed in the struct ghes. Once the records have been processed, this address is overwritten with zero so that it won't be processed again without being re-populated by firmware. This goes wrong if a struct ghes can be processed concurrently, as can happen at probe time when an NMI occurs. Avoid this stashing by letting the caller hold the address. A later patch will do away with the use of ghes->flags in the read/clear code too. Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 28 ++++++++++++++-------------- include/acpi/ghes.h | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index ba5344d26a39..c58f9b330ed3 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -300,14 +300,13 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, static int ghes_read_estatus(struct ghes *ghes, struct acpi_hest_generic_status *estatus, - int fixmap_idx) + u64 *buf_paddr, int fixmap_idx) { struct acpi_hest_generic *g = ghes->generic; - u64 buf_paddr; u32 len; int rc; - rc = apei_read(&buf_paddr, &g->error_status_address); + rc = apei_read(buf_paddr, &g->error_status_address); if (rc) { if (printk_ratelimit()) pr_warning(FW_WARN GHES_PFX @@ -315,15 +314,14 @@ static int ghes_read_estatus(struct ghes *ghes, g->header.source_id); return -EIO; } - if (!buf_paddr) + if (!*buf_paddr) return -ENOENT; - ghes_copy_tofrom_phys(estatus, buf_paddr, + ghes_copy_tofrom_phys(estatus, *buf_paddr, sizeof(*estatus), 1, fixmap_idx); if (!estatus->block_status) return -ENOENT; - ghes->buffer_paddr = buf_paddr; ghes->flags |= GHES_TO_CLEAR; rc = -EIO; @@ -335,7 +333,7 @@ static int ghes_read_estatus(struct ghes *ghes, if (cper_estatus_check_header(estatus)) goto err_read_block; ghes_copy_tofrom_phys(estatus + 1, - buf_paddr + sizeof(*estatus), + *buf_paddr + sizeof(*estatus), len - sizeof(*estatus), 1, fixmap_idx); if (cper_estatus_check(estatus)) goto err_read_block; @@ -350,12 +348,12 @@ static int ghes_read_estatus(struct ghes *ghes, static void ghes_clear_estatus(struct ghes *ghes, struct acpi_hest_generic_status *estatus, - int fixmap_idx) + u64 buf_paddr, int fixmap_idx) { estatus->block_status = 0; if (!(ghes->flags & GHES_TO_CLEAR)) return; - ghes_copy_tofrom_phys(estatus, ghes->buffer_paddr, + ghes_copy_tofrom_phys(estatus, buf_paddr, sizeof(estatus->block_status), 0, fixmap_idx); ghes->flags &= ~GHES_TO_CLEAR; } @@ -727,10 +725,11 @@ static void __process_error(struct ghes *ghes, static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) { int sev; + u64 buf_paddr; struct acpi_hest_generic_status *estatus = ghes->estatus; - if (ghes_read_estatus(ghes, estatus, fixmap_idx)) { - ghes_clear_estatus(ghes, estatus, fixmap_idx); + if (ghes_read_estatus(ghes, estatus, &buf_paddr, fixmap_idx)) { + ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); return -ENOENT; } @@ -744,7 +743,7 @@ static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) return 0; __process_error(ghes, estatus); - ghes_clear_estatus(ghes, estatus, fixmap_idx); + ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); return 0; } @@ -861,9 +860,10 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 *gv2) static int ghes_proc(struct ghes *ghes) { int rc; + u64 buf_paddr; struct acpi_hest_generic_status *estatus = ghes->estatus; - rc = ghes_read_estatus(ghes, estatus, FIX_APEI_GHES_IRQ); + rc = ghes_read_estatus(ghes, estatus, &buf_paddr, FIX_APEI_GHES_IRQ); if (rc) goto out; @@ -877,7 +877,7 @@ static int ghes_proc(struct ghes *ghes) ghes_do_proc(ghes, estatus); out: - ghes_clear_estatus(ghes, estatus, FIX_APEI_GHES_IRQ); + ghes_clear_estatus(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ); if (rc == -ENOENT) return rc; diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index 82cb4eb225a4..6dc021e9cdad 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -22,7 +22,6 @@ struct ghes { struct acpi_hest_generic_v2 *generic_v2; }; struct acpi_hest_generic_status *estatus; - u64 buffer_paddr; unsigned long flags; union { struct list_head list; From patchwork Fri Sep 21 22:17:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611167 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F207514BD for ; Fri, 21 Sep 2018 22:48:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF5112DFDA for ; Fri, 21 Sep 2018 22:48:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D161B2DFE1; Fri, 21 Sep 2018 22:48:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 63E332DFDA for ; Fri, 21 Sep 2018 22:48:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=mAFHM6qfbSgdNYgQ3K9N1zzLdbODiaFbUYmeLDa3L2g=; b=jGiqfxTNDA2qKi wrf6IRgdAtMy2FVF/1PliOY8Lj5mYinpn6z7u3WVQ565rN6SCKIxtXVGzt7Xt9LhOWDfXtRZpbOW8 gS8S1oZCyGfWUORJKPZ/YDfvlezgGV74xEN9eiiZTAbSXtJN3T1o1WfuBUvuRpaEqRNFtfAxJUxgL 2rYMdNdW06qB3qM50HMXBmq4eSiTzAz/5fHlUCmPcY11tZtcnf2qB1MBSf9R3qafolrF+8pGWb3sm oUTCBHzrM/IU4m9EBIXdKEWpwW8EVL2mLNnQj+odbLgM9J19pZRHxnU/muPNQUPsehPALQUUqr5EA rks1/94eaDrotvqtJy8A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3UE0-0004Zy-Tc; Fri, 21 Sep 2018 22:48:36 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzu-0004vq-8n for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:34:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=bboPjrhPBdZVtPAqzi8WofR0+B9wPN9MRHdT7ciiho8=; b=Ps9/ueZymNpt4KG57gdBIRnvL4 yEUN5OTfYkx0BDemPYb0FVWPCWl9n1qxBJJB8vTIMF8xYJ6+1lNTRynazvmbuW7aqQAydhQMwtPN1 6WOQx2IyrQ/IA7fgbWiajcaeRXnq1mDXRlgYrOrQFiNdo7l/RnnKqYMpNnnEC9VlLQDRM+m6Knz8X 03uZp65UBSqMZR11Tc2tjZd9xuRbjlSOVsezpzKhPgaSad5880HeYs8w5lwfWkJ2mQHOVg7M2RNse uQPtTE1i19YzVNkLghAhaBxOO2vv83jLhZGkkrSseoaElZeVXyJOEuJKVb0TeThFVZc8JSTldt9Gk FS6c/ZbQ==; Received: from foss.arm.com ([217.140.101.70]) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlD-0003wE-2G for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:18:52 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EDAA61684; Fri, 21 Sep 2018 15:18:44 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D87523F557; Fri, 21 Sep 2018 15:18:41 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 13/18] ACPI / APEI: Don't update struct ghes' flags in read/clear estatus Date: Fri, 21 Sep 2018 23:17:00 +0100 Message-Id: <20180921221705.6478-14-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231851_389260_B56A2520 X-CRM114-Status: GOOD ( 15.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP ghes_read_estatus() sets a flag in struct ghes if the buffer of CPER records needs to be cleared once the records have been processed. This global flags value is a problem if a struct ghes can be processed concurrently, as happens at probe time if an NMI arrives for the same error source. The GHES_TO_CLEAR flags was only set at the same time as buffer_paddr, which is now owned by the caller and passed to ghes_clear_estatus(). Use this as the flag. A non-zero buf_paddr returned by ghes_read_estatus() means ghes_clear_estatus() will clear this address. ghes_read_estatus() already checks for a read of error_status_address being zero, so we can never get CPER records written at zero. After this ghes_clear_estatus() no longer needs the struct ghes. Signed-off-by: James Morse Reviewed-by: Borislav Petkov --- drivers/acpi/apei/ghes.c | 26 ++++++++++++-------------- include/acpi/ghes.h | 1 - 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index c58f9b330ed3..3028487d43a3 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -319,10 +319,10 @@ static int ghes_read_estatus(struct ghes *ghes, ghes_copy_tofrom_phys(estatus, *buf_paddr, sizeof(*estatus), 1, fixmap_idx); - if (!estatus->block_status) + if (!estatus->block_status) { + *buf_paddr = 0; return -ENOENT; - - ghes->flags |= GHES_TO_CLEAR; + } rc = -EIO; len = cper_estatus_len(estatus); @@ -346,16 +346,14 @@ static int ghes_read_estatus(struct ghes *ghes, return rc; } -static void ghes_clear_estatus(struct ghes *ghes, - struct acpi_hest_generic_status *estatus, +static void ghes_clear_estatus(struct acpi_hest_generic_status *estatus, u64 buf_paddr, int fixmap_idx) { estatus->block_status = 0; - if (!(ghes->flags & GHES_TO_CLEAR)) - return; - ghes_copy_tofrom_phys(estatus, buf_paddr, - sizeof(estatus->block_status), 0, fixmap_idx); - ghes->flags &= ~GHES_TO_CLEAR; + if (buf_paddr) + ghes_copy_tofrom_phys(estatus, buf_paddr, + sizeof(estatus->block_status), 0, + fixmap_idx); } static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) @@ -729,7 +727,7 @@ static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) struct acpi_hest_generic_status *estatus = ghes->estatus; if (ghes_read_estatus(ghes, estatus, &buf_paddr, fixmap_idx)) { - ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); + ghes_clear_estatus(estatus, buf_paddr, fixmap_idx); return -ENOENT; } @@ -739,11 +737,11 @@ static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) __ghes_panic(ghes, estatus); } - if (!(ghes->flags & GHES_TO_CLEAR)) + if (!buf_paddr) return 0; __process_error(ghes, estatus); - ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); + ghes_clear_estatus(estatus, buf_paddr, fixmap_idx); return 0; } @@ -877,7 +875,7 @@ static int ghes_proc(struct ghes *ghes) ghes_do_proc(ghes, estatus); out: - ghes_clear_estatus(ghes, estatus, buf_paddr, FIX_APEI_GHES_IRQ); + ghes_clear_estatus(estatus, buf_paddr, FIX_APEI_GHES_IRQ); if (rc == -ENOENT) return rc; diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index 6dc021e9cdad..536f90dd1e34 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -13,7 +13,6 @@ * estatus: memory buffer for error status block, allocated during * HEST parsing. */ -#define GHES_TO_CLEAR 0x0001 #define GHES_EXITING 0x0002 struct ghes { From patchwork Fri Sep 21 22:17:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611085 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76AC05A4 for ; Fri, 21 Sep 2018 22:22:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64D4C2E380 for ; Fri, 21 Sep 2018 22:22:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 587F82E611; Fri, 21 Sep 2018 22:22:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DD2182E380 for ; Fri, 21 Sep 2018 22:22:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=fEakcC3IC2yplsbyQrFMY3pKClGrOsnAfWb6LgvJU0Q=; b=DEs//1lEqr6cNm OqVj7BYnIIUzQV9+mzn3W8kmbb/AabgFcwsaeWKzoJ3Iu7poggfb33DJfK4F2VoyND8PqkQwP5AvU 3z++BVZMCUJIV51zRDnlEmcOveDt1M7Y/VA0XfuoNYHXIStU24sqWLCYEMS8L79tEdIvrQ1gUUfhY QFVgIdFaZNMCXFVOiBEKZWC7I/27js71jtJWQEEZ/xBVzAs/oH/Hu00cEnpahqLWk0UBy0rrOmzWD 58BMhKLvGvKXgCh8AZ7Bd4F+GBhdvZRas/tCDdo1rA+4lTvfj5Ed1S0gY0+iS1bEOA0QKN7M9KutE +U5EwQNwUufTKrBsbIiQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3ToE-0007ST-39; Fri, 21 Sep 2018 22:21:58 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlM-0004yk-Ia for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:20:51 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 21CA81596; Fri, 21 Sep 2018 15:18:50 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 0C7F43F557; Fri, 21 Sep 2018 15:18:46 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 14/18] ACPI / APEI: Split ghes_read_estatus() to read CPER length Date: Fri, 21 Sep 2018 23:17:01 +0100 Message-Id: <20180921221705.6478-15-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151900_681797_8FF0A0E2 X-CRM114-Status: GOOD ( 16.60 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP ghes_read_estatus() reads the record address, then the record's header, then performs some sanity checks before reading the records into the provided estatus buffer. We either need to know the size of the records before we call ghes_read_estatus(), or always provide a worst-case sized buffer, as happens today. Add a function to peek at the record's header to find the size. This will let the NMI path allocate the right amount of memory before reading the records, instead of using the worst-case size, and having to copy the records. Split ghes_read_estatus() to create ghes_peek_estatus() which returns the address and size of the CPER records. Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 55 ++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 3028487d43a3..055176ed68ac 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -298,11 +298,12 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, } } -static int ghes_read_estatus(struct ghes *ghes, - struct acpi_hest_generic_status *estatus, - u64 *buf_paddr, int fixmap_idx) +/* read the CPER block returning its address and size */ +static int ghes_peek_estatus(struct ghes *ghes, int fixmap_idx, + u64 *buf_paddr, u32 *buf_len) { struct acpi_hest_generic *g = ghes->generic; + struct acpi_hest_generic_status estatus; u32 len; int rc; @@ -317,26 +318,23 @@ static int ghes_read_estatus(struct ghes *ghes, if (!*buf_paddr) return -ENOENT; - ghes_copy_tofrom_phys(estatus, *buf_paddr, - sizeof(*estatus), 1, fixmap_idx); - if (!estatus->block_status) { + ghes_copy_tofrom_phys(&estatus, *buf_paddr, + sizeof(estatus), 1, fixmap_idx); + if (!estatus.block_status) { *buf_paddr = 0; return -ENOENT; } rc = -EIO; - len = cper_estatus_len(estatus); - if (len < sizeof(*estatus)) + len = cper_estatus_len(&estatus); + if (len < sizeof(estatus)) goto err_read_block; if (len > ghes->generic->error_block_length) goto err_read_block; - if (cper_estatus_check_header(estatus)) - goto err_read_block; - ghes_copy_tofrom_phys(estatus + 1, - *buf_paddr + sizeof(*estatus), - len - sizeof(*estatus), 1, fixmap_idx); - if (cper_estatus_check(estatus)) + if (cper_estatus_check_header(&estatus)) goto err_read_block; + *buf_len = len; + rc = 0; err_read_block: @@ -346,6 +344,35 @@ static int ghes_read_estatus(struct ghes *ghes, return rc; } +static int __ghes_read_estatus(struct acpi_hest_generic_status *estatus, + u64 buf_paddr, size_t buf_len, + int fixmap_idx) +{ + ghes_copy_tofrom_phys(estatus, buf_paddr, buf_len, 1, fixmap_idx); + if (cper_estatus_check(estatus)) { + if (printk_ratelimit()) + pr_warning(FW_WARN GHES_PFX + "Failed to read error status block!\n"); + return -EIO; + } + + return 0; +} + +static int ghes_read_estatus(struct ghes *ghes, + struct acpi_hest_generic_status *estatus, + u64 *buf_paddr, int fixmap_idx) +{ + int rc; + u32 buf_len; + + rc = ghes_peek_estatus(ghes, fixmap_idx, buf_paddr, &buf_len); + if (rc) + return rc; + + return __ghes_read_estatus(estatus, *buf_paddr, buf_len, fixmap_idx); +} + static void ghes_clear_estatus(struct acpi_hest_generic_status *estatus, u64 buf_paddr, int fixmap_idx) { From patchwork Fri Sep 21 22:17:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0EE2514DA for ; Fri, 21 Sep 2018 22:35:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0C212D796 for ; Fri, 21 Sep 2018 22:35:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E18362D79F; Fri, 21 Sep 2018 22:35:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 651862D796 for ; Fri, 21 Sep 2018 22:35:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=mFRzP+O/KyMUG3riL5WgVnZBN4COM26JPNBtPc6XLYM=; b=mG/8WNLyI+yBQ3 UJA9xT9crAGCn2p06ot2IfNEaITscbjKicK0FEiwgVacze5Fckn62KvKpL18EQhitGPzqpi2giVrJ Sgpin2lxPh1BXmBc0VsoCrZtgPRUkpdTip5xxyPK2/IDuZXGa5eA8U2psoKyHAp3Kkpy/fcHje7hZ HmPSq6v1jUvYrsGXU/yiypjNR3w7f9QrQ/VoDdHUOmwakeCFL9+wiP9HQOl+w1PND1vA5tJXcEdkS RZXw6Z16PydMNd336xcfg6UpPMkkqoALGwbi4kHCP1F9LmEVezOtNVsjQ8NEiLYuBWsl0W1ngAMnx 4KkdX0D4RRYUT+jzIvyw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U11-0005uq-Hk; Fri, 21 Sep 2018 22:35:11 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzp-0004vp-2E for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:33:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=NlHipBD85WpKIhfoKQJofToLO84wEXj65vQgfTlE2IY=; b=QKVdeHJ1LXXalotFHj4MP8019u t5CHqc8AlxDpQy2fxrHkwo4Wb72OFNLrC8K9jFJHPAkX/BVK6EnEMKrLSzPy37dzGB+w9ZRDqEx2S cAUGfG1Cm9/nt0R1yGrc5QDqhh1Sqlj5e5WoqeqfhwlJYd5WTh8XyvtxZ1k7tWeR9RjJgwWTYHYIy bygrGka044PKME2UT8mzumX4q5okV5DahFBMpPnIpNpcQyISlHQK+cXxcF4ZoDfXFMlJgEFGgnjxH TNEBFeX0r7azrrbkj/WbaR/GIevQE+qJEYGxVZ9x1tq3Bq+beB79B+6YE2dWDb8tZr/zUeZXhpwri LwDr62MA==; Received: from foss.arm.com ([217.140.101.70]) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlS-0003yO-1Y for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:19:09 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4347D15BE; Fri, 21 Sep 2018 15:18:55 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2DB4A3F557; Fri, 21 Sep 2018 15:18:52 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 15/18] ACPI / APEI: Only use queued estatus entry during _in_nmi_notify_one() Date: Fri, 21 Sep 2018 23:17:02 +0100 Message-Id: <20180921221705.6478-16-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231906_424132_6887D1A1 X-CRM114-Status: GOOD ( 14.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Each struct ghes has an worst-case sized buffer for storing the estatus. If an error is being processed by ghes_proc() in process context this buffer will be in use. If the error source then triggers an NMI-like notification, the same buffer will be used by _in_nmi_notify_one() to stage the estatus data, before __process_error() copys it into a queued estatus entry. Merge __process_error()s work into _in_nmi_notify_one() so that the queued estatus entry is used from the beginning. Use the ghes_peek_estatus() so we know how much memory to allocate from the ghes_estatus_pool before we read the records. Reported-by: Borislav Petkov Signed-off-by: James Morse --- drivers/acpi/apei/ghes.c | 45 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 055176ed68ac..a0c10b60ad44 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -722,40 +722,32 @@ static void ghes_print_queued_estatus(void) } } -/* Save estatus for further processing in IRQ context */ -static void __process_error(struct ghes *ghes, - struct acpi_hest_generic_status *ghes_estatus) +static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) { + u64 buf_paddr; + int sev, rc = 0; u32 len, node_len; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic_status *estatus; - if (ghes_estatus_cached(ghes_estatus)) - return; + rc = ghes_peek_estatus(ghes, fixmap_idx, &buf_paddr, &len); + if (rc) + return rc; - len = cper_estatus_len(ghes_estatus); node_len = GHES_ESTATUS_NODE_LEN(len); estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, node_len); if (!estatus_node) - return; + return -ENOMEM; estatus_node->ghes = ghes; estatus_node->generic = ghes->generic; estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - memcpy(estatus, ghes_estatus, len); - llist_add(&estatus_node->llnode, &ghes_estatus_llist); -} - -static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) -{ - int sev; - u64 buf_paddr; - struct acpi_hest_generic_status *estatus = ghes->estatus; - if (ghes_read_estatus(ghes, estatus, &buf_paddr, fixmap_idx)) { + if (__ghes_read_estatus(estatus, buf_paddr, len, fixmap_idx)) { ghes_clear_estatus(estatus, buf_paddr, fixmap_idx); - return -ENOENT; + rc = -ENOENT; + goto no_work; } sev = ghes_severity(estatus->error_severity); @@ -764,13 +756,20 @@ static int _in_nmi_notify_one(struct ghes *ghes, int fixmap_idx) __ghes_panic(ghes, estatus); } - if (!buf_paddr) - return 0; - - __process_error(ghes, estatus); ghes_clear_estatus(estatus, buf_paddr, fixmap_idx); - return 0; + if (!buf_paddr || ghes_estatus_cached(estatus)) + goto no_work; + + llist_add(&estatus_node->llnode, &ghes_estatus_llist); + + return rc; + +no_work: + gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, + node_len); + + return rc; } static int ghes_estatus_queue_notified(struct list_head *rcu_list, From patchwork Fri Sep 21 22:17:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611157 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6FEA5A4 for ; Fri, 21 Sep 2018 22:40:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5AB02DC8C for ; Fri, 21 Sep 2018 22:40:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A9AD32DCB4; Fri, 21 Sep 2018 22:40:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 38B012DC8C for ; Fri, 21 Sep 2018 22:40:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=hUFd5z8cI5tUCQQl44icvSjxCWUiKTlB7fSUVmrTvwo=; b=qFo1IHU2YXhFTI SI/uNl0sN6kPbbnjO5rPeRVReDQeSnX9b4VnsVe7Pp4xgLemjfklWUiAYfVT5YcBxxcAq0+CWxYIY N9bi6+EkLHl4I6RbF+28WvVUer+C6D4a5dI3kcfh6BYyZ4ri+Hhdjzi24UJYWZpJBk+WH0/IzL2ir YYu9q/y8yC2QdXPKvC0m9+b80M4c+VMQIRS0osRZBakJRRIzJZnTkG550tDfC9Lr98upeLx9AYu1d DxizHWgx6y7s5pvpm3/VBj/CJkjidQ3fXIXwjDebn4W6g0WmX/RdrcD3l5xszE+UkYLWD1OJPNNa9 bS84pK21/3/LuPe/6/mg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U6B-0001bp-1f; Fri, 21 Sep 2018 22:40:31 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U4o-0008In-V0 for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:39:06 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=FxGw+iV01oGrcLCTyFbW5iMNYV3xDYX8+cWpbfzyJ0M=; b=OaM6WW99sKzkR5nk+ygwFyg25D CJ2jn4WvFQFQM7K1vKmCAwcQao1J/M/AYAIm+3n4pHTRyXIc4S8TvTKkBHMQ7H3RpGyfsvb3M6hGf ehTJUEbR8AaY108g5249mWfoT9cAyazzLC0krqqvV9fxAd44LkBcXbuQXRrx4QIzVlJTxG7HXC15n HHBFfMXJkv+DYgduz+L/wy7jjALirrysEtOMhlSoa64DvkP3GlJmIOQwzU/5vN5CUsIudLRJGC8kM p+b/h4IpSKEwsBRTNU8Rx4wq4QIOY+PCNs1U4+r85J8Fim6rCRhTORfUnvi5dnCAgFwOqPitOwm18 zC9DEkfA==; Received: from foss.arm.com ([217.140.101.70]) by merlin.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlW-0002Cz-Q5 for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:19:11 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EBABF15BF; Fri, 21 Sep 2018 15:18:59 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D62BB3F557; Fri, 21 Sep 2018 15:18:56 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 16/18] ACPI / APEI: Split fixmap pages for arm64 NMI-like notifications Date: Fri, 21 Sep 2018 23:17:03 +0100 Message-Id: <20180921221705.6478-17-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_181910_988866_326B4D33 X-CRM114-Status: GOOD ( 14.46 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Now that ghes notification helpers provide the fixmap slots and take the lock themselves we can support multiple NMI-like notifications on arm64. These should be named after their notification method. x86's NOTIFY_NMI already is, move it to live with the ghes_nmi list. Change the SEA fixmap entry to be called FIX_APEI_GHES_SEA. Future patches can add support for FIX_APEI_GHES_SEI and FIX_APEI_GHES_SDEI_{NORMAL,CRITICAL}. Signed-off-by: James Morse --- Changes since v3: * idx/lock are now in a separate struct. * Add to the comment above ghes_fixmap_lock_irq so that it makes more sense in isolation. --- arch/arm64/include/asm/fixmap.h | 4 +++- drivers/acpi/apei/ghes.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h index ec1e6d6fa14c..c3974517c2cb 100644 --- a/arch/arm64/include/asm/fixmap.h +++ b/arch/arm64/include/asm/fixmap.h @@ -55,7 +55,9 @@ enum fixed_addresses { #ifdef CONFIG_ACPI_APEI_GHES /* Used for GHES mapping from assorted contexts */ FIX_APEI_GHES_IRQ, - FIX_APEI_GHES_NMI, +#ifdef CONFIG_ACPI_APEI_SEA + FIX_APEI_GHES_SEA, +#endif #endif /* CONFIG_ACPI_APEI_GHES */ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index a0c10b60ad44..463c8e6d1bb5 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -994,7 +994,7 @@ int ghes_notify_sea(void) int rv; raw_spin_lock(&ghes_notify_lock_sea); - rv = ghes_estatus_queue_notified(&ghes_sea, FIX_APEI_GHES_NMI); + rv = ghes_estatus_queue_notified(&ghes_sea, FIX_APEI_GHES_SEA); raw_spin_unlock(&ghes_notify_lock_sea); return rv; @@ -1025,8 +1025,8 @@ static inline void ghes_sea_remove(struct ghes *ghes) { } #ifdef CONFIG_HAVE_ACPI_APEI_NMI /* - * NMI may be triggered on any CPU, so ghes_in_nmi is used for - * having only one concurrent reader. + * NOTIFY_NMI may be triggered on any CPU, so ghes_in_nmi is + * used for having only one concurrent reader. */ static atomic_t ghes_in_nmi = ATOMIC_INIT(0); From patchwork Fri Sep 21 22:17:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611111 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DBCD614DA for ; Fri, 21 Sep 2018 22:34:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA2782D796 for ; Fri, 21 Sep 2018 22:34:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBCE82D79F; Fri, 21 Sep 2018 22:34:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 292132D796 for ; Fri, 21 Sep 2018 22:34:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=4MkAVgb/ECa8yDC65sVi1YT8cRTAQM6Pc/HjpxiS/Os=; b=qi7NS9V91WZg9M PJkKw/9u7XPqK95wZqwIPdfRpm/dcolzZ4fn9W7Egnqj9x4Kk1ksJJCg8IiEACXvRldA58rQ0DBiK Yla5BA3sG3Zi4WUrlUisXbHnL5et5EEFptk77+7IiMoYYrIgnAooC9kMSvXqJfAPDhFSawnqWzBGx HGPpfkUGjpuZwQYNj1bEDokrcvDuBCfcgSZeIqhQn4oWFcspoC3woauqDNK+tXqYXoCmljfSl4sm2 gR8LwHjygOq6MwU1wvgnNmOWuCoyHlQb3s2pE0STI95HINTKsV7UoluzlEZ/C3ekd4GX1DoJlNK9i h105AMN3RbmtPICEQqPg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3U0K-0005Rv-63; Fri, 21 Sep 2018 22:34:28 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tzp-0004vq-Gn for linux-arm-kernel@bombadil.infradead.org; Fri, 21 Sep 2018 22:33:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=MRWCM2674PLZLao8XX6YSk3/LTKlQlpF1gW9UIEfsUY=; b=o5DIYapr5409g13F5qytNgrOOx BCKg6v8/DHusB0rbHJ14+9tX9ZGs9xKym7QiXNy8s23SE8HdNRh4zEDclgY9+FTIoIVa7C2Nh2s1V mF3LNqljnzpNWJDPeyQRLeiLVm61i3J2VQ8cSXSe1IeJvwUwhOr/hWRxyByocMao9rZGCuj6WTI8I gH6w8+IDSkUodpkbpLZ934nMWjHnDRsrtR0iTdGwAJiKWGamS1p6uwTecEzF5ctM1giN6tRqk8VEG 1TRB6afVGS5YakI7x711qD0nqZD2IlxzOlKNJT9YUfEMWe5uNg1nC1qqHcDuYBxFUhLJvb6bVCo4f VbNpRTuw==; Received: from foss.arm.com ([217.140.101.70]) by casper.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3TlS-0003zF-1a for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:19:07 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8754318A; Fri, 21 Sep 2018 15:19:04 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 727973F557; Fri, 21 Sep 2018 15:19:01 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 17/18] mm/memory-failure: increase queued recovery work's priority Date: Fri, 21 Sep 2018 23:17:04 +0100 Message-Id: <20180921221705.6478-18-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_231906_220086_EF884A87 X-CRM114-Status: GOOD ( 13.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP arm64 can take an NMI-like error notification when user-space steps in some corrupt memory. APEI's GHES code will call memory_failure_queue() to schedule the recovery work. We then return to user-space, possibly taking the fault again. Currently the arch code unconditionally signals user-space from this path, so we don't get stuck in this loop, but the affected process never benefits from memory_failure()s recovery work. To fix this we need to know the recovery work will run before we get back to user-space. Increase the priority of the recovery work by scheduling it on the system_highpri_wq, then try to bump the current task off this CPU so that the recovery work starts immediately. Reported-by: Xie XiuQi Signed-off-by: James Morse Reviewed-by: Punit Agrawal Tested-by: Tyler Baicar Tested-by: gengdongjiu CC: Xie XiuQi CC: gengdongjiu --- mm/memory-failure.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 0cd3de3550f0..4e7b115cea5a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -1454,6 +1455,7 @@ static DEFINE_PER_CPU(struct memory_failure_cpu, memory_failure_cpu); */ void memory_failure_queue(unsigned long pfn, int flags) { + int cpu = smp_processor_id(); struct memory_failure_cpu *mf_cpu; unsigned long proc_flags; struct memory_failure_entry entry = { @@ -1463,11 +1465,14 @@ void memory_failure_queue(unsigned long pfn, int flags) mf_cpu = &get_cpu_var(memory_failure_cpu); spin_lock_irqsave(&mf_cpu->lock, proc_flags); - if (kfifo_put(&mf_cpu->fifo, entry)) - schedule_work_on(smp_processor_id(), &mf_cpu->work); - else + if (kfifo_put(&mf_cpu->fifo, entry)) { + queue_work_on(cpu, system_highpri_wq, &mf_cpu->work); + set_tsk_need_resched(current); + preempt_set_need_resched(); + } else { pr_err("Memory failure: buffer overflow when queuing memory failure at %#lx\n", pfn); + } spin_unlock_irqrestore(&mf_cpu->lock, proc_flags); put_cpu_var(memory_failure_cpu); } From patchwork Fri Sep 21 22:17:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10611087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6367E14BD for ; Fri, 21 Sep 2018 22:22:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 534302E611 for ; Fri, 21 Sep 2018 22:22:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46CC32E6CF; Fri, 21 Sep 2018 22:22:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DDEDB2E611 for ; Fri, 21 Sep 2018 22:22:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=RAOnyD/orhE2n1Jr5Ot11nEyYVJ1KTUzfBrY7/rm+lQ=; b=DnNO4LEBlAYZ9I 3C0AjULMyb/MbgxvTWx1OUvFmkYbLDgSN9QQ06eBgYl+OiricvF6jw1THc0JFd0ns+GufO/JOmATp TRH661hEU/pJga3dqFbU3zN2/gE5dB3uQCTnaRJtCMxreDspr/TdN9Kq+cYvKxD/e60NZ5vUXshs4 H7LNNRrMpQ9ZSOdg/adBsA1jf1fqSMnM6t0X/b0Gu7g2zZRqs9hyvfbqZfWlfnATcgUUdyDy6j96c X2AFXZL82Opxa/hB1MN23oILZoqvcsnAar1flXvkd/drLzYQzTODK4KNIREPmubhS7MaZmZ9UVBb3 38qNP4jueJLS1RU8SlnQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Ton-0007iC-Bg; Fri, 21 Sep 2018 22:22:33 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g3Tlf-000576-4b for linux-arm-kernel@lists.infradead.org; Fri, 21 Sep 2018 22:21:10 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E085518A; Fri, 21 Sep 2018 15:19:08 -0700 (PDT) Received: from melchizedek.Emea.Arm.com (melchizedek.emea.arm.com [10.4.12.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CB4903F557; Fri, 21 Sep 2018 15:19:05 -0700 (PDT) From: James Morse To: linux-acpi@vger.kernel.org Subject: [PATCH v6 18/18] arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work Date: Fri, 21 Sep 2018 23:17:05 +0100 Message-Id: <20180921221705.6478-19-james.morse@arm.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180921221705.6478-1-james.morse@arm.com> References: <20180921221705.6478-1-james.morse@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180921_151919_232899_1E5E91E2 X-CRM114-Status: GOOD ( 16.58 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jonathan.zhang@cavium.com, Rafael Wysocki , Tony Luck , Punit Agrawal , Xie XiuQi , Marc Zyngier , Catalin Marinas , Tyler Baicar , Will Deacon , Christoffer Dall , Dongjiu Geng , linux-mm@kvack.org, Borislav Petkov , James Morse , Naoya Horiguchi , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Len Brown Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP APEI is unable to do all of its error handling work in nmi-context, so it defers non-fatal work onto the irq_work queue. arch_irq_work_raise() sends an IPI to the calling cpu, but we can't guarantee this will be taken before we return. Unless we interrupted a context with irqs-masked, we can call irq_work_run() to do the work now. Otherwise return -EINPROGRESS to indicate ghes_notify_sea() found some work to do, but it hasn't finished yet. With this we can take apei_claim_sea() returning '0' to mean this external-abort was also notification of a firmware-first RAS error, and that APEI has processed the CPER records. Signed-off-by: James Morse Reviewed-by: Punit Agrawal Tested-by: Tyler Baicar CC: Xie XiuQi CC: gengdongjiu --- Changes since v2: * Removed IS_ENABLED() check, done by the caller unless we have a dummy definition. --- arch/arm64/kernel/acpi.c | 19 +++++++++++++++++++ arch/arm64/mm/fault.c | 9 ++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index a9b8bba014b5..09744e2d15a0 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -270,10 +271,14 @@ int apei_claim_sea(struct pt_regs *regs) { int err = -ENOENT; unsigned long current_flags = arch_local_save_flags(); + unsigned long interrupted_flags = current_flags; if (!IS_ENABLED(CONFIG_ACPI_APEI_SEA)) return err; + if (regs) + interrupted_flags = regs->pstate; + /* * SEA can interrupt SError, mask it and describe this as an NMI so * that APEI defers the handling. @@ -282,6 +287,20 @@ int apei_claim_sea(struct pt_regs *regs) nmi_enter(); err = ghes_notify_sea(); nmi_exit(); + + /* + * APEI NMI-like notifications are deferred to irq_work. Unless + * we interrupted irqs-masked code, we can do that now. + */ + if (!err) { + if (!arch_irqs_disabled_flags(interrupted_flags)) { + local_daif_restore(DAIF_PROCCTX_NOIRQ); + irq_work_run(); + } else { + err = -EINPROGRESS; + } + } + local_daif_restore(current_flags); return err; diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 2c38776bb71f..97036e01522a 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -630,11 +630,10 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) inf = esr_to_fault_info(esr); - /* - * Return value ignored as we rely on signal merging. - * Future patches will make this more robust. - */ - apei_claim_sea(regs); + if (apei_claim_sea(regs) == 0) { + /* APEI claimed this as a firmware-first notification */ + return 0; + } clear_siginfo(&info); info.si_signo = inf->sig;