Re: [RFC PATCH] iommu/arm-smmu-v3: Allow nested attach for PCI bridges without vDEVICE
Dmitry Malkin <[email protected]>
| Newsgroups | dev.linux.lists.regressions,dev.linux.lists.iommu,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <PA1P190MB2557C62960471C0FD212D2F1DBDA2@PA1P190MB2557.EURP190.PROD.OUTLOOK.COM> |
Hi Praan,
> I agree that this is needed for old bridges. However, should this check
> actually live higher up in IOMMUFD? Instead of the SMMU driver deciding
> to bypass the error, what if iommufd itself intercepts the vDEVICE
> mapping failure during the group iteration? If IOMMUFD sees that the
> device lacking a vDEVICE is an IOMMU group alias/bridge, it could
> explicitly tell the underlying driver to proceed with a NULL vmaster?
>
> Also, regarding RID aliasing: while it's true the host bridge doesn't
> need a vDEVICE for its own host-consumed DMAs (like AER/PME), are we
> confident this won't break guest-injected events if the bridge aliases
> the downstream endpoint's traffic? For e.g. if the "real" endpoint's
> traffic is aliased to the bridge's RID and the bridge has no vmaster,
> won't we lose the ability to inject IO Page faults into the guest?
Thanks, both points make sense.
IOMMUFD currently cannot handle this alone. It calls
iommu_replace_group_handle(), while the generic IOMMU core performs the
per-device iteration. IOMMUFD receives only the final error and cannot
tell attach_dev() to proceed with a NULL driver-private vmaster for a
specific device without a generic API change.
For the bridge case, I suggest limiting the exception to PCIe port types
that pci_for_each_dma_alias() explicitly skips, avoiding bridges that may
alias a downstream RID:
static bool arm_smmu_is_nonaliasing_pcie_port(struct device *dev)
{
struct pci_dev *pdev;
if (!dev_is_pci(dev))
return false;
pdev = to_pci_dev(dev);
if (!pci_is_bridge(pdev) || !pci_is_pcie(pdev))
return false;
switch (pci_pcie_type(pdev)) {
case PCI_EXP_TYPE_ROOT_PORT:
case PCI_EXP_TYPE_UPSTREAM:
case PCI_EXP_TYPE_DOWNSTREAM:
return true;
default:
return false;
}
}
Thanks,
Dmitry