Re: 答复: [PATCH v3 2/2] iommu/vt-d:Add support for probing ACPI device in RMRR

From: Lu Baolu
Date: Tue Sep 01 2020 - 22:38:27 EST


On 9/1/20 5:13 PM, FelixCui-oc wrote:
hi  baolu ,

                   These ACPI devices can be retrieved from the kernel and there is no bound device driver .

So you have a hidden device (invisible to host kernel). But you need to
setup some identity mappings for this device, so that the firmware
could keep working, right?

The platform designs this by putting that range in the RMRR table and
expecting the OS kernel to setup identity mappings during boot.

Do I understand it right?

Best regards,
baolu



Best regards

Felixcui-oc

------------------------------------------------------------------------
*发件人:* Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
*发送时间:* 2020年9月1日 14:12:34
*收件人:* FelixCui-oc; Joerg Roedel; iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; David Woodhouse; Dan Carpenter; kbuild@xxxxxxxxxxxx
*抄送:* baolu.lu@xxxxxxxxxxxxxxx; CobeChen-oc; RaymondPang-oc; Tony W Wang-oc
*主题:* Re: [PATCH v3 2/2] iommu/vt-d:Add support for probing ACPI device in RMRR
Hi Felix,

On 8/27/20 6:02 PM, FelixCuioc wrote:
After acpi device in RMRR is detected,it is necessary
to establish a mapping for these devices.
In acpi_device_create_direct_mappings(),create a mapping
for the acpi device in RMRR.
Add a helper to achieve the acpi namespace device can
access the RMRR region.

Are those ACPI devices visible to kernel? If so, any device driver bound
for it?

Best regards,
baolu


Signed-off-by: FelixCuioc <FelixCui-oc@xxxxxxxxxxx>
---
   drivers/iommu/intel/iommu.c | 29 +++++++++++++++++++++++++++++
   drivers/iommu/iommu.c       |  6 ++++++
   include/linux/iommu.h       |  3 +++
   3 files changed, 38 insertions(+)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 208a91605288..51d7a5b18f41 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4799,6 +4799,21 @@ static int __init platform_optin_force_iommu(void)
        return 1;
   }
+static int acpi_device_create_direct_mappings(struct device *pn_dev, struct device *acpi_device)
+{
+     struct iommu_group *group;
+
+     acpi_device->bus->iommu_ops = &intel_iommu_ops;
+     group = iommu_group_get(pn_dev);
+     if (!group) {
+             pr_warn("ACPI name space devices create direct mappings wrong!\n");
+             return -EINVAL;
+     }
+     __acpi_device_create_direct_mappings(group, acpi_device);
+
+     return 0;
+}
+
   static int __init probe_acpi_namespace_devices(void)
   {
        struct dmar_drhd_unit *drhd;
@@ -4813,6 +4828,7 @@ static int __init probe_acpi_namespace_devices(void)
                        struct acpi_device_physical_node *pn;
                        struct iommu_group *group;
                        struct acpi_device *adev;
+                     struct device *pn_dev = NULL;
                        if (dev->bus != &acpi_bus_type)
                                continue;
@@ -4823,6 +4839,7 @@ static int __init probe_acpi_namespace_devices(void)
                                            &adev->physical_node_list, node) {
                                group = iommu_group_get(pn->dev);
                                if (group) {
+                                     pn_dev = pn->dev;
                                        iommu_group_put(group);
                                        continue;
                                }
@@ -4831,7 +4848,19 @@ static int __init probe_acpi_namespace_devices(void)
                                ret = iommu_probe_device(pn->dev);
                                if (ret)
                                        break;
+                             pn_dev = pn->dev;
+                     }
+                     if (!pn_dev) {
+                             dev->bus->iommu_ops = &intel_iommu_ops;
+                             ret = iommu_probe_device(dev);
+                             if (ret) {
+                                     pr_err("acpi_device probe fail! ret:%d\n", ret);
+                                     goto unlock;
+                             }
+                             goto unlock;
                        }
+                     ret = acpi_device_create_direct_mappings(pn_dev, dev);
+unlock:
                        mutex_unlock(&adev->physical_node_lock);
                        if (ret)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 609bd25bf154..4f714a2d5ef7 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -779,6 +779,12 @@ static bool iommu_is_attach_deferred(struct iommu_domain *domain,
        return false;
   }
+void  __acpi_device_create_direct_mappings(struct iommu_group *group, struct device *acpi_device)
+{
+     iommu_create_device_direct_mappings(group, acpi_device);
+}
+EXPORT_SYMBOL_GPL(__acpi_device_create_direct_mappings);
+
   /**
    * iommu_group_add_device - add a device to an iommu group
    * @group: the group into which to add the device (reference should be held)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index fee209efb756..9be134775886 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -514,6 +514,9 @@ extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr)
   extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
                              unsigned long iova, int flags);
+extern void __acpi_device_create_direct_mappings(struct iommu_group *group,
+                                             struct device *acpi_device);
+
   static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
   {
        if (domain->ops->flush_iotlb_all)