On 2021/6/17 17:57, LeoLiuoc wrote:在 2021/6/16 17:03, Xiongfeng Wang 写道:On 2021/6/4 17:36, LeoLiuoc wrote:When using ACPI device to create identity mapping, if the physical node of the ACPI device is a pci device, domain_1 will be created for these two devices. But if the pci device and other pci devices belong to another domain_2, this will happen conflict and destroy another domain. Such asI think it may be caused by a BIOS flaw. The pci device and the corresponding acpi device are both listed in Device Scope ? I'm not sure whether it's a flaw. Can we fix this by only modifying DMAR table ? Have we sent this patch to the mainline ? Thanks, XiongfengThis is not a problem reported by BIOS.In fact,some ACPI devices use the SID of the pci device to work. The BIOS only need to report the ACPI device in RMRR, but the reported SID belongs to a pci device.So there is a domain conflict.This patch increases the handing of domain conflicts. This patch is base on a previously submitted patch which has been received by openEuler-1.0-LTS(0f7d0c8b66a415734cbd2c8a7afc586c4a1d61cc).But the previous patch has not been received by the mainline,so this patch will not be submitted to the mainline.Could you share your DMAR and DSDT table ?
Please see the attachments.
BRs Leo
BRs LeoPCI devices under the PCIE-to-PCI bridge. Therefore, when the physical node of the ACPI device is a PCI device, this patch uses the PCI device to create the domain. In this way, there is only one domain. Signed-off-by: LeoLiu-oc <LeoLiu-oc@zhaoxin.com> --- drivers/iommu/intel-iommu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index e111e5d6d269..cf0dc4c80183 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2736,12 +2736,32 @@ static int domain_prepare_identity_map(struct device *dev, return iommu_domain_identity_map(domain, start, end); } +static struct device *acpi_dev_find_pci_dev(struct device *dev) +{ + struct acpi_device_physical_node *pn; + struct acpi_device *adev; + + if (dev->bus == &acpi_bus_type) { + adev = to_acpi_device(dev); + mutex_lock(&adev->physical_node_lock); + list_for_each_entry(pn, &adev->physical_node_list, node) { + if (dev_is_pci(pn->dev)) { + return pn->dev; + } + } + mutex_unlock(&adev->physical_node_lock); + } + + return dev; +} + static int iommu_prepare_identity_map(struct device *dev, unsigned long long start, unsigned long long end) { struct dmar_domain *domain; int ret; + dev = acpi_dev_find_pci_dev(dev); domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH); if (!domain)..