Skip to content
/ linux Public

Commit 8d3fc66

Browse files
Mani-SadhasivamSasha Levin
authored andcommitted
PCI: Enable ACS after configuring IOMMU for OF platforms
[ Upstream commit c41e2fb ] Platform, ACPI, or IOMMU drivers call pci_request_acs(), which sets 'pci_acs_enable' to request that ACS be enabled for any devices enumerated in the future. OF platforms called pci_enable_acs() for the first device before of_iommu_configure() called pci_request_acs(), so ACS was never enabled for that device (typically a Root Port). Call pci_enable_acs() later, from pci_dma_configure(), after of_dma_configure() has had a chance to call pci_request_acs(). Here's the call path, showing the move of pci_enable_acs() from pci_acs_init() to pci_dma_configure(), where it always happens after pci_request_acs(): pci_device_add pci_init_capabilities pci_acs_init - pci_enable_acs - if (pci_acs_enable) <-- previous test - ... device_add bus_notify(BUS_NOTIFY_ADD_DEVICE) iommu_bus_notifier iommu_probe_device iommu_init_device dev->bus->dma_configure pci_dma_configure # pci_bus_type.dma_configure of_dma_configure of_iommu_configure pci_request_acs pci_acs_enable = 1 <-- set + pci_enable_acs + if (pci_acs_enable) <-- new test + ... bus_probe_device device_initial_probe ... really_probe dev->bus->dma_configure pci_dma_configure # pci_bus_type.dma_configure ... pci_enable_acs Note that we will now call pci_enable_acs() twice for every device, first from the iommu_probe_device() path and again from the really_probe() path. Presumably that's not an issue since we also call dev->bus->dma_configure() twice. For the ACPI platforms, pci_request_acs() is called during ACPI initialization time itself, independent of the IOMMU framework. Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org> Link: https://patch.msgid.link/20260102-pci_acs-v3-1-72280b94d288@oss.qualcomm.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d60ed85 commit 8d3fc66

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

drivers/pci/pci-driver.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,14 @@ static int pci_dma_configure(struct device *dev)
16521652
ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev));
16531653
}
16541654

1655+
/*
1656+
* Attempt to enable ACS regardless of capability because some Root
1657+
* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
1658+
* the standard ACS capability but still support ACS via those
1659+
* quirks.
1660+
*/
1661+
pci_enable_acs(to_pci_dev(dev));
1662+
16551663
pci_put_host_bridge_device(bridge);
16561664

16571665
/* @drv may not be valid when we're called from the IOMMU layer */

drivers/pci/pci.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ static void pci_std_enable_acs(struct pci_dev *dev, struct pci_acs *caps)
10151015
* pci_enable_acs - enable ACS if hardware support it
10161016
* @dev: the PCI device
10171017
*/
1018-
static void pci_enable_acs(struct pci_dev *dev)
1018+
void pci_enable_acs(struct pci_dev *dev)
10191019
{
10201020
struct pci_acs caps;
10211021
bool enable_acs = false;
@@ -3677,14 +3677,6 @@ bool pci_acs_path_enabled(struct pci_dev *start,
36773677
void pci_acs_init(struct pci_dev *dev)
36783678
{
36793679
dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
3680-
3681-
/*
3682-
* Attempt to enable ACS regardless of capability because some Root
3683-
* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
3684-
* the standard ACS capability but still support ACS via those
3685-
* quirks.
3686-
*/
3687-
pci_enable_acs(dev);
36883680
}
36893681

36903682
void pci_rebar_init(struct pci_dev *pdev)

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
920920
}
921921

922922
void pci_acs_init(struct pci_dev *dev);
923+
void pci_enable_acs(struct pci_dev *dev);
923924
#ifdef CONFIG_PCI_QUIRKS
924925
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
925926
int pci_dev_specific_enable_acs(struct pci_dev *dev);

0 commit comments

Comments
 (0)