Hi Shameer, On 10/31/25 11:50 AM, 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. > > Reviewed-by: Jonathan Cameron <[email protected]> > Signed-off-by: Shameer Kolothum <[email protected]> > --- > hw/arm/smmuv3-accel.c | 23 ++++++++++++++++++++++- > hw/arm/smmuv3-internal.h | 1 + > hw/arm/smmuv3.c | 10 +++++++++- > include/hw/arm/smmuv3.h | 1 + > 4 files changed, 33 insertions(+), 2 deletions(-) > > diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c > index caa4a1d82d..1f206be8e4 100644 > --- a/hw/arm/smmuv3-accel.c > +++ b/hw/arm/smmuv3-accel.c > @@ -68,6 +68,12 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s, > error_setg(errp, "Host SMMUv3 SIDSIZE not compatible"); > return false; > } > + /* If user enables PASID support(pasid=on), QEMU sets SSIDSIZE to 16 */ > + if (FIELD_EX32(info->idr[1], IDR1, SSIDSIZE) < > + FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)) { > + error_setg(errp, "Host SMMUv3 SSIDSIZE not compatible"); > + return false; > + } > > /* User can disable QEMU SMMUv3 Range Invalidation support */ > if (FIELD_EX32(info->idr[3], IDR3, RIL) != > @@ -642,7 +648,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 = { > @@ -672,6 +685,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); > + } > } > > /* Based on SMUUv3 GBPA configuration, attach a corresponding HWPT */ > diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h > index cfc5897569..2e0d8d538b 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 c4d28a3786..e1140fe087 100644 > --- a/hw/arm/smmuv3.c > +++ b/hw/arm/smmuv3.c > @@ -611,7 +611,8 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, > } > } > > - if (STE_S1CDMAX(ste) != 0) { > + /* If pasid enabled, we report SSIDSIZE = 16 */ > + if (!FIELD_EX32(s->idr[1], IDR1, SSIDSIZE) && STE_S1CDMAX(ste) != 0) { can't you directly check s->pasid instead of decoding the IDR1? > qemu_log_mask(LOG_UNIMP, > "SMMUv3 does not support multiple context descriptors > yet\n"); you may suggest to add pasid= option then. > goto bad_ste; > @@ -1966,6 +1967,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 false; > } > > @@ -2098,6 +2103,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) > @@ -2133,6 +2139,8 @@ static void smmuv3_class_init(ObjectClass *klass, const > void *data) > object_class_property_set_description(klass, "oas", > "Specify Output Address Size (for accel =on). Supported values " > "are 44 or 48 bits. Defaults to 44 bits"); > + object_class_property_set_description(klass, "pasid", > + "Enable/disable PASID support (for accel=on)"); > } > > static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, > diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h > index e4226b66f3..ee0b5ed74f 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 { Otherwise looks good to me Reviewed-by: Eric Auger <[email protected]>
Eric
