[RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
Shameer Kolothum
shameerali.kolothum.thodi at huawei.com
Thu Feb 8 07:18:36 PST 2024
If kvm is available make use of kvm pinned VMID interfaces to
set the s2 stage VMID for nested domains.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++-----
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 ++
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b41d77787a2f..18e3e04b50f4 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/io-pgtable.h>
#include <linux/iopoll.h>
+#include <linux/kvm_host.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of.h>
@@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct arm_smmu_device *smmu,
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
int vmid;
- /* Reserve VMID 0 for stage-2 bypass STEs */
- vmid = ida_alloc_range(&smmu->vmid_map, 1,
- (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
+ if (smmu_domain->kvm) {
+ vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
+ } else {
+ /* Reserve VMID 0 for stage-2 bypass STEs */
+ vmid = ida_alloc_range(&smmu->vmid_map, 1,
+ (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
+ }
if (vmid < 0)
return vmid;
smmu_domain->vmid = vmid;
@@ -2431,7 +2436,10 @@ void arm_smmu_domain_free_id(struct arm_smmu_domain *smmu_domain)
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2 &&
smmu_domain->vmid) {
arm_smmu_tlb_inv_all_s2(smmu_domain);
- ida_free(&smmu->vmid_map, smmu_domain->vmid);
+ if (smmu_domain->kvm)
+ kvm_pinned_vmid_put(smmu_domain->kvm);
+ else
+ ida_free(&smmu->vmid_map, smmu_domain->vmid);
}
}
@@ -3217,7 +3225,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
goto err_free;
}
smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
- smmu_domain->nesting_parent = true;
+ smmu_domain->kvm = kvm;
}
smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 45bcd72fcda4..7d732ea2a6ee 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -758,6 +758,8 @@ struct arm_smmu_domain {
struct mmu_notifier mmu_notifier;
bool btm_invalidation : 1;
bool nesting_parent : 1;
+
+ struct kvm *kvm;
};
struct arm_smmu_nested_domain {
--
2.34.1
More information about the linux-arm-kernel
mailing list