From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from omzsmtpe01.verizonbusiness.com ([199.249.25.210]:29999 "EHLO omzsmtpe01.verizonbusiness.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754486AbdDDTc6 (ORCPT ); Tue, 4 Apr 2017 15:32:58 -0400 From: alexander.levin@verizon.com To: "gregkh@linuxfoundation.org" CC: "stable@vger.kernel.org" Subject: [PATCH for 4.9 18/98] arm64: PCI: Manage controller-specific data on per-controller basis Date: Tue, 4 Apr 2017 19:32:08 +0000 Message-ID: <20170404193158.19041-19-alexander.levin@verizon.com> References: <20170404193158.19041-1-alexander.levin@verizon.com> In-Reply-To: <20170404193158.19041-1-alexander.levin@verizon.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Tomasz Nowicki [ Upstream commit 093d24a204425f71f4f106b7e62c8df4b456e1cc ] Currently we use one shared global acpi_pci_root_ops structure to keep controller-specific ops. We pass its pointer to acpi_pci_root_create() and associate it with a host bridge instance for good. Such a design implies serious drawback. Any potential manipulation on the single system-wide acpi_pci_root_ops leads to kernel crash. The structure content is not really changing even across multiple host bridges creation; thus it was not an issue so far. In preparation for adding ECAM quirks mechanism (where controller-specific PCI ops may be different for each host bridge) allocate new acpi_pci_root_ops and fill in with data for each bridge. Now it is safe to have different controller-specific info. As a consequence free acpi_pci_root_ops when host bridge is released. No functional changes in this patch. Signed-off-by: Tomasz Nowicki Signed-off-by: Bjorn Helgaas Acked-by: Lorenzo Pieralisi Signed-off-by: Sasha Levin --- arch/arm64/kernel/pci.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index acf3872..95e0bb4 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -159,33 +159,36 @@ static void pci_acpi_generic_release_info(struct acpi= _pci_root_info *ci) =20 ri =3D container_of(ci, struct acpi_pci_generic_root_info, common); pci_ecam_free(ri->cfg); + kfree(ci->ops); kfree(ri); } =20 -static struct acpi_pci_root_ops acpi_pci_root_ops =3D { - .release_info =3D pci_acpi_generic_release_info, -}; - /* Interface called from ACPI code to setup PCI host controller */ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) { int node =3D acpi_get_node(root->device->handle); struct acpi_pci_generic_root_info *ri; struct pci_bus *bus, *child; + struct acpi_pci_root_ops *root_ops; =20 ri =3D kzalloc_node(sizeof(*ri), GFP_KERNEL, node); if (!ri) return NULL; =20 + root_ops =3D kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node); + if (!root_ops) + return NULL; + ri->cfg =3D pci_acpi_setup_ecam_mapping(root); if (!ri->cfg) { kfree(ri); + kfree(root_ops); return NULL; } =20 - acpi_pci_root_ops.pci_ops =3D &ri->cfg->ops->pci_ops; - bus =3D acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, - ri->cfg); + root_ops->release_info =3D pci_acpi_generic_release_info; + root_ops->pci_ops =3D &ri->cfg->ops->pci_ops; + bus =3D acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg); if (!bus) return NULL; =20 --=20 2.9.3