From: Nathan Chen <nathanc@nvidia.com>
Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
Setting 'auto' will use the default value, i.e. 0 in IDR1. A future
patch will implement resolution of 'auto' value to match the host SMMUv3
SSIDSIZE value.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
hw/arm/smmuv3.c | 16 ++++++----------
include/hw/arm/smmuv3.h | 3 ++-
3 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index 6f44fd3469..ab037df7ac 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -803,7 +803,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
SMMUState *bs = opaque;
SMMUv3State *s = ARM_SMMUV3(bs);
- if (s->ssidsize) {
+ if (s->ssidsize > SSID_SIZE_MODE_0) {
flags |= VIOMMU_FLAG_PASID_SUPPORTED;
}
return flags;
@@ -818,6 +818,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
.get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
};
+static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
+{
+ /* SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. */
+ /* SSID_SIZE_MODE_AUTO = 0 */
+ if (mode == SSID_SIZE_MODE_AUTO) {
+ return 0;
+ }
+ return mode - 1; /* Enum values are offset by 1 from actual values */
+}
+
void smmuv3_accel_idr_override(SMMUv3State *s)
{
if (!s->accel) {
@@ -847,7 +857,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
* By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
* has enabled it.
*/
- s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
+ if (s->ssidsize != SSID_SIZE_MODE_AUTO) {
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
+ ssidsize_mode_to_value(s->ssidsize));
+ }
}
/* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index acbd9d3ffe..8b0121c0ed 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -20,6 +20,7 @@
#include "qemu/bitops.h"
#include "hw/core/irq.h"
#include "hw/core/sysbus.h"
+#include "hw/core/qdev-properties-system.h"
#include "migration/blocker.h"
#include "migration/vmstate.h"
#include "hw/core/qdev-properties.h"
@@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
}
/* Multiple context descriptors require SubstreamID support */
- if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
+ if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
qemu_log_mask(LOG_UNIMP,
"SMMUv3: multiple S1 context descriptors require SubstreamID support. "
"Configure ssidsize > 0 (requires accel=on)\n");
@@ -1984,7 +1985,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
error_setg(errp, "OAS must be 44 bits when accel=off");
return false;
}
- if (s->ssidsize) {
+ if (s->ssidsize > SSID_SIZE_MODE_0) {
error_setg(errp, "ssidsize can only be set if accel=on");
return false;
}
@@ -2002,11 +2003,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
error_setg(errp, "OAS can only be set to 44 or 48 bits");
return false;
}
- if (s->ssidsize > SMMU_SSID_MAX_BITS) {
- error_setg(errp, "ssidsize must be in the range 0 to %d",
- SMMU_SSID_MAX_BITS);
- return false;
- }
return true;
}
@@ -2135,7 +2131,8 @@ static const Property smmuv3_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
- DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
+ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
+ SSID_SIZE_MODE_0),
};
static void smmuv3_instance_init(Object *obj)
@@ -2173,8 +2170,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
"Number of bits used to represent SubstreamIDs (SSIDs). "
"A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
"Valid range is 0-20, where 0 disables SubstreamID support. "
- "Defaults to 0. A value greater than 0 is required to enable "
- "PASID support.");
+ "A value greater than 0 is required to enable PASID support.");
}
static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index c35e599bbc..ddf472493d 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -21,6 +21,7 @@
#include "hw/arm/smmu-common.h"
#include "qom/object.h"
+#include "qapi/qapi-types-misc-arm.h"
#define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
@@ -72,7 +73,7 @@ struct SMMUv3State {
OnOffAuto ril;
OnOffAuto ats;
uint8_t oas;
- uint8_t ssidsize;
+ SsidSizeMode ssidsize;
};
typedef enum {
--
2.43.0
> -----Original Message-----
> From: Nathan Chen <nathanc@nvidia.com>
> Sent: 12 March 2026 21:03
> To: qemu-devel@nongnu.org; qemu-arm@nongnu.org
> Cc: Eric Auger <eric.auger@redhat.com>; Peter Maydell
> <peter.maydell@linaro.org>; Michael S . Tsirkin <mst@redhat.com>; Igor
> Mammedov <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>;
> Shannon Zhao <shannon.zhaosl@gmail.com>; Paolo Bonzini
> <pbonzini@redhat.com>; Daniel P . Berrangé <berrange@redhat.com>;
> Eduardo Habkost <eduardo@habkost.net>; Eric Blake <eblake@redhat.com>;
> Markus Armbruster <armbru@redhat.com>; Shameer Kolothum Thodi
> <skolothumtho@nvidia.com>; Nicolin Chen <nicolinc@nvidia.com>; Matt
> Ochs <mochs@nvidia.com>; Nathan Chen <nathanc@nvidia.com>
> Subject: [PATCH v2 5/8] hw/arm/smmuv3-accel: Change SSIDSIZE property to
> SsidSizeMode
>
> From: Nathan Chen <nathanc@nvidia.com>
>
> Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
> Setting 'auto' will use the default value, i.e. 0 in IDR1. A future
> patch will implement resolution of 'auto' value to match the host SMMUv3
> SSIDSIZE value.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
> hw/arm/smmuv3.c | 16 ++++++----------
> include/hw/arm/smmuv3.h | 3 ++-
> 3 files changed, 23 insertions(+), 13 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 6f44fd3469..ab037df7ac 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -803,7 +803,7 @@ static uint64_t
> smmuv3_accel_get_viommu_flags(void *opaque)
> SMMUState *bs = opaque;
> SMMUv3State *s = ARM_SMMUV3(bs);
>
> - if (s->ssidsize) {
> + if (s->ssidsize > SSID_SIZE_MODE_0) {
> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
> }
> return flags;
> @@ -818,6 +818,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
> .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
> };
>
> +static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
> +{
> + /* SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. */
> + /* SSID_SIZE_MODE_AUTO = 0 */
> + if (mode == SSID_SIZE_MODE_AUTO) {
> + return 0;
> + }
> + return mode - 1; /* Enum values are offset by 1 from actual values */
> +}
Maybe better to consolidate these comments and move them to a
function level block comment above.
Thanks,
Shameer
> +
> void smmuv3_accel_idr_override(SMMUv3State *s)
> {
> if (!s->accel) {
> @@ -847,7 +857,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if
> user
> * has enabled it.
> */
> - s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
> + if (s->ssidsize != SSID_SIZE_MODE_AUTO) {
> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
> + ssidsize_mode_to_value(s->ssidsize));
> + }
> }
>
> /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding
> HWPT */
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index acbd9d3ffe..8b0121c0ed 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -20,6 +20,7 @@
> #include "qemu/bitops.h"
> #include "hw/core/irq.h"
> #include "hw/core/sysbus.h"
> +#include "hw/core/qdev-properties-system.h"
> #include "migration/blocker.h"
> #include "migration/vmstate.h"
> #include "hw/core/qdev-properties.h"
> @@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s,
> SMMUTransCfg *cfg,
> }
>
> /* Multiple context descriptors require SubstreamID support */
> - if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
> + if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
> qemu_log_mask(LOG_UNIMP,
> "SMMUv3: multiple S1 context descriptors require SubstreamID
> support. "
> "Configure ssidsize > 0 (requires accel=on)\n");
> @@ -1984,7 +1985,7 @@ static bool
> smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "OAS must be 44 bits when accel=off");
> return false;
> }
> - if (s->ssidsize) {
> + if (s->ssidsize > SSID_SIZE_MODE_0) {
> error_setg(errp, "ssidsize can only be set if accel=on");
> return false;
> }
> @@ -2002,11 +2003,6 @@ static bool
> smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "OAS can only be set to 44 or 48 bits");
> return false;
> }
> - if (s->ssidsize > SMMU_SSID_MAX_BITS) {
> - error_setg(errp, "ssidsize must be in the range 0 to %d",
> - SMMU_SSID_MAX_BITS);
> - return false;
> - }
>
> return true;
> }
> @@ -2135,7 +2131,8 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril,
> ON_OFF_AUTO_ON),
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats,
> ON_OFF_AUTO_OFF),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
> + SSID_SIZE_MODE_0),
> };
>
> static void smmuv3_instance_init(Object *obj)
> @@ -2173,8 +2170,7 @@ static void smmuv3_class_init(ObjectClass *klass,
> const void *data)
> "Number of bits used to represent SubstreamIDs (SSIDs). "
> "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
> "Valid range is 0-20, where 0 disables SubstreamID support. "
> - "Defaults to 0. A value greater than 0 is required to enable "
> - "PASID support.");
> + "A value greater than 0 is required to enable PASID support.");
> }
>
> static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index c35e599bbc..ddf472493d 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -21,6 +21,7 @@
>
> #include "hw/arm/smmu-common.h"
> #include "qom/object.h"
> +#include "qapi/qapi-types-misc-arm.h"
>
> #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-
> memory-region"
>
> @@ -72,7 +73,7 @@ struct SMMUv3State {
> OnOffAuto ril;
> OnOffAuto ats;
> uint8_t oas;
> - uint8_t ssidsize;
> + SsidSizeMode ssidsize;
> };
>
> typedef enum {
> --
> 2.43.0
On 3/16/2026 1:56 AM, Shameer Kolothum Thodi wrote:
>
>> -----Original Message-----
>> From: Nathan Chen<nathanc@nvidia.com>
>> Sent: 12 March 2026 21:03
>> To:qemu-devel@nongnu.org;qemu-arm@nongnu.org
>> Cc: Eric Auger<eric.auger@redhat.com>; Peter Maydell
>> <peter.maydell@linaro.org>; Michael S . Tsirkin<mst@redhat.com>; Igor
>> Mammedov<imammedo@redhat.com>; Ani Sinha<anisinha@redhat.com>;
>> Shannon Zhao<shannon.zhaosl@gmail.com>; Paolo Bonzini
>> <pbonzini@redhat.com>; Daniel P . Berrangé<berrange@redhat.com>;
>> Eduardo Habkost<eduardo@habkost.net>; Eric Blake<eblake@redhat.com>;
>> Markus Armbruster<armbru@redhat.com>; Shameer Kolothum Thodi
>> <skolothumtho@nvidia.com>; Nicolin Chen<nicolinc@nvidia.com>; Matt
>> Ochs<mochs@nvidia.com>; Nathan Chen<nathanc@nvidia.com>
>> Subject: [PATCH v2 5/8] hw/arm/smmuv3-accel: Change SSIDSIZE property to
>> SsidSizeMode
>>
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
>> Setting 'auto' will use the default value, i.e. 0 in IDR1. A future
>> patch will implement resolution of 'auto' value to match the host SMMUv3
>> SSIDSIZE value.
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
>> hw/arm/smmuv3.c | 16 ++++++----------
>> include/hw/arm/smmuv3.h | 3 ++-
>> 3 files changed, 23 insertions(+), 13 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 6f44fd3469..ab037df7ac 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -803,7 +803,7 @@ static uint64_t
>> smmuv3_accel_get_viommu_flags(void *opaque)
>> SMMUState *bs = opaque;
>> SMMUv3State *s = ARM_SMMUV3(bs);
>>
>> - if (s->ssidsize) {
>> + if (s->ssidsize > SSID_SIZE_MODE_0) {
>> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
>> }
>> return flags;
>> @@ -818,6 +818,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
>> .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
>> };
>>
>> +static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
>> +{
>> + /* SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. */
>> + /* SSID_SIZE_MODE_AUTO = 0 */
>> + if (mode == SSID_SIZE_MODE_AUTO) {
>> + return 0;
>> + }
>> + return mode - 1; /* Enum values are offset by 1 from actual values */
>> +}
> Maybe better to consolidate these comments and move them to a
> function level block comment above.
Yes, I will move it above and include more details about the function
implementation in the block comment.
Thanks,
Nathan
On 3/12/26 10:03 PM, Nathan Chen wrote:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
> Setting 'auto' will use the default value, i.e. 0 in IDR1. A future
> patch will implement resolution of 'auto' value to match the host SMMUv3
> SSIDSIZE value.
At the moment we need to reject auto setting as it is not supported
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
> hw/arm/smmuv3.c | 16 ++++++----------
> include/hw/arm/smmuv3.h | 3 ++-
> 3 files changed, 23 insertions(+), 13 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 6f44fd3469..ab037df7ac 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -803,7 +803,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
> SMMUState *bs = opaque;
> SMMUv3State *s = ARM_SMMUV3(bs);
>
> - if (s->ssidsize) {
> + if (s->ssidsize > SSID_SIZE_MODE_0) {
> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
> }
> return flags;
> @@ -818,6 +818,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
> .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
> };
>
> +static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
> +{
> + /* SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. */
> + /* SSID_SIZE_MODE_AUTO = 0 */
> + if (mode == SSID_SIZE_MODE_AUTO) {
> + return 0;
> + }
> + return mode - 1; /* Enum values are offset by 1 from actual values */
> +}
> +
> void smmuv3_accel_idr_override(SMMUv3State *s)
> {
> if (!s->accel) {
> @@ -847,7 +857,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
> * has enabled it.
> */
> - s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
> + if (s->ssidsize != SSID_SIZE_MODE_AUTO) {
> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
> + ssidsize_mode_to_value(s->ssidsize));
> + }
> }
>
> /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index acbd9d3ffe..8b0121c0ed 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -20,6 +20,7 @@
> #include "qemu/bitops.h"
> #include "hw/core/irq.h"
> #include "hw/core/sysbus.h"
> +#include "hw/core/qdev-properties-system.h"
> #include "migration/blocker.h"
> #include "migration/vmstate.h"
> #include "hw/core/qdev-properties.h"
> @@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
> }
>
> /* Multiple context descriptors require SubstreamID support */
> - if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
> + if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
> qemu_log_mask(LOG_UNIMP,
> "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
> "Configure ssidsize > 0 (requires accel=on)\n");
> @@ -1984,7 +1985,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "OAS must be 44 bits when accel=off");
> return false;
> }
> - if (s->ssidsize) {
> + if (s->ssidsize > SSID_SIZE_MODE_0) {
> error_setg(errp, "ssidsize can only be set if accel=on");
> return false;
> }
> @@ -2002,11 +2003,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "OAS can only be set to 44 or 48 bits");
> return false;
> }
> - if (s->ssidsize > SMMU_SSID_MAX_BITS) {
> - error_setg(errp, "ssidsize must be in the range 0 to %d",
> - SMMU_SSID_MAX_BITS);
> - return false;
> - }
>
> return true;
> }
> @@ -2135,7 +2131,8 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
> + SSID_SIZE_MODE_0),
> };
>
> static void smmuv3_instance_init(Object *obj)
> @@ -2173,8 +2170,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
> "Number of bits used to represent SubstreamIDs (SSIDs). "
> "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
> "Valid range is 0-20, where 0 disables SubstreamID support. "
> - "Defaults to 0. A value greater than 0 is required to enable "
> - "PASID support.");
> + "A value greater than 0 is required to enable PASID support.");
Why removing "Defaults to 0"?
> }
>
> static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index c35e599bbc..ddf472493d 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -21,6 +21,7 @@
>
> #include "hw/arm/smmu-common.h"
> #include "qom/object.h"
> +#include "qapi/qapi-types-misc-arm.h"
>
> #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
>
> @@ -72,7 +73,7 @@ struct SMMUv3State {
> OnOffAuto ril;
> OnOffAuto ats;
> uint8_t oas;
> - uint8_t ssidsize;
> + SsidSizeMode ssidsize;
> };
>
> typedef enum {
Thanks
Eric
On 3/16/2026 12:50 AM, Eric Auger wrote:
> On 3/12/26 10:03 PM, Nathan Chen wrote:
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Change accel SMMUv3 SSIDSIZE property from uint8_t to SsidSizeMode.
>> Setting 'auto' will use the default value, i.e. 0 in IDR1. A future
>> patch will implement resolution of 'auto' value to match the host SMMUv3
>> SSIDSIZE value.
> At the moment we need to reject auto setting as it is not supported
>
I will enforce rejecting auto setting for this and the other properties
in the next refresh.
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 17 +++++++++++++++--
>> hw/arm/smmuv3.c | 16 ++++++----------
>> include/hw/arm/smmuv3.h | 3 ++-
>> 3 files changed, 23 insertions(+), 13 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 6f44fd3469..ab037df7ac 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -803,7 +803,7 @@ static uint64_t smmuv3_accel_get_viommu_flags(void *opaque)
>> SMMUState *bs = opaque;
>> SMMUv3State *s = ARM_SMMUV3(bs);
>>
>> - if (s->ssidsize) {
>> + if (s->ssidsize > SSID_SIZE_MODE_0) {
>> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
>> }
>> return flags;
>> @@ -818,6 +818,16 @@ static const PCIIOMMUOps smmuv3_accel_ops = {
>> .get_msi_direct_gpa = smmuv3_accel_get_msi_gpa,
>> };
>>
>> +static uint8_t ssidsize_mode_to_value(SsidSizeMode mode)
>> +{
>> + /* SSID_SIZE_MODE_0 = 1, SSID_SIZE_MODE_1 = 2, etc. */
>> + /* SSID_SIZE_MODE_AUTO = 0 */
>> + if (mode == SSID_SIZE_MODE_AUTO) {
>> + return 0;
>> + }
>> + return mode - 1; /* Enum values are offset by 1 from actual values */
>> +}
>> +
>> void smmuv3_accel_idr_override(SMMUv3State *s)
>> {
>> if (!s->accel) {
>> @@ -847,7 +857,10 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>> * By default QEMU SMMUv3 has no SubstreamID support. Update IDR1 if user
>> * has enabled it.
>> */
>> - s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, s->ssidsize);
>> + if (s->ssidsize != SSID_SIZE_MODE_AUTO) {
>> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
>> + ssidsize_mode_to_value(s->ssidsize));
>> + }
>> }
>>
>> /* Based on SMUUv3 GPBA.ABORT configuration, attach a corresponding HWPT */
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index acbd9d3ffe..8b0121c0ed 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -20,6 +20,7 @@
>> #include "qemu/bitops.h"
>> #include "hw/core/irq.h"
>> #include "hw/core/sysbus.h"
>> +#include "hw/core/qdev-properties-system.h"
>> #include "migration/blocker.h"
>> #include "migration/vmstate.h"
>> #include "hw/core/qdev-properties.h"
>> @@ -625,7 +626,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
>> }
>>
>> /* Multiple context descriptors require SubstreamID support */
>> - if (!s->ssidsize && STE_S1CDMAX(ste) != 0) {
>> + if (s->ssidsize == SSID_SIZE_MODE_0 && STE_S1CDMAX(ste) != 0) {
>> qemu_log_mask(LOG_UNIMP,
>> "SMMUv3: multiple S1 context descriptors require SubstreamID support. "
>> "Configure ssidsize > 0 (requires accel=on)\n");
>> @@ -1984,7 +1985,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "OAS must be 44 bits when accel=off");
>> return false;
>> }
>> - if (s->ssidsize) {
>> + if (s->ssidsize > SSID_SIZE_MODE_0) {
>> error_setg(errp, "ssidsize can only be set if accel=on");
>> return false;
>> }
>> @@ -2002,11 +2003,6 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "OAS can only be set to 44 or 48 bits");
>> return false;
>> }
>> - if (s->ssidsize > SMMU_SSID_MAX_BITS) {
>> - error_setg(errp, "ssidsize must be in the range 0 to %d",
>> - SMMU_SSID_MAX_BITS);
>> - return false;
>> - }
>>
>> return true;
>> }
>> @@ -2135,7 +2131,8 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_ON),
>> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_OFF),
>> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
>> - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
>> + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
>> + SSID_SIZE_MODE_0),
>> };
>>
>> static void smmuv3_instance_init(Object *obj)
>> @@ -2173,8 +2170,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
>> "Number of bits used to represent SubstreamIDs (SSIDs). "
>> "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
>> "Valid range is 0-20, where 0 disables SubstreamID support. "
>> - "Defaults to 0. A value greater than 0 is required to enable "
>> - "PASID support.");
>> + "A value greater than 0 is required to enable PASID support.");
> Why removing "Defaults to 0"?
This was left over from the v1 RFC. I will fix this in the next refresh.
Thanks,
Nathan
© 2016 - 2026 Red Hat, Inc.