On Thu, May 20, 2021 at 2:28 AM Wang Xingang <wangxingang5@xxxxxxxxxx> wrote: > > From: Xingang Wang <wangxingang5@xxxxxxxxxx> > > When booting with devicetree, the pci_request_acs() is called after the > enumeration and initialization of PCI devices, thus the ACS is not > enabled. And ACS should be enabled when IOMMU is detected for the > PCI host bridge, so add check for IOMMU before probe of PCI host and call > pci_request_acs() to make sure ACS will be enabled when enumerating PCI > devices. > > Fixes: 6bf6c24720d33 ("iommu/of: Request ACS from the PCI core when > configuring IOMMU linkage") > Signed-off-by: Xingang Wang <wangxingang5@xxxxxxxxxx> > --- > drivers/iommu/of_iommu.c | 1 - > drivers/pci/controller/pci-host-common.c | 17 +++++++++++++++++ > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c > index a9d2df001149..54a14da242cc 100644 > --- a/drivers/iommu/of_iommu.c > +++ b/drivers/iommu/of_iommu.c > @@ -205,7 +205,6 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, > .np = master_np, > }; > > - pci_request_acs(); > err = pci_for_each_dma_alias(to_pci_dev(dev), > of_pci_iommu_init, &info); > } else { > diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c > index d3924a44db02..5904ad0bd9ae 100644 > --- a/drivers/pci/controller/pci-host-common.c > +++ b/drivers/pci/controller/pci-host-common.c This file is generally only for ECAM compliant hosts. Are those the only hosts we need to support this? From the looks of dts files with iommu-map, that would be dropping support in lots of cases. Perhaps in devm_of_pci_bridge_init() or one of the functions it calls is the better place. > @@ -49,6 +49,21 @@ static struct pci_config_window *gen_pci_init(struct device *dev, > return cfg; > } > > +static void pci_host_enable_acs(struct pci_host_bridge *bridge) > +{ > + struct device_node *np = bridge->dev.parent->of_node; > + static bool acs_enabled; > + > + if (!np || acs_enabled) > + return; > + > + /* Detect IOMMU and make sure ACS will be enabled */ > + if (of_property_read_bool(np, "iommu-map")) { > + acs_enabled = true; > + pci_request_acs(); Given this function just sets a variable, I don't think you need the static acs_enabled here. > + } > +} > + > int pci_host_common_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > @@ -81,6 +96,8 @@ int pci_host_common_probe(struct platform_device *pdev) > bridge->ops = (struct pci_ops *)&ops->pci_ops; > bridge->msi_domain = true; > > + pci_host_enable_acs(bridge); > + > return pci_host_probe(bridge); > } > EXPORT_SYMBOL_GPL(pci_host_common_probe); > -- > 2.19.1 >