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;