hw/arm/smmuv3-accel: Implement "auto" value for "ssidsize"
Allow accelerated SMMUv3 SSID size property to be derived from host IOMMU capabilities. Derive host values using IOMMU_GET_HW_INFO, retrieving SSID size from IDR1. When the auto SSID size is resolved to a non-zero value, PASID capability is advertised to the vIOMMU and accelerated use cases such as Shared Virtual Addressing (SVA) are supported. Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Signed-off-by: Nathan Chen <nathanc@nvidia.com> Tested-by: Eric Auger <eric.auger@redhat.com> Message-id: 20260608174900.2227340-7-nathanc@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Nathan Chen committed
Jun 8, 2026 at 10:48 UTC
13b941aaff48060ce0b5dca5a2b345a6dc25cb1c
2 files changed
+27
-12
hw/arm/smmuv3-accel.c
+15
-2
@@ -63,6 +63,11 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
63
FIELD_EX32(info->idr[3], IDR3, RIL));
64
}
65
66
+ if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
67
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
68
+ FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
69
+ }
70
+
71
accel->auto_finalised = true;
72
}
73
@@ -823,6 +828,13 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque,
828
}
829
}
830
831
+static inline bool smmuv3_pasid_supported(SMMUv3State *s)
832
+{
833
+ return s->ssidsize > SSID_SIZE_MODE_0 ||
834
+ (s->ssidsize == SSID_SIZE_MODE_AUTO &&
835
+ FIELD_EX32(s->idr[1], IDR1, SSIDSIZE));
836
+}
837
+
838
static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
839
{
840
/*
@@ -835,7 +847,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
847
SMMUState *bs = opaque;
848
SMMUv3State *s = ARM_SMMUV3(bs);
849
838
- if (s->ssidsize > SSID_SIZE_MODE_0) {
850
+ if (smmuv3_pasid_supported(s)) {
851
flags |= VIOMMU_FLAG_PASID_SUPPORTED;
852
}
853
return flags;
@@ -972,7 +984,8 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
984
smmuv3_accel_as_init(s);
985
986
if (s->ats == ON_OFF_AUTO_AUTO ||
975
- s->ril == ON_OFF_AUTO_AUTO) {
987
+ s->ril == ON_OFF_AUTO_AUTO ||
988
+ s->ssidsize == SSID_SIZE_MODE_AUTO) {
989
s->s_accel->auto_mode = true;
990
}
991
hw/arm/smmuv3.c
+12
-10
@@ -626,7 +626,10 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
626
}
627
628
/* Multiple context descriptors require SubstreamID support */
629
- if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
629
+ if ((s->ssidsize == SSID_SIZE_MODE_0 ||
630
+ (s->ssidsize == SSID_SIZE_MODE_AUTO &&
631
+ !FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) &&
632
+ STE_S1CDMAX(ste) != 0) {
633
qemu_log_mask(LOG_UNIMP,
634
"SMMUv3: multiple S1 context descriptors require SubstreamID support. "
635
"Configure ssidsize > 0 (requires accel=on)\n");
@@ -1965,10 +1968,6 @@ static void smmu_reset_exit(Object *obj, ResetType type)
1968
1969
static bool smmu_validate_property(SMMUv3State *s, Error **errp)
1970
{
1968
- if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
1969
- error_setg(errp, "ssidsize auto mode is not supported");
1970
- return false;
1971
- }
1971
if (s->oas != OAS_MODE_44 && s->oas != OAS_MODE_48) {
1972
error_setg(errp, "QEMU SMMUv3 model only implements 44 and 48 bit"
1973
"OAS; other OasMode values are not supported");
@@ -1989,7 +1988,8 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
1988
return false;
1989
}
1990
if (s->ssidsize > SSID_SIZE_MODE_0) {
1992
- error_setg(errp, "ssidsize can only be set if accel=on");
1991
+ error_setg(errp, "ssidsize can only be greater than 0 "
1992
+ "bits if accel=on");
1993
return false;
1994
}
1995
return true;
@@ -2175,11 +2175,13 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
2175
"are 44 or 48 bits. Defaults to 44 bits. oas=auto is not "
2176
"supported.");
2177
object_class_property_set_description(klass, "ssidsize",
2178
- "Number of bits used to represent SubstreamIDs (SSIDs). "
2178
+ "Set number of bits used to represent SubstreamIDs (SSIDs). "
2179
+ "Valid values are 0-20 and auto. Defaults to 0. "
2180
"A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
2180
- "Valid range is 0-20, where 0 disables SubstreamID support. "
2181
- "Defaults to 0. A value greater than 0 is required to enable "
2182
- "PASID support. ssidsize=auto is not supported.");
2181
+ "A value of 0 disables SubstreamID support. A value greater "
2182
+ "than 0 is required to enable PASID support."
2183
+ "Please ensure the value does not exceed the maximum "
2184
+ "SubstreamID size supported by the host platform.");
2185
}
2186
2187
static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,