[PATCH v8 12/25] iommu/arm-smmu-v3-kvm: Probe SMMU HW

Nicolin Chen nicolinc at nvidia.com
Tue Sep 22 18:43:44 PDT 2026


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



More information about the linux-arm-kernel mailing list