Hi Shameer,
On 9/29/25 3:36 PM, Shameer Kolothum wrote:
> QEMU SMMUv3 currently forces SSID (Substream ID) to zero. One key use case
> for accelerated mode is Shared Virtual Addressing (SVA), which requires
> SSID support so the guest can maintain multiple context descriptors per
> substream ID.
>
> Provide an option for user to enable PASID support. A SSIDSIZE of 16
> is currently used as default.
>
> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 24 +++++++++++++++++++++++-
> hw/arm/smmuv3-internal.h | 1 +
> hw/arm/smmuv3.c | 8 +++++++-
> include/hw/arm/smmuv3.h | 1 +
> 4 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 283d36e6cd..0de9598dcb 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -79,6 +79,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> return false;
> }
>
> + /* If user enables PASID support(pasid=on), QEMU sets SSIDSIZE to 16 */
> + val = FIELD_EX32(info->idr[1], IDR1, SSIDSIZE);
> + if (val < FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)) {
> + error_setg(errp, "Host SUMMUv3 SSIDSIZE not compatible");
> + return false;
> + }
> +
> /* User can override QEMU SMMUv3 Range Invalidation support */
> val = FIELD_EX32(info->idr[3], IDR3, RIL);
> if (val != FIELD_EX32(s->idr[3], IDR3, RIL)) {
> @@ -635,7 +642,14 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
> * The real HW nested support should be reported from host SMMUv3 and if
> * it doesn't, the nesting parent allocation will fail anyway in VFIO core.
> */
> - return VIOMMU_FLAG_WANT_NESTING_PARENT;
> + uint64_t flags = VIOMMU_FLAG_WANT_NESTING_PARENT;
> + SMMUState *bs = opaque;
> + SMMUv3State *s = ARM_SMMUV3(bs);
> +
> + if (s->pasid) {
> + flags |= VIOMMU_FLAG_PASID_SUPPORTED;
> + }
> + return flags;
> }
>
> static const PCIIOMMUOps smmuv3_accel_ops = {
> @@ -664,6 +678,14 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> if (s->oas == 48) {
> s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
> }
> +
> + /*
> + * By default QEMU SMMUv3 has no PASID(SSID) support. Update IDR1 if user
> + * has enabled it.
> + */
> + if (s->pasid) {
> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, SMMU_IDR1_SSIDSIZE);
> + }
> }
>
> /*
> diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
> index 910a34e05b..38e9da245b 100644
> --- a/hw/arm/smmuv3-internal.h
> +++ b/hw/arm/smmuv3-internal.h
> @@ -81,6 +81,7 @@ REG32(IDR1, 0x4)
> FIELD(IDR1, ECMDQ, 31, 1)
>
> #define SMMU_IDR1_SIDSIZE 16
> +#define SMMU_IDR1_SSIDSIZE 16
> #define SMMU_CMDQS 19
> #define SMMU_EVENTQS 19
>
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 7c391ab711..f7a1635ec7 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -604,7 +604,8 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
> }
> }
>
> - if (STE_S1CDMAX(ste) != 0) {
> + /* If pasid enabled, we report SSIDSIZE = 16 */
why do we chose 16 and not a bigger value to avoid incompatibility?
worth a comment
> + if (!FIELD_EX32(s->idr[1], IDR1, SSIDSIZE) && STE_S1CDMAX(ste) != 0) {
> qemu_log_mask(LOG_UNIMP,
> "SMMUv3 does not support multiple context descriptors yet\n");
> goto bad_ste;
> @@ -1962,6 +1963,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "oas can only be set to 44 bits if accel=off");
> return false;
> }
> + if (s->pasid) {
> + error_setg(errp, "pasid can only be enabled if accel=on");
> + return false;
> + }
> return true;
> }
Just skimming though the SMMU spec, I don't see any handling for
STE.S1DSS anywhere
Also I would expect some C_BAD_SUBSTREAMID likely to be emitted?
Thanks
Eric
>
> @@ -2088,6 +2093,7 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> + DEFINE_PROP_BOOL("pasid", SMMUv3State, pasid, false),
> };
>
> static void smmuv3_instance_init(Object *obj)
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index d3788b2d85..3781b79fc8 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -71,6 +71,7 @@ struct SMMUv3State {
> bool ril;
> bool ats;
> uint8_t oas;
> + bool pasid;
> };
>
> typedef enum {