Skip to content
/ linux Public

Commit ec494c0

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 a2376e9 commit ec494c0

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
@@ -1668,6 +1668,14 @@ static int pci_dma_configure(struct device *dev)
16681668
ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev));
16691669
}
16701670

1671+
/*
1672+
* Attempt to enable ACS regardless of capability because some Root
1673+
* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
1674+
* the standard ACS capability but still support ACS via those
1675+
* quirks.
1676+
*/
1677+
pci_enable_acs(to_pci_dev(dev));
1678+
16711679
pci_put_host_bridge_device(bridge);
16721680

16731681
if (!ret && !driver->driver_managed_dma) {

drivers/pci/pci.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ static void pci_std_enable_acs(struct pci_dev *dev)
986986
* pci_enable_acs - enable ACS if hardware support it
987987
* @dev: the PCI device
988988
*/
989-
static void pci_enable_acs(struct pci_dev *dev)
989+
void pci_enable_acs(struct pci_dev *dev)
990990
{
991991
if (!pci_acs_enable)
992992
goto disable_acs_redir;
@@ -3761,14 +3761,6 @@ bool pci_acs_path_enabled(struct pci_dev *start,
37613761
void pci_acs_init(struct pci_dev *dev)
37623762
{
37633763
dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
3764-
3765-
/*
3766-
* Attempt to enable ACS regardless of capability because some Root
3767-
* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
3768-
* the standard ACS capability but still support ACS via those
3769-
* quirks.
3770-
*/
3771-
pci_enable_acs(dev);
37723764
}
37733765

37743766
/**

drivers/pci/pci.h

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

557557
void pci_acs_init(struct pci_dev *dev);
558+
void pci_enable_acs(struct pci_dev *dev);
558559
#ifdef CONFIG_PCI_QUIRKS
559560
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
560561
int pci_dev_specific_enable_acs(struct pci_dev *dev);

0 commit comments

Comments
 (0)