Re: [PATCH v8 12/25] iommu/arm-smmu-v3-kvm: Probe SMMU HW
From: Nicolin Chen
Date: Tue Sep 22 2026 - 21:47:42 EST
On Tue, Sep 22, 2026 at 01:12:45PM +0000, Mostafa Saleh wrote:
> +++ 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?
> +++ 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?
> +
> + 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()?
> +
> + 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?
> @@ -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