From patchwork Wed Oct 27 08:12:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuesong Chen X-Patchwork-Id: 12586609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54720C433FE for ; Wed, 27 Oct 2021 08:14:10 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 21C6E60F9D for ; Wed, 27 Oct 2021 08:14:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 21C6E60F9D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=7/yW4z3DjHbOxM2S8m9DKh1LTzWP+HbpjNYD+aS/dlA=; b=kSHlfJowCf2FLC 4oFBnYytDETHwG6zJMUOe6VBK15Gt/7xecxZphAXVAXCI5F5Qx/xl5fBkt+HBql7qFdgI3Pf3eghT AHLyEFfTvMgFC3vA8jxy8H5hHFV48X2DeIgFEj2xy40jGd3m8J6LGZubwYIgdbviP6U0jpgVc0w7t 8hufVXsOOi+fmc3gVt/QqKz033ej8AlQp7tEpFT9kOqDSlJROEzIGpdFN1j5U+yGt8DSdbsx30AwL iYSMc55PNVl0EMLOfFsbXmFeXo2eVHJekmh3Vhr6CscxwhbQtxCB/78AguN1yTWhQgFqdgNQfCw+v gT7U8GfCgwlZJLzqk2Yg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mfe3K-004HZf-Ct; Wed, 27 Oct 2021 08:12:54 +0000 Received: from out30-45.freemail.mail.aliyun.com ([115.124.30.45]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mfe3G-004HXR-HY for linux-arm-kernel@lists.infradead.org; Wed, 27 Oct 2021 08:12:52 +0000 X-Alimail-AntiSpam: AC=PASS; BC=-1|-1; BR=01201311R571e4; CH=green; DM=||false|; DS=||; FP=0|-1|-1|-1|0|-1|-1|-1; HT=e01e04394; MF=xuesong.chen@linux.alibaba.com; NM=1; PH=DS; RN=16; SR=0; TI=SMTPD_---0UtrwnR5_1635322365; Received: from localhost.localdomain(mailfrom:xuesong.chen@linux.alibaba.com fp:SMTPD_---0UtrwnR5_1635322365) by smtp.aliyun-inc.com(127.0.0.1); Wed, 27 Oct 2021 16:12:46 +0800 From: Xuesong Chen To: helgaas@kernel.org Cc: catalin.marinas@arm.com, lorenzo.pieralisi@arm.com, james.morse@arm.com, will@kernel.org, rafael@kernel.org, tony.luck@intel.com, bp@alien8.de, mingo@kernel.org, bhelgaas@google.com, linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, xuesong.chen@linux.alibaba.com Subject: [PATCH v4 2/4] ACPI: APEI: Filter the PCI MCFG address with an arch-agnostic method Date: Wed, 27 Oct 2021 16:12:40 +0800 Message-Id: <20211027081240.53588-1-xuesong.chen@linux.alibaba.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20211027081035.53370-1-xuesong.chen@linux.alibaba.com> References: <20211027081035.53370-1-xuesong.chen@linux.alibaba.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211027_011250_783792_0A265C47 X-CRM114-Status: GOOD ( 19.67 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The commit d91525eb8ee6 ("ACPI, EINJ: Enhance error injection tolerance level") fixes the issue that the ACPI/APEI can not access the PCI MCFG address on x86 platform, but this issue can also happen on other architectures, for instance, we got below error message on ARM64 platform: ... APEI: Can not request [mem 0x50100000-0x50100003] for APEI EINJ Trigger registers ... The above register range is within the MCFG area, because the PCI ECAM can access the configuration space in an atomic way in case of the hardware implementation of ECAM is correct, which means we don't need a mutual exclusion for the EINJ action, thus we can remove this register address region from the MCFG safely just like the x86 fix does. Since all the MCFG resources have been saved into the pci_mmcfg_list which is shared across different arches, thus we can filter the MCFG resources from the APEI by apei_resources_sub(...) in a more common arch-agnostic way, which will be beneficial to all the APEI-dependent platforms after that. Signed-off-by: Xuesong Chen --- arch/x86/pci/mmconfig-shared.c | 28 -------------------------- drivers/acpi/apei/apei-base.c | 45 ++++++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 0b961fe6..12f7d96 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -605,32 +605,6 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) return 0; } -#ifdef CONFIG_ACPI_APEI -extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size, - void *data), void *data); - -static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size, - void *data), void *data) -{ - struct pci_mmcfg_region *cfg; - int rc; - - if (list_empty(&pci_mmcfg_list)) - return 0; - - list_for_each_entry(cfg, &pci_mmcfg_list, list) { - rc = func(cfg->res.start, resource_size(&cfg->res), data); - if (rc) - return rc; - } - - return 0; -} -#define set_apei_filter() (arch_apei_filter_addr = pci_mmcfg_for_each_region) -#else -#define set_apei_filter() -#endif - static void __init __pci_mmcfg_init(int early) { pci_mmcfg_reject_broken(early); @@ -665,8 +639,6 @@ void __init pci_mmcfg_early_init(void) else acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); __pci_mmcfg_init(1); - - set_apei_filter(); } } diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index c7fdb12..daae75a 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -448,13 +449,34 @@ static int apei_get_nvs_resources(struct apei_resources *resources) return acpi_nvs_for_each_region(apei_get_res_callback, resources); } -int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size, - void *data), void *data); -static int apei_get_arch_resources(struct apei_resources *resources) +#ifdef CONFIG_PCI +extern struct list_head pci_mmcfg_list; +static int apei_filter_mcfg_addr(struct apei_resources *res, + struct apei_resources *mcfg_res) +{ + int rc = 0; + struct pci_mmcfg_region *cfg; + + if (list_empty(&pci_mmcfg_list)) + return 0; + + apei_resources_init(mcfg_res); + list_for_each_entry(cfg, &pci_mmcfg_list, list) { + rc = apei_res_add(&mcfg_res->iomem, cfg->res.start, resource_size(&cfg->res)); + if (rc) + return rc; + } + /* filter the mcfg resource from current APEI's */ + return apei_resources_sub(res, mcfg_res); +} +#else +static inline int apei_filter_mcfg_addr(struct apei_resources *res, + struct apei_resources *mcfg_res) { - return arch_apei_filter_addr(apei_get_res_callback, resources); + return 0; } +#endif /* * IO memory/port resource management mechanism is used to check @@ -486,15 +508,9 @@ int apei_resources_request(struct apei_resources *resources, if (rc) goto nvs_res_fini; - if (arch_apei_filter_addr) { - apei_resources_init(&arch_res); - rc = apei_get_arch_resources(&arch_res); - if (rc) - goto arch_res_fini; - rc = apei_resources_sub(resources, &arch_res); - if (rc) - goto arch_res_fini; - } + rc = apei_filter_mcfg_addr(resources, &arch_res); + if (rc) + goto arch_res_fini; rc = -EINVAL; list_for_each_entry(res, &resources->iomem, list) { @@ -544,8 +560,7 @@ int apei_resources_request(struct apei_resources *resources, release_mem_region(res->start, res->end - res->start); } arch_res_fini: - if (arch_apei_filter_addr) - apei_resources_fini(&arch_res); + apei_resources_fini(&arch_res); nvs_res_fini: apei_resources_fini(&nvs_resources); return rc;