
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBMHO0 CVE: NA -------------------------------- 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@huawei.com> Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com> Signed-off-by: lishusen <lishusen2@huawei.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 +++++++++++++++------ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 2 files changed, 17 insertions(+), 6 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 d8913d5246cb..7741aa24f2c3 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> @@ -2612,9 +2613,13 @@ static void arm_smmu_domain_free_paging(struct iommu_domain *domain) xa_erase(&arm_smmu_asid_xa, smmu_domain->cd.asid); mutex_unlock(&arm_smmu_asid_lock); } else { - struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg; - if (cfg->vmid) - ida_free(&smmu->vmid_map, cfg->vmid); + if (smmu_domain->iommufd_kvm) { + kvm_pinned_vmid_put(smmu_domain->iommufd_kvm); + } else { + struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg; + if (cfg->vmid) + ida_free(&smmu->vmid_map, cfg->vmid); + } } kfree(smmu_domain); @@ -2642,9 +2647,13 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_device *smmu, int vmid; struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg; - /* 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->iommufd_kvm) { + vmid = kvm_pinned_vmid_get(smmu_domain->iommufd_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; @@ -3386,6 +3395,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags, } smmu_domain->stage = ARM_SMMU_DOMAIN_S2; smmu_domain->nest_parent = true; + smmu_domain->iommufd_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 38d46098c668..8aa3a46edd6a 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -883,6 +883,7 @@ struct arm_smmu_domain { struct list_head node; struct kvm *kvm; #endif + struct kvm *iommufd_kvm; }; struct arm_smmu_nested_domain { -- 2.33.0