device_def_domain_type() determines the domain type a device could have and
it's called only during boot. But, to change the domain of a group through
sysfs, kernel has to call this function during runtime. Hence, add an
argument to the function which lets the function know if it's being called
at boot time or runtime.

Normally, device_def_domain_type() considers the value of command line
arguments like "intel_iommu=igfx_off" or "iommu=pt" to determine the domain
type of a device, but at runtime, user request should take higher priority
over command line arguments. Hence, use 'startup' argument to modify
device_def_domain_type() such that command line argument settings apply only at
boot time.

Cc: Christoph Hellwig <[email protected]>
Cc: Joerg Roedel <[email protected]>
Cc: Ashok Raj <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Lu Baolu <[email protected]>
Cc: Sohil Mehta <[email protected]>
Cc: Robin Murphy <[email protected]>
Cc: Jacob Pan <[email protected]>
Signed-off-by: Sai Praneeth Prakhya <[email protected]>
---
 drivers/iommu/intel-iommu.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ac4172c02244..54e82415e396 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2862,15 +2862,19 @@ static bool device_is_rmrr_locked(struct device *dev)
 /*
  * Return the required default domain type for a specific device.
  *
- * @dev: the device in query
- * @startup: true if this is during early boot
+ * @dev:       The device in query
+ * @startup:   Should command line arguments (E.g: igfx_off or iommu=pt) be
+ *             considered to decide the domain type of a device? Which is
+ *             'true' while booting but 'false' if the user requests kernel to
+ *             change the domain type by writing to
+ *             /sys/kernel/iommu_groups/<group_id>/type.
  *
  * Returns:
  *  - IOMMU_DOMAIN_DMA: device requires a dynamic mapping domain
  *  - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
  *  - 0: both identity and dynamic domains work for this device
  */
-static int device_def_domain_type(struct device *dev)
+static int device_def_domain_type(struct device *dev, bool startup)
 {
        if (dev_is_pci(dev)) {
                struct pci_dev *pdev = to_pci_dev(dev);
@@ -2888,8 +2892,11 @@ static int device_def_domain_type(struct device *dev)
                if ((iommu_identity_mapping & IDENTMAP_AZALIA) && 
IS_AZALIA(pdev))
                        return IOMMU_DOMAIN_IDENTITY;
 
-               if ((iommu_identity_mapping & IDENTMAP_GFX) && 
IS_GFX_DEVICE(pdev))
-                       return IOMMU_DOMAIN_IDENTITY;
+               if (startup) {
+                       if ((iommu_identity_mapping & IDENTMAP_GFX) &&
+                           IS_GFX_DEVICE(pdev))
+                               return IOMMU_DOMAIN_IDENTITY;
+               }
 
                /*
                 * We want to start off with all devices in the 1:1 domain, and
@@ -2920,8 +2927,12 @@ static int device_def_domain_type(struct device *dev)
                        return IOMMU_DOMAIN_DMA;
        }
 
-       return (iommu_identity_mapping & IDENTMAP_ALL) ?
-                       IOMMU_DOMAIN_IDENTITY : 0;
+       if (startup) {
+               if (iommu_identity_mapping & IDENTMAP_ALL)
+                       return IOMMU_DOMAIN_IDENTITY;
+       }
+
+       return 0;
 }
 
 static void intel_iommu_init_qi(struct intel_iommu *iommu)
@@ -5275,7 +5286,7 @@ static int intel_iommu_add_device(struct device *dev)
        domain = iommu_get_domain_for_dev(dev);
        dmar_domain = to_dmar_domain(domain);
        if (domain->type == IOMMU_DOMAIN_DMA) {
-               if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) {
+               if (device_def_domain_type(dev, true) == IOMMU_DOMAIN_IDENTITY) 
{
                        ret = iommu_request_dm_for_dev(dev);
                        if (ret) {
                                dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
@@ -5285,7 +5296,7 @@ static int intel_iommu_add_device(struct device *dev)
                        }
                }
        } else {
-               if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
+               if (device_def_domain_type(dev, true) == IOMMU_DOMAIN_DMA) {
                        ret = iommu_request_dma_domain_for_dev(dev);
                        if (ret) {
                                dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
-- 
2.19.1

_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to