From patchwork Thu Dec 1 08:29:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Helgaas X-Patchwork-Id: 9455593 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5780260515 for ; Thu, 1 Dec 2016 08:39:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E42F2847C for ; Thu, 1 Dec 2016 08:39:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 41BBD2847F; Thu, 1 Dec 2016 08:39:09 +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=-6.4 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2ABA28402 for ; Thu, 1 Dec 2016 08:39:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755125AbcLAIjH (ORCPT ); Thu, 1 Dec 2016 03:39:07 -0500 Received: from mail.kernel.org ([198.145.29.136]:52258 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750775AbcLAIjG (ORCPT ); Thu, 1 Dec 2016 03:39:06 -0500 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3903D2037F; Thu, 1 Dec 2016 08:29:49 +0000 (UTC) Received: from localhost (unknown [69.71.4.155]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DE5F220375; Thu, 1 Dec 2016 08:29:47 +0000 (UTC) Subject: [PATCH v10 03/12] x86/PCI: Use acpi_resource_consumer() to search ACPI namespace for MMCFG From: Bjorn Helgaas To: linux-pci@vger.kernel.org Cc: Lorenzo Pieralisi , Gabriele Paoloni , "Rafael J. Wysocki" , Tomasz Nowicki , Duc Dang , Sinan Kaya , Christopher Covington , Dongdong Liu Date: Thu, 01 Dec 2016 02:29:46 -0600 Message-ID: <20161201082946.12247.69256.stgit@bhelgaas-glaptop.roam.corp.google.com> In-Reply-To: <20161201075131.12247.2211.stgit@bhelgaas-glaptop.roam.corp.google.com> References: <20161201075131.12247.2211.stgit@bhelgaas-glaptop.roam.corp.google.com> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bjorn Helgaas The static MCFG table tells us the base of MMCFG space, but it does not reserve the space -- the reservation should be done via a device in the ACPI namespace whose _CRS includes the MMCFG region. Replace find_mboard_resource(), which already searches for such a device, with the new acpi_resource_consumer() interface that does essentially the same thing. acpi_resource_consumer() is not as strict as find_mboard_resource() was: find_mboard_resource() only looks at PNP0C01 and PNP0C02 devices and the following _CRS descriptor types: ACPI_RESOURCE_TYPE_FIXED_MEMORY32 ACPI_RESOURCE_TYPE_ADDRESS32 ACPI_RESOURCE_TYPE_ADDRESS64 but acpi_resource_consumer() looks at *all* devices in the namespace and the following descriptor types: ACPI_RESOURCE_TYPE_MEMORY24 ACPI_RESOURCE_TYPE_MEMORY32 ACPI_RESOURCE_TYPE_FIXED_MEMORY32 ACPI_RESOURCE_TYPE_ADDRESS16 ACPI_RESOURCE_TYPE_ADDRESS32 ACPI_RESOURCE_TYPE_ADDRESS64 ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 I think it is correct to accept the larger set of descriptor types. Note 2 to Table 4-2 of the PCI Firmware spec r3.2 does suggest that the MMCFG region should be declared by a PNP0C02 device. I don't know why it calls out PNP0C02 specifically, unless it's related to the fact that the Consumer/Producer issues make it hard to use the PNP0A03 device itself. Signed-off-by: Bjorn Helgaas --- arch/x86/pci/mmconfig-shared.c | 69 +++++----------------------------------- 1 file changed, 9 insertions(+), 60 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index dd30b7e..f62ffe7 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -373,71 +373,20 @@ static int __init pci_mmcfg_check_hostbridge(void) return !list_empty(&pci_mmcfg_list); } -static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data) -{ - struct resource *mcfg_res = data; - struct acpi_resource_address64 address; - acpi_status status; - - if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { - struct acpi_resource_fixed_memory32 *fixmem32 = - &res->data.fixed_memory32; - if (!fixmem32) - return AE_OK; - if ((mcfg_res->start >= fixmem32->address) && - (mcfg_res->end < (fixmem32->address + - fixmem32->address_length))) { - mcfg_res->flags = 1; - return AE_CTRL_TERMINATE; - } - } - if ((res->type != ACPI_RESOURCE_TYPE_ADDRESS32) && - (res->type != ACPI_RESOURCE_TYPE_ADDRESS64)) - return AE_OK; - - status = acpi_resource_to_address64(res, &address); - if (ACPI_FAILURE(status) || - (address.address.address_length <= 0) || - (address.resource_type != ACPI_MEMORY_RANGE)) - return AE_OK; - - if ((mcfg_res->start >= address.address.minimum) && - (mcfg_res->end < (address.address.minimum + address.address.address_length))) { - mcfg_res->flags = 1; - return AE_CTRL_TERMINATE; - } - return AE_OK; -} - -static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl, - void *context, void **rv) -{ - struct resource *mcfg_res = context; - - acpi_walk_resources(handle, METHOD_NAME__CRS, - check_mcfg_resource, context); - - if (mcfg_res->flags) - return AE_CTRL_TERMINATE; - - return AE_OK; -} - static int is_acpi_reserved(u64 start, u64 end, unsigned not_used) { struct resource mcfg_res; + struct acpi_device *adev; mcfg_res.start = start; mcfg_res.end = end - 1; - mcfg_res.flags = 0; + mcfg_res.flags = IORESOURCE_MEM; - acpi_get_devices("PNP0C01", find_mboard_resource, &mcfg_res, NULL); - - if (!mcfg_res.flags) - acpi_get_devices("PNP0C02", find_mboard_resource, &mcfg_res, - NULL); + adev = acpi_resource_consumer(&mcfg_res); + if (adev) + return 1; - return mcfg_res.flags; + return 0; } typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); @@ -450,7 +399,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved, u64 size = resource_size(&cfg->res); u64 old_size = size; int num_buses; - char *method = with_e820 ? "E820" : "ACPI motherboard resources"; + char *method = with_e820 ? "E820" : "ACPI namespace"; while (!is_reserved(addr, addr + size, E820_RESERVED)) { size >>= 1; @@ -504,12 +453,12 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev, if (dev) dev_info(dev, FW_INFO "MMCONFIG at %pR not reserved in " - "ACPI motherboard resources\n", + "ACPI namespace\n", &cfg->res); else pr_info(FW_INFO PREFIX "MMCONFIG at %pR not reserved in " - "ACPI motherboard resources\n", + "ACPI namespace\n", &cfg->res); }