From patchwork Mon Dec 3 18:06:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 10710273 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 849B718BC for ; Mon, 3 Dec 2018 18:07:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 795D92B47E for ; Mon, 3 Dec 2018 18:07:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6C8942B495; Mon, 3 Dec 2018 18:07:57 +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,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3EBA2B487 for ; Mon, 3 Dec 2018 18:07:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EC44F6B6A88; Mon, 3 Dec 2018 13:07:42 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id E73C36B6A89; Mon, 3 Dec 2018 13:07:42 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D69646B6A8A; Mon, 3 Dec 2018 13:07:42 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-oi1-f197.google.com (mail-oi1-f197.google.com [209.85.167.197]) by kanga.kvack.org (Postfix) with ESMTP id A96786B6A88 for ; Mon, 3 Dec 2018 13:07:42 -0500 (EST) Received: by mail-oi1-f197.google.com with SMTP id j13so8564864oii.8 for ; Mon, 03 Dec 2018 10:07:42 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=i8kqVEny1BxLFODzbCS4OoIldxl/VAf8AelIhGS7wlY=; b=Evb5EopcpoCj2AD7p7AzIPYBDUwOLX6ZuKaUo2LHtubdXaGjIMMQOG1xZ0C7mWB2md ld0r1h3dP4zoUsmLqXs6Crr9M1OVXX6QktW+37ECyv3rT/ayTOCnnZrjLL1Y5UIDX30K QRsWHXdWUPg5nUw1ny5E7O3h5DUGzKTkr4SmPupv5AwlDgy+IqbgXR9jOrlY5vdytnmf DBEAWV2rhvGasYH97VLLchrMgjH047+t16JsQflSfjbCpjyFX1GU9kHsocWjwbEqykho rqjM/dJvuZvdcQSiTx8H6xmNQu7dVi12Mb40YrIWl7Ghm+jkN0fZt9OIClNmUSxfrDxD M4Vw== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of james.morse@arm.com designates 217.140.101.70 as permitted sender) smtp.mailfrom=james.morse@arm.com X-Gm-Message-State: AA+aEWaL7MQlEum+c+2X6Ki5tPYGPdbwmGUL7dlY5S8NdTY9thdDMi+V RKrD3ZiKZxBusWsBWChwnPI0R4dKnQ/UgQKqfeECgyaM/Q0/qMtP3ob/NvLkbt7XscPn91H7i/u txs+dOUNV/gpZBfZVb+JwQsc5HfjRDBlXuoNlzyPPWyEa8MQTdKzx7IVlKC08Q8UsdA== X-Received: by 2002:a9d:2da2:: with SMTP id g31mr11323394otb.310.1543860462430; Mon, 03 Dec 2018 10:07:42 -0800 (PST) X-Google-Smtp-Source: AFSGD/XSKXDgHDyl0/fkq0mH3ToWvrnpoyGBCDol+g52eMIzg2s8J3Etib67V7MsYWSrVeZjaYgH X-Received: by 2002:a9d:2da2:: with SMTP id g31mr11323365otb.310.1543860461711; Mon, 03 Dec 2018 10:07:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543860461; cv=none; d=google.com; s=arc-20160816; b=h7FuEPBwYE2hg7UYq+UCQns3/i1uV62sP1IJfaU0zdh52UZbuq4nfuw97kxj6ZLsY4 818CzBkdjynNi/IvIHXDJxqz+5nql2aioa4TsbKSsSUsXa4p7VunYq2dUajw6vaU5Epj 5HlI09Cf+p3UFG/GVZeRIpjeAa1a+0l6upa8QitXypwgMkomDM0FO30viqoRus0f5aYH bwmFho/GWd3DzH9ZtqMG9wxTnmeoFqOEguV0ngxNEwckc8dl3yzhWFFquMZvAktqbVLc JOJ/F2P5V7dUsS+PmB+G2KJZlJte26iMVdunh1eKw/qMkeXlntl7H31COKn3QbDEpAzp S3yA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=i8kqVEny1BxLFODzbCS4OoIldxl/VAf8AelIhGS7wlY=; b=Z5LX54Xtb8TV2ftbY5hbYbE0Awa3qixV/9ykiS4fdXreUXsa+SjSjyLqbDXqvqQFkh cJB6GQnRcLvaAO+cuxmq3F5UlsCYUtyQzwEpFC0u/s4hQ1A/G/A2L8f6oflzEIHGBXJI btTDKvTMGvb6yIoIpvw0xiiGw8JCHKxj0kAX8qjOiwCYUHG8JVtFSmHtDyb0bFumWnD2 p21Jw3dLpo/BE7mwsTtzOy76RKbdwE/zJonf2+6BtcrM+ZwKr5QlSVsDXHtpQ/SzwJJu LH1XFmRPJUQDqjjUOaJQPaYY5CJX3hYG6Yjzw684L/bLFO10Q6orqQwsQNYMOcfZjJQw x47A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of james.morse@arm.com designates 217.140.101.70 as permitted sender) smtp.mailfrom=james.morse@arm.com Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com. [217.140.101.70]) by mx.google.com with ESMTP id y23si7283647otj.129.2018.12.03.10.07.41 for ; Mon, 03 Dec 2018 10:07:41 -0800 (PST) Received-SPF: pass (google.com: domain of james.morse@arm.com designates 217.140.101.70 as permitted sender) client-ip=217.140.101.70; Authentication-Results: mx.google.com; spf=pass (google.com: domain of james.morse@arm.com designates 217.140.101.70 as permitted sender) smtp.mailfrom=james.morse@arm.com 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 46A07169E; Mon, 3 Dec 2018 10:07:41 -0800 (PST) Received: from eglon.cambridge.arm.com (eglon.cambridge.arm.com [10.1.196.105]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 76E263F59C; Mon, 3 Dec 2018 10:07:38 -0800 (PST) From: James Morse To: linux-acpi@vger.kernel.org Cc: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, Borislav Petkov , Marc Zyngier , Christoffer Dall , Will Deacon , Catalin Marinas , Naoya Horiguchi , Rafael Wysocki , Len Brown , Tony Luck , Dongjiu Geng , Xie XiuQi , Fan Wu , James Morse Subject: [PATCH v7 18/25] ACPI / APEI: Split ghes_read_estatus() to allow a peek at the CPER length Date: Mon, 3 Dec 2018 18:06:06 +0000 Message-Id: <20181203180613.228133-19-james.morse@arm.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181203180613.228133-1-james.morse@arm.com> References: <20181203180613.228133-1-james.morse@arm.com> MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: 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. To provide this estatus buffer the caller must know the size of the records in advance, or always provide a worst-case sized buffer as happens today for the non-NMI notifications. 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 Changes since v6: * Additional buf_addr = 0 error handling * Moved checking out of peek-estatus * Reworded an error message so we can tell them apart --- drivers/acpi/apei/ghes.c | 59 ++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index b70f5fd962cc..07a12aac4c1a 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -277,12 +277,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 and returning its address, and header in estatus. */ +static int __ghes_peek_estatus(struct ghes *ghes, int fixmap_idx, + struct acpi_hest_generic_status *estatus, + u64 *buf_paddr) { struct acpi_hest_generic *g = ghes->generic; - u32 len; int rc; rc = apei_read(buf_paddr, &g->error_status_address); @@ -303,29 +303,64 @@ static int ghes_read_estatus(struct ghes *ghes, return -ENOENT; } - rc = -EIO; - len = cper_estatus_len(estatus); + return 0; +} + +/* Check the top-level record header has an appropriate size. */ +int __ghes_check_estatus(struct ghes *ghes, + struct acpi_hest_generic_status *estatus) +{ + u32 len = cper_estatus_len(estatus); + int rc = -EIO; + 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)) - goto err_read_block; rc = 0; err_read_block: if (rc) pr_warn_ratelimited(FW_WARN GHES_PFX - "Failed to read error status block!\n"); + "Invalid Error status block!\n"); 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)) { + pr_warn_ratelimited(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; + + rc = __ghes_peek_estatus(ghes, fixmap_idx, estatus, buf_paddr); + if (rc) + return rc; + + rc = __ghes_check_estatus(ghes, estatus); + if (rc) + return rc; + + return __ghes_read_estatus(estatus, *buf_paddr, + cper_estatus_len(estatus), fixmap_idx); +} + static void ghes_clear_estatus(struct acpi_hest_generic_status *estatus, u64 buf_paddr, int fixmap_idx) {