Re: [PATCH v8 12/25] iommu/arm-smmu-v3-kvm: Probe SMMU HW
From: Nicolin Chen <hidden>
Date: 2026-09-23 01:44:15
Also in:
kvmarm, linux-iommu, lkml
On Tue, Sep 22, 2026 at 01:12:45PM +0000, Mostafa Saleh wrote:
quoted hunk ↗ jump to hunk
+++ b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3-hyp.h@@ -11,6 +11,9 @@ * * Other members are filled and used at runtime by the SMMU driver. * @base Virtual address of SMMU registers + * @oas PA size + * @pgsize_bitmap Supported page sizes + * @sid_bits Max number of SID bits supported */
Some of them belongs to one of the prior patches. And, if we are going to list them all, could we do in kdoc style?
quoted hunk ↗ jump to hunk
+++ b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c@@ -29,6 +29,47 @@ static void smmu_deinit_device(struct hyp_arm_smmu_v3_device *smmu) smmu->base = NULL; } +/* + * Mini-probe and validation for the hypervisor. + */ +static int smmu_probe(struct hyp_arm_smmu_v3_device *smmu) +{ + u32 reg; + + if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY)) + return -EINVAL;
Does this need to check IDR0.COHACC? If not, an inline note that explains why?
quoted hunk ↗ jump to hunk
+ + reg = arm_smmu_idr0_probe(smmu); + + if (!(FIELD_GET(IDR0_TTF, reg) & IDR0_TTF_AARCH64)) + return -ENXIO; + + if (!(smmu->features & (ARM_SMMU_FEAT_TT_LE | ARM_SMMU_FEAT_TT_BE))) + return -ENXIO; + + reg = readl_relaxed(smmu->base + ARM_SMMU_IDR1); + if (reg & (IDR1_TABLES_PRESET | IDR1_QUEUES_PRESET | IDR1_REL)) + return -EINVAL; + + smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg); + /* Follows the kernel logic */ + if (smmu->sid_bits <= STRTAB_SPLIT) + smmu->features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB;
The IDR1 reg guard and sid_bits can be shared with the main driver. Maybe add an arm_smmu_device_idr1_probe()?
quoted hunk ↗ jump to hunk
+ + arm_smmu_idr3_probe(smmu); + + arm_smmu_idr5_probe(smmu); + if (!smmu->oas) + smmu->oas = 48;
The truncation can be shared with the main driver too?
quoted hunk ↗ jump to hunk
@@ -43,8 +84,14 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu) return ret; smmu->base = (void __iomem *)haddr; + ret = smmu_probe(smmu); + if (ret) + goto out_ret; return 0; +out_ret: + smmu_deinit_device(smmu);
Nit: out_deinit Nicolin