@samitouri / QOSamiQemu / commits / ffded86bdd

hw/arm/smmuv3-accel: Change "ssidsize" property type to SsidSizeMode

Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode. The 'auto' value is not implemented, as this commit is meant to set the property to the correct type and avoid breaking JSON/QMP when the auto mode is introduced. A future patch will implement resolution of 'auto' value to match the host SMMUv3 SSIDSIZE value. The conversion of the "ssidsize" property type to OnOffAuto is an incompatible change for JSON/QMP when a uint8_t value is expected for "ssidsize", but this property is new in 11.0 and this patch is submitted as a fix to the property type. Fixes: b8c6f8a69d27 ("hw/arm/smmuv3-accel: Make SubstreamID support configurable") Tested-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Shameer Kolothum <skolothumtho@nvidia.com> Acked-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Nathan Chen <nathanc@nvidia.com> Message-id: 20260323182454.1416110-6-nathanc@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Nathan Chen committed Mar 24, 2026 at 14:02 UTC ffded86bdda6171fea1771199f3f0c9e0601029f
4 files changed +33 -13
hw/arm/smmuv3-accel.c
+21 -2
@@ -802,7 +802,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
802 SMMUState *bs = opaque;
803 SMMUv3State *s = ARM_SMMUV3(bs);
804
805 - if (s->ssidsize) {
805 + if (s->ssidsize > SSID_SIZE_MODE_0) {
806 flags |= VIOMMU_FLAG_PASID_SUPPORTED;
807 }
808 return flags;
@@ -817,6 +817,22 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
817 .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
818 };
819
820 +/*
821 + * This returns the value of a SsidSizeMode value offset by 1 to
822 + * account for the enum values offset by 1 from actual values.
823 + *
824 + * SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. so return 0
825 + * if SSID_SIZE_MODE_0 is passed as input, return 1 if
826 + * SSID_SIZE_MODE_1 is passed as input, etc.
827 + */
828 +static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
829 +{
830 + if (mode == SSID_SIZE_MODE_AUTO) {
831 + return 0;
832 + }
833 + return mode - 1;
834 +}
835 +
836 void smmuv3_accel_idr_override(SMMUv3State *s)
837 {
838 if (!s->accel) {
@@ -842,7 +858,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
858 * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
859 * has enabled it.
860 */
845 - s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
861 + if (s->ssidsize > SSID_SIZE_MODE_0) {
862 + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
863 + ssidsize_mode_to_value(s->ssidsize));
864 + }
865 }
866
867 /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
hw/arm/smmuv3.c
+10 -9
@@ -20,6 +20,7 @@
20 #include "qemu/bitops.h"
21 #include "hw/core/irq.h"
22 #include "hw/core/sysbus.h"
23 +#include "hw/core/qdev-properties-system.h"
24 #include "migration/blocker.h"
25 #include "migration/vmstate.h"
26 #include "hw/core/qdev-properties.h"
@@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
626 }
627
628 /* Multiple context descriptors require SubstreamID support */
628 - if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
629 + if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
630 qemu_log_mask(LOG_UNIMP,
631 "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
632 "Configure ssidsize > 0 (requires accel=on)\n");
@@ -1979,6 +1980,10 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
1980 error_setg(errp, "ril auto mode is not supported");
1981 return false;
1982 }
1983 + if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
1984 + error_setg(errp, "ssidsize auto mode is not supported");
1985 + return false;
1986 + }
1987
1988 if (!s->accel) {
1989 if (s->ril == ON_OFF_AUTO_OFF) {
@@ -1993,7 +1998,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
1998 error_setg(errp, "OAS must be 44 bits when accel=off");
1999 return false;
2000 }
1996 - if (s->ssidsize) {
2001 + if (s->ssidsize > SSID_SIZE_MODE_0) {
2002 error_setg(errp, "ssidsize can only be set if accel=on");
2003 return false;
2004 }
@@ -2011,11 +2016,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
2016 error_setg(errp, "OAS can only be set to 44 or 48 bits");
2017 return false;
2018 }
2014 - if (s->ssidsize > SMMU_SSID_MAX_BITS) {
2015 - error_setg(errp, "ssidsize must be in the range 0 to %d",
2016 - SMMU_SSID_MAX_BITS);
2017 - return false;
2018 - }
2019
2020 return true;
2021 }
@@ -2144,7 +2144,8 @@ static const Property smmuv3_properties[] = {
2144 DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
2145 DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
2146 DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
2147 - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
2147 + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
2148 + SSID_SIZE_MODE_0),
2149 };
2150
2151 static void smmuv3_instance_init(Object *obj)
@@ -2185,7 +2186,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
2186 "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
2187 "Valid range is 0-20, where 0 disables SubstreamID support. "
2188 "Defaults to 0. A value greater than 0 is required to enable "
2188 - "PASID support.");
2189 + "PASID support. ssidsize=auto is not supported.");
2190 }
2191
2192 static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
include/hw/arm/smmuv3-common.h
-1
@@ -311,7 +311,6 @@ REG32(IDR1, 0x4)
311 FIELD(IDR1, TABLES_PRESET, 30, 1)
312 FIELD(IDR1, ECMDQ, 31, 1)
313
314 -#define SMMU_SSID_MAX_BITS 20
314 #define SMMU_IDR1_SIDSIZE 16
315 #define SMMU_CMDQS 19
316 #define SMMU_EVENTQS 19
include/hw/arm/smmuv3.h
+2 -1
@@ -21,6 +21,7 @@
21
22 #include "hw/arm/smmu-common.h"
23 #include "qom/object.h"
24 +#include "qapi/qapi-types-misc-arm.h"
25
26 #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
27
@@ -72,7 +73,7 @@ struct SMMUv3State {
73 OnOffAuto ril;
74 OnOffAuto ats;
75 uint8_t oas;
75 - uint8_t ssidsize;
76 + SsidSizeMode ssidsize;
77 };
78
79 typedef enum {