* [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties
@ 2026-03-09 19:21 Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
` (8 more replies)
0 siblings, 9 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
Hi,
This series introduces support for specifying 'auto' for arm-smmuv3
accelerated mode's ATS, RIL, SSIDSIZE, and OAS feature properties.
When set to 'auto', these feature values are derived directly from
host IOMMU capabilities, avoiding the need for management layers to
introspect host settings.
Accelerated SMMUv3 Address Translation Services support is derived
from IDR0, Range Invalidation support is derived from IDR3, Substream
ID size is derived from IDR1, and output address space is derived from
IDR5.
Additionally, an OnOffAuto "ats" property is added for vfio-pci devices,
where setting 'auto' detects the per-device presence of
IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED from the kernel, and the ATS cap can
be advertised or hidden by setting 'on' or 'off'. This is dependent
on Shameer's recent kernel series for reporting effective ATS support
status [0].
The default values are set to 'auto' for all properties.
A complete branch can be found here:
https://github.com/NathanChenNVIDIA/qemu/tree/smmuv3-accel-auto
Please take a look and let me know your feedback.
Thanks,
Nathan
Example usage:
qemu-system-aarch64 \
-object iommufd,id=iommufd0 \
-machine virt,accel=kvm,gic-version=3,ras=on,highmem-mmio-size=4T \
-cpu host -smp cpus=4 -m size=16G -nographic \
-object memory-backend-ram,size=16G,id=m0 \
-numa node,memdev=m0,cpus=0-3,nodeid=0 \
-numa node,nodeid=1 -numa node,nodeid=2 -numa node,nodeid=3 -numa node,nodeid=4 \
-numa node,nodeid=5 -numa node,nodeid=6 -numa node,nodeid=7 -numa node,nodeid=8 \
-device pxb-pcie,id=pcie.1,bus_nr=1,bus=pcie.0,numa_node=0 \
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1,accel=on,ats=auto,ssidsize=auto,ril=auto,oas=auto \
-device pcie-root-port,id=pcie.port1,bus=pcie.1,chassis=1,io-reserve=0 \
-device vfio-pci-nohotplug,host=0009:06:00.0,bus=pcie.port1,rombar=0,id=dev0,iommufd=iommufd0,ats=auto \
-object acpi-generic-initiator,id=gi0,pci-dev=dev0,node=1 \
-object acpi-generic-initiator,id=gi1,pci-dev=dev0,node=2 \
-object acpi-generic-initiator,id=gi2,pci-dev=dev0,node=3 \
-object acpi-generic-initiator,id=gi3,pci-dev=dev0,node=4 \
-object acpi-generic-initiator,id=gi4,pci-dev=dev0,node=5 \
-object acpi-generic-initiator,id=gi5,pci-dev=dev0,node=6 \
-object acpi-generic-initiator,id=gi6,pci-dev=dev0,node=7 \
-object acpi-generic-initiator,id=gi7,pci-dev=dev0,node=8 \
-bios /usr/share/AAVMF/AAVMF_CODE.fd \
-device nvme,drive=nvme0,serial=deadbeaf1,bus=pcie.0 \
-drive file=/var/lib/libvirt/images/guest.qcow2,index=0,media=disk,format=qcow2,if=none,id=nvme0 \
-device e1000,romfile=/usr/local/share/qemu/efi-e1000.rom,netdev=net0,bus=pcie.0 \
-netdev user,id=net0,hostfwd=tcp::5558-:22,hostfwd=tcp::5586-:5586
The properties may also be omitted as they are set to auto by default:
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1,accel=on \
-device vfio-pci-nohotplug,host=0009:06:00.0,bus=pcie.port1,rombar=0,id=dev0,iommufd=iommufd0 \
Testing:
Basic sanity testing was performed on an NVIDIA Grace platform with GPU
device assignment and running CUDA test apps on the guest. Observed the
feature properties being set based on host IOMMU capabilities and the
ATS capability for a vfio-pci device reported based on what was reported
from the host. Additional testing and feedback are welcome.
[0] https://lore.kernel.org/all/20260303150348.233997-1-skolothumtho@nvidia.com/#r
Nathan Chen (8):
hw/arm/smmuv3-accel: Add helper for resolving auto parameters
hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
vfio/pci: Add ats property and mask ATS cap when not exposed
hw/arm/smmuv3-accel: Introduce _AUTO support for RIL
qdev: Add a SsidSizeMode property
hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size
qdev: Add an OasMode property
hw/arm/smmuv3-accel: Introduce _AUTO support for OAS
backends/iommufd.c | 15 +++
hw/arm/smmuv3-accel.c | 118 ++++++++++++++++++++---
hw/arm/smmuv3-accel.h | 2 +
hw/arm/smmuv3.c | 43 +++++----
hw/arm/virt-acpi-build.c | 2 +-
hw/core/qdev-properties-system.c | 27 ++++++
hw/vfio/pci.c | 63 ++++++++++++
hw/vfio/pci.h | 1 +
include/hw/arm/smmuv3.h | 9 +-
include/hw/core/qdev-properties-system.h | 6 ++
include/system/host_iommu_device.h | 10 ++
qapi/misc-arm.json | 31 ++++++
qapi/pragma.json | 1 +
13 files changed, 292 insertions(+), 36 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 49+ messages in thread
* [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:00 ` Markus Armbruster
2026-03-10 7:42 ` Cédric Le Goater
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
` (7 subsequent siblings)
8 siblings, 2 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen, Shameer Kolothum
From: Nathan Chen <nathanc@nvidia.com>
Introduce smmuv3_accel_auto_finalise() to resolve properties
that are set to 'auto' for accelerated SMMUv3. This helper
function allows properties such as ATS, RIL, SSIDSIZE, and OAS
support to be resolved from host IOMMU values, while avoiding
triggering auto-resolved values for hot-plugged devices.
Auto mode requires at least one cold-plugged device to retrieve
and finalise these properties, and we fail boot if that is not
the case.
Subsequent patches will make use of this helper to set the
values when we convert the values to OnOffAuto. New auto_mode
and auto_finalised bool members are added to SMMUv3AccelState.
smmuv3_accel_init() will set auto_mode to true when 'auto' is
detected for the accel SMMUv3 properties.
smmuv3_accel_auto_finalise() will set auto_finalised to true
after all 'auto' properties are resolved, and subsequent
calls to this function will return early if auto_finalised is
set to true.
Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
hw/arm/smmuv3-accel.h | 2 ++
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index 17306cd04b..617629bacd 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
return map[oas];
}
+static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
+ struct iommu_hw_info_arm_smmuv3 *info) {
+ SMMUv3AccelState *accel = s->s_accel;
+
+ /* Return if no auto for any or finalised already */
+ if (!accel->auto_mode || accel->auto_finalised) {
+ return;
+ }
+
+ /* We can't update if device is hotplugged */
+ if (DEVICE(pdev)->hotplugged) {
+ warn_report("arm-smmuv3: 'auto' feature property detected, but host "
+ "value cannot be applied for hot-plugged device; using "
+ "existing value");
+ return;
+ }
+
+ accel->auto_finalised = true;
+}
+
static bool
smmuv3_accel_check_hw_compatible(SMMUv3State *s,
struct iommu_hw_info_arm_smmuv3 *info,
+ PCIDevice *pdev,
Error **errp)
{
+ smmuv3_accel_auto_finalise(s, pdev, info);
+
/* QEMU SMMUv3 supports both linear and 2-level stream tables */
if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
@@ -124,7 +147,7 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
static bool
smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
- Error **errp)
+ PCIDevice *pdev, Error **errp)
{
struct iommu_hw_info_arm_smmuv3 info;
uint32_t data_type;
@@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
return false;
}
- if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
+ if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
return false;
}
return true;
@@ -595,6 +618,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
SMMUv3State *s = ARM_SMMUV3(bs);
SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
+ PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
if (!idev) {
return true;
@@ -613,7 +637,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
* Check the host SMMUv3 associated with the dev is compatible with the
* QEMU SMMUv3 accel.
*/
- if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
+ if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
return false;
}
@@ -867,8 +891,12 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
void smmuv3_accel_reset(SMMUv3State *s)
{
- /* Attach a HWPT based on GBPA reset value */
- smmuv3_accel_attach_gbpa_hwpt(s, NULL);
+ if (s->s_accel && s->s_accel->auto_mode && !s->s_accel->auto_finalised) {
+ error_report("AUTO mode specified but properties not finalised.");
+ exit(1);
+ }
+ /* Attach a HWPT based on GBPA reset value */
+ smmuv3_accel_attach_gbpa_hwpt(s, NULL);
}
static void smmuv3_accel_as_init(SMMUv3State *s)
diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
index dba6c71de5..3c1cd55714 100644
--- a/hw/arm/smmuv3-accel.h
+++ b/hw/arm/smmuv3-accel.h
@@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
uint32_t bypass_hwpt_id;
uint32_t abort_hwpt_id;
QLIST_HEAD(, SMMUv3AccelDevice) device_list;
+ bool auto_mode;
+ bool auto_finalised;
} SMMUv3AccelState;
typedef struct SMMUS1Hwpt {
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:05 ` Markus Armbruster
` (2 more replies)
2026-03-09 19:21 ` [RFC PATCH 3/8] vfio/pci: Add ats property and mask ATS cap when not exposed Nathan Chen
` (6 subsequent siblings)
8 siblings, 3 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
Allow accelerated SMMUv3 Address Translation Services support property
to be derived from host IOMMU capabilities. Derive host values using
IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
Set the default value of ATS to auto. The default for ATS support used
to be set to off, but we change it to match what the host IOMMU
properties report.
Add a "ats-enabled" read-only property for smmuv3 to address an
expected bool for the "ats" property in iort_smmuv3_devices().
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
hw/arm/smmuv3.c | 12 ++++++++++--
hw/arm/virt-acpi-build.c | 2 +-
include/hw/arm/smmuv3.h | 2 +-
4 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index 617629bacd..8fec335557 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
return;
}
+ /* Update ATS if auto from info */
+ if (s->ats == ON_OFF_AUTO_AUTO) {
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
+ FIELD_EX32(info->idr[0], IDR0, ATS));
+ }
+
accel->auto_finalised = true;
}
@@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
return false;
}
+ /* Check ATS value opted is compatible with Host SMMUv3 */
+ if (FIELD_EX32(info->idr[0], IDR0, ATS) <
+ FIELD_EX32(s->idr[0], IDR0, ATS)) {
+ error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
+ " Services");
+ return false;
+ }
/* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
@@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
/* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
- /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
- s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
+ /* Only override ATS if user explicitly set ON or OFF */
+ if (s->ats == ON_OFF_AUTO_ON) {
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
+ } else if (s->ats == ON_OFF_AUTO_OFF) {
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
+ }
/* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
if (s->oas == SMMU_OAS_48BIT) {
@@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
s->s_accel = g_new0(SMMUv3AccelState, 1);
bs->iommu_ops = &smmuv3_accel_ops;
smmuv3_accel_as_init(s);
+
+ if (s->ats == ON_OFF_AUTO_AUTO) {
+ s->s_accel->auto_mode = true;
+ }
}
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 068108e49b..197ba7c77b 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
smmuv3_accel_idr_override(s);
}
+static bool get_ats_enabled(Object *obj, Error **errp)
+{
+ SMMUv3State *s = ARM_SMMUV3(obj);
+ return FIELD_EX32(s->idr[0], IDR0, ATS);
+}
+
static void smmuv3_reset(SMMUv3State *s)
{
s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
@@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
error_setg(errp, "ril can only be disabled if accel=on");
return false;
}
- if (s->ats) {
+ if (s->ats == ON_OFF_AUTO_ON) {
error_setg(errp, "ats can only be enabled if accel=on");
return false;
}
@@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
/* RIL can be turned off for accel cases */
DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
- DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
+ DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
};
@@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
dc->hotpluggable = false;
dc->user_creatable = true;
+ object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
+
object_class_property_set_description(klass, "accel",
"Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
"configured in nested mode for vfio-pci dev assignment");
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 719d2f994e..6c77fc5f6a 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
- sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
+ sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
sbdev = SYS_BUS_DEVICE(obj);
sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index 26b2fc42fd..2ca49ded36 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -70,7 +70,7 @@ struct SMMUv3State {
uint64_t msi_gpa;
Error *migration_blocker;
bool ril;
- bool ats;
+ OnOffAuto ats;
uint8_t oas;
uint8_t ssidsize;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 3/8] vfio/pci: Add ats property and mask ATS cap when not exposed
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL Nathan Chen
` (5 subsequent siblings)
8 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen, Shameer Kolothum
From: Nathan Chen <nathanc@nvidia.com>
Add an "ats" OnOffAuto property to vfio-pci. When the device has an ATS
extended capability in config space but we should not expose it (ats=off,
or ats=auto and kernel reports IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED), mask
the capability so the guest does not see it.
This aligns with the kernel's per-device effective ATS reporting and
allows omitting ATS capability when the vIOMMU has ats=off.
Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
backends/iommufd.c | 15 +++++++
hw/vfio/pci.c | 63 ++++++++++++++++++++++++++++++
hw/vfio/pci.h | 1 +
include/system/host_iommu_device.h | 10 +++++
4 files changed, 89 insertions(+)
diff --git a/backends/iommufd.c b/backends/iommufd.c
index acfab907c0..d1e9d4dec3 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -22,6 +22,13 @@
#include "hw/vfio/vfio-device.h"
#include <sys/ioctl.h>
#include <linux/iommufd.h>
+/*
+ * Until kernel UAPI is synced via scripts;
+ * matches include/uapi/linux/iommufd.h
+ */
+#ifndef IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED
+#define IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED (1 << 3)
+#endif
static const char *iommufd_fd_name(IOMMUFDBackend *be)
{
@@ -570,6 +577,13 @@ static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)
}
}
+static bool hiod_iommufd_support_ats(HostIOMMUDevice *hiod)
+{
+ HostIOMMUDeviceCaps *caps = &hiod->caps;
+
+ return !(caps->hw_caps & IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED);
+}
+
static bool hiod_iommufd_get_pasid_info(HostIOMMUDevice *hiod,
PasidInfo *pasid_info)
{
@@ -592,6 +606,7 @@ static void hiod_iommufd_class_init(ObjectClass *oc, const void *data)
hioc->get_cap = hiod_iommufd_get_cap;
hioc->get_pasid_info = hiod_iommufd_get_pasid_info;
+ hioc->support_ats = hiod_iommufd_support_ats;
};
static const TypeInfo types[] = {
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c89f3fbea3..62b7cc08e6 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -49,6 +49,10 @@
#include "system/iommufd.h"
#include "vfio-migration-internal.h"
#include "vfio-helpers.h"
+#ifdef CONFIG_IOMMUFD
+#include "system/host_iommu_device.h"
+#include "linux/iommufd.h"
+#endif
/* Protected by BQL */
static KVMRouteChange vfio_route_change;
@@ -2550,10 +2554,53 @@ static bool vfio_pci_synthesize_pasid_cap(VFIOPCIDevice *vdev, Error **errp)
return true;
}
+/*
+ * Determine whether ATS capability should be advertised for @vdev, based on
+ * whether it was enabled on the command line and whether it is supported
+ * according to the kernel's IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED bit.
+ *
+ * Store whether ATS capability should be advertised in @ats_need.
+ *
+ * Return false if kernel enables IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED
+ * and ATS is effectively unsupported.
+ */
+static bool vfio_pci_ats_requested_and_supported(VFIOPCIDevice *vdev,
+ bool *ats_need, Error **errp)
+{
+ HostIOMMUDevice *hiod = vdev->vbasedev.hiod;
+ HostIOMMUDeviceClass *hiodc;
+ bool ats_supported;
+
+ if (vdev->ats == ON_OFF_AUTO_OFF) {
+ *ats_need = false;
+ return true;
+ }
+
+ *ats_need = true;
+ if (!hiod) {
+ return true;
+ }
+ hiodc = HOST_IOMMU_DEVICE_GET_CLASS(hiod);
+ if (!hiodc || !hiodc->support_ats) {
+ return true;
+ }
+
+ ats_supported = hiodc->support_ats(hiod);
+ if (vdev->ats == ON_OFF_AUTO_ON && !ats_supported) {
+ error_setg(errp, "vfio: ATS requested but not supported by kernel");
+ *ats_need = false;
+ return false;
+ }
+
+ *ats_need = ats_supported;
+ return true;
+}
+
static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
{
PCIDevice *pdev = PCI_DEVICE(vdev);
bool pasid_cap_added = false;
+ bool ats_needed = false;
Error *err = NULL;
uint32_t header;
uint16_t cap_id, next, size;
@@ -2603,6 +2650,11 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
pci_set_long(pdev->wmask + PCI_CONFIG_SPACE_SIZE, 0);
pci_set_long(vdev->emulated_config_bits + PCI_CONFIG_SPACE_SIZE, ~0);
+ if (!vfio_pci_ats_requested_and_supported(vdev, &ats_needed, &err)) {
+ error_report_err(err);
+ err = NULL;
+ }
+
for (next = PCI_CONFIG_SPACE_SIZE; next;
next = PCI_EXT_CAP_NEXT(pci_get_long(config + next))) {
header = pci_get_long(config + next);
@@ -2640,6 +2692,16 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
case PCI_EXT_CAP_ID_PASID:
pasid_cap_added = true;
/* fallthrough */
+ case PCI_EXT_CAP_ID_ATS:
+ /*
+ * If ATS is requested and supported according to the kernel, add
+ * the ATS capability. If not supported according to the kernel or
+ * disabled on the qemu command line, omit the ATS cap.
+ */
+ if (ats_needed) {
+ pcie_add_capability(pdev, cap_id, cap_ver, next, size);
+ }
+ break;
default:
pcie_add_capability(pdev, cap_id, cap_ver, next, size);
}
@@ -3819,6 +3881,7 @@ static const Property vfio_pci_properties[] = {
#ifdef CONFIG_IOMMUFD
DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
+ DEFINE_PROP_ON_OFF_AUTO("ats", VFIOPCIDevice, ats, ON_OFF_AUTO_AUTO),
#endif
DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
DEFINE_PROP_UINT16("x-vpasid-cap-offset", VFIOPCIDevice,
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index d6495d7f29..514a9197ce 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -191,6 +191,7 @@ struct VFIOPCIDevice {
VFIODisplay *dpy;
Notifier irqchip_change_notifier;
VFIOPCICPR cpr;
+ OnOffAuto ats;
};
/* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
diff --git a/include/system/host_iommu_device.h b/include/system/host_iommu_device.h
index f000301583..44c56e87bb 100644
--- a/include/system/host_iommu_device.h
+++ b/include/system/host_iommu_device.h
@@ -133,6 +133,16 @@ struct HostIOMMUDeviceClass {
* Returns: true on success, false on failure.
*/
bool (*get_pasid_info)(HostIOMMUDevice *hiod, PasidInfo *pasid_info);
+ /**
+ * @support_ats: Return whether ATS is supported for the device
+ * associated with @hiod host IOMMU device, checking if the
+ * IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED capability bit is set.
+ *
+ * @hiod: handle to the host IOMMU device
+ *
+ * Returns: true on success, false on failure
+ */
+ bool (*support_ats)(HostIOMMUDevice *hiod);
};
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (2 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 3/8] vfio/pci: Add ats property and mask ATS cap when not exposed Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:06 ` Markus Armbruster
2026-03-09 19:21 ` [RFC PATCH 5/8] qdev: Add a SsidSizeMode property Nathan Chen
` (4 subsequent siblings)
8 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
Allow accelerated SMMUv3 Range Invalidation support property to be
derived from host IOMMU capabilities. Derive host values using
IOMMU_GET_HW_INFO, retrieving RIL capability from IDR3.
Set the default value of RIL to auto. The default for RIL support used
to be set to on, but we change it to match what the host IOMMU
properties report so that users do not have to introspect host IDR3 for
Range Invalidation support. The RIL support needs to be compatible with
host SMMUv3 if accelerated mode is enabled.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 20 +++++++++++++++++---
hw/arm/smmuv3.c | 4 ++--
include/hw/arm/smmuv3.h | 2 +-
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index 8fec335557..02e3f7a9f3 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -58,6 +58,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
FIELD_EX32(info->idr[0], IDR0, ATS));
}
+ /* Update RIL if auto from info */
+ if (s->ril == ON_OFF_AUTO_AUTO) {
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL,
+ FIELD_EX32(info->idr[3], IDR3, RIL));
+ }
+
accel->auto_finalised = true;
}
@@ -854,8 +860,15 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
return;
}
- /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
- s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
+ /*
+ * Only override RIL if user explicitly set ON or OFF.
+ * AUTO will be resolved later when host info is available.
+ */
+ if (s->ril == ON_OFF_AUTO_ON) {
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
+ } else if (s->ril == ON_OFF_AUTO_OFF) {
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 0);
+ }
/* Only override ATS if user explicitly set ON or OFF */
if (s->ats == ON_OFF_AUTO_ON) {
@@ -941,7 +954,8 @@ void smmuv3_accel_init(SMMUv3State *s)
bs->iommu_ops = &smmuv3_accel_ops;
smmuv3_accel_as_init(s);
- if (s->ats == ON_OFF_AUTO_AUTO) {
+ if (s->ats == ON_OFF_AUTO_AUTO ||
+ s->ril == ON_OFF_AUTO_AUTO) {
s->s_accel->auto_mode = true;
}
}
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 197ba7c77b..7791e5294d 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1973,7 +1973,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
#endif
if (!s->accel) {
- if (!s->ril) {
+ if (s->ril == ON_OFF_AUTO_OFF) {
error_setg(errp, "ril can only be disabled if accel=on");
return false;
}
@@ -2133,7 +2133,7 @@ static const Property smmuv3_properties[] = {
/* GPA of MSI doorbell, for SMMUv3 accel use. */
DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
/* RIL can be turned off for accel cases */
- DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
+ DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index 2ca49ded36..9124bfe751 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -69,7 +69,7 @@ struct SMMUv3State {
struct SMMUv3AccelState *s_accel;
uint64_t msi_gpa;
Error *migration_blocker;
- bool ril;
+ OnOffAuto ril;
OnOffAuto ats;
uint8_t oas;
uint8_t ssidsize;
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 5/8] qdev: Add a SsidSizeMode property
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (3 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:14 ` Markus Armbruster
2026-03-09 19:21 ` [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size Nathan Chen
` (3 subsequent siblings)
8 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
Introduce a new enum type property allowing to set a Substream ID size
for HW-accelerated smmuv3. Values are auto and 0..20. The auto value
allows SSID size property to be derived from host IOMMU capabilities.
A value of 0 disables SubstreamID, while non-zero values specify the
SSID size in bits.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/core/qdev-properties-system.c | 14 ++++++++++++++
include/hw/core/qdev-properties-system.h | 3 +++
qapi/misc-arm.json | 15 +++++++++++++++
qapi/pragma.json | 1 +
4 files changed, 33 insertions(+)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index a402321f42..4aca1d4326 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -18,6 +18,7 @@
#include "qapi/qapi-types-block.h"
#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-types-migration.h"
+#include "qapi/qapi-types-misc-arm.h"
#include "qapi/qapi-visit-virtio.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ctype.h"
@@ -723,6 +724,19 @@ const PropertyInfo qdev_prop_zero_page_detection = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+/* --- SsidSizeMode --- */
+
+QEMU_BUILD_BUG_ON(sizeof(SsidSizeMode) != sizeof(int));
+
+const PropertyInfo qdev_prop_ssidsize_mode = {
+ .type = "SsidSizeMode",
+ .description = "ssidsize mode: auto, 0-20",
+ .enum_table = &SsidSizeMode_lookup,
+ .get = qdev_propinfo_get_enum,
+ .set = qdev_propinfo_set_enum,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
/* --- Reserved Region --- */
/*
diff --git a/include/hw/core/qdev-properties-system.h b/include/hw/core/qdev-properties-system.h
index ec21732ce5..4708885164 100644
--- a/include/hw/core/qdev-properties-system.h
+++ b/include/hw/core/qdev-properties-system.h
@@ -14,6 +14,7 @@ extern const PropertyInfo qdev_prop_multifd_compression;
extern const PropertyInfo qdev_prop_mig_mode;
extern const PropertyInfo qdev_prop_granule_mode;
extern const PropertyInfo qdev_prop_zero_page_detection;
+extern const PropertyInfo qdev_prop_ssidsize_mode;
extern const PropertyInfo qdev_prop_losttickpolicy;
extern const PropertyInfo qdev_prop_blockdev_on_error;
extern const PropertyInfo qdev_prop_bios_chs_trans;
@@ -61,6 +62,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
#define DEFINE_PROP_ZERO_PAGE_DETECTION(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_zero_page_detection, \
ZeroPageDetection)
+#define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
index f921d740f1..b372a3661b 100644
--- a/qapi/misc-arm.json
+++ b/qapi/misc-arm.json
@@ -45,3 +45,18 @@
# { "version": 3, "emulated": false, "kernel": true } ] }
##
{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
+
+##
+# @SsidSizeMode:
+#
+# SMMUv3 SubstreamID size configuration mode.
+#
+# @auto: derive from host IOMMU capabilities
+#
+# Values 0-20: SSIDSIZE value in bits. 0 disables SubstreamID.
+#
+# Since: 11.0
+##
+{ 'enum': 'SsidSizeMode',
+ 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] }
diff --git a/qapi/pragma.json b/qapi/pragma.json
index 193bc39059..24aebbe8f5 100644
--- a/qapi/pragma.json
+++ b/qapi/pragma.json
@@ -68,6 +68,7 @@
'S390CpuEntitlement',
'S390CpuPolarization',
'S390CpuState',
+ 'SsidSizeMode',
'String',
'StringWrapper',
'SysEmuTarget',
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (4 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 5/8] qdev: Add a SsidSizeMode property Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:21 ` Markus Armbruster
2026-03-09 19:21 ` [RFC PATCH 7/8] qdev: Add an OasMode property Nathan Chen
` (2 subsequent siblings)
8 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
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.
Set the default ssidsize value to auto. The default SSID size used
to be 0, but we change it to match what the host IOMMU properties
report so that users do not have to introspect host IDR1 for the
Substream ID support. 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.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 30 +++++++++++++++++++++++++++---
hw/arm/smmuv3.c | 16 ++++++----------
include/hw/arm/smmuv3.h | 3 ++-
3 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index 02e3f7a9f3..bd27b0da7c 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -64,6 +64,13 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
FIELD_EX32(info->idr[3], IDR3, RIL));
}
+ /* Update SSIDSIZE if auto from info */
+ if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
+ /* Store for get_viommu_flags() to determine PASID support */
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
+ FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
+ }
+
accel->auto_finalised = true;
}
@@ -839,7 +846,10 @@ 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 &&
+ s->ssidsize != SSID_SIZE_MODE_AUTO) ||
+ (s->ssidsize == SSID_SIZE_MODE_AUTO &&
+ FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) {
flags |= VIOMMU_FLAG_PASID_SUPPORTED;
}
return flags;
@@ -854,6 +864,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) {
@@ -886,7 +906,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 */
@@ -955,7 +978,8 @@ void smmuv3_accel_init(SMMUv3State *s)
smmuv3_accel_as_init(s);
if (s->ats == ON_OFF_AUTO_AUTO ||
- s->ril == ON_OFF_AUTO_AUTO) {
+ s->ril == ON_OFF_AUTO_AUTO ||
+ s->ssidsize == SSID_SIZE_MODE_AUTO) {
s->s_accel->auto_mode = true;
}
}
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 7791e5294d..bc03353759 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"
@@ -626,7 +627,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");
@@ -1985,7 +1986,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;
}
@@ -2003,11 +2004,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;
}
@@ -2136,7 +2132,8 @@ static const Property smmuv3_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
- DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
+ DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
+ SSID_SIZE_MODE_AUTO),
};
static void smmuv3_instance_init(Object *obj)
@@ -2176,8 +2173,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 9124bfe751..ae8158a5c3 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
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 7/8] qdev: Add an OasMode property
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (5 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-11 18:20 ` Eric Auger
2026-03-09 19:21 ` [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS Nathan Chen
2026-03-11 17:43 ` [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Eric Auger
8 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
Introduce a new enum type property allowing to set an Output Address
Size. Values are auto, 44, and 48, where a value of N specifies an
N-bit OAS.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/core/qdev-properties-system.c | 13 +++++++++++++
include/hw/core/qdev-properties-system.h | 3 +++
qapi/misc-arm.json | 16 ++++++++++++++++
3 files changed, 32 insertions(+)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 4aca1d4326..a805ee2e1f 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+/* --- OasMode --- */
+
+QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
+
+const PropertyInfo qdev_prop_oas_mode = {
+ .type = "OasMode",
+ .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
+ .enum_table = &OasMode_lookup,
+ .get = qdev_propinfo_get_enum,
+ .set = qdev_propinfo_set_enum,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
/* --- Reserved Region --- */
/*
diff --git a/include/hw/core/qdev-properties-system.h b/include/hw/core/qdev-properties-system.h
index 4708885164..2cbea16d61 100644
--- a/include/hw/core/qdev-properties-system.h
+++ b/include/hw/core/qdev-properties-system.h
@@ -15,6 +15,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
extern const PropertyInfo qdev_prop_granule_mode;
extern const PropertyInfo qdev_prop_zero_page_detection;
extern const PropertyInfo qdev_prop_ssidsize_mode;
+extern const PropertyInfo qdev_prop_oas_mode;
extern const PropertyInfo qdev_prop_losttickpolicy;
extern const PropertyInfo qdev_prop_blockdev_on_error;
extern const PropertyInfo qdev_prop_bios_chs_trans;
@@ -64,6 +65,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
ZeroPageDetection)
#define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
+#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
index b372a3661b..76b6965502 100644
--- a/qapi/misc-arm.json
+++ b/qapi/misc-arm.json
@@ -60,3 +60,19 @@
{ 'enum': 'SsidSizeMode',
'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] }
+
+##
+# @OasMode:
+#
+# SMMUv3 Output Address Size configuration mode.
+#
+# @auto: derive from host IOMMU capabilities
+#
+# @44: 44-bit output address size
+#
+# @48: 48-bit output address size
+#
+# Since: 11.0
+##
+{ 'enum': 'OasMode',
+ 'data': [ 'auto', '44', '48' ] }
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (6 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 7/8] qdev: Add an OasMode property Nathan Chen
@ 2026-03-09 19:21 ` Nathan Chen
2026-03-10 7:23 ` Markus Armbruster
2026-03-11 17:43 ` [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Eric Auger
8 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-09 19:21 UTC (permalink / raw)
To: qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster, Nathan Chen
From: Nathan Chen <nathanc@nvidia.com>
Allow accelerated SMMUv3 OAS property to be derived from host IOMMU
capabilities. Derive host values using IOMMU_GET_HW_INFO, retrieving
OAS from IDR5.
Set the default oas value to auto. The default Output Address Size used
to be 44-bit, but we change it to match what the host IOMMU properties
report so that users do not have to introspect host IDR5 for the OAS.
This keeps the OAS value advertised by the virtual SMMU compatible with
the capabilities of the host SMMUv3, so that the intermediate physical
addresses (IPA) consumed by host SMMU for stage-2 translation do not
exceed the host's max supported IPA size.
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
---
hw/arm/smmuv3-accel.c | 11 +++++++++--
hw/arm/smmuv3.c | 11 ++++++-----
include/hw/arm/smmuv3.h | 2 +-
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
index bd27b0da7c..03950a4cef 100644
--- a/hw/arm/smmuv3-accel.c
+++ b/hw/arm/smmuv3-accel.c
@@ -71,6 +71,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
}
+ /* Update OAS if auto from info */
+ if (s->oas == OAS_MODE_AUTO) {
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS,
+ FIELD_EX32(info->idr[5], IDR5, OAS));
+ }
+
accel->auto_finalised = true;
}
@@ -898,7 +904,7 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
}
/* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
- if (s->oas == SMMU_OAS_48BIT) {
+ if (s->oas == OAS_MODE_48) {
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
}
@@ -979,7 +985,8 @@ void smmuv3_accel_init(SMMUv3State *s)
if (s->ats == ON_OFF_AUTO_AUTO ||
s->ril == ON_OFF_AUTO_AUTO ||
- s->ssidsize == SSID_SIZE_MODE_AUTO) {
+ s->ssidsize == SSID_SIZE_MODE_AUTO ||
+ s->oas == OAS_MODE_AUTO) {
s->s_accel->auto_mode = true;
}
}
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index bc03353759..4fc4ed2c06 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1982,7 +1982,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
error_setg(errp, "ats can only be enabled if accel=on");
return false;
}
- if (s->oas != SMMU_OAS_44BIT) {
+ if (s->oas > OAS_MODE_44) {
error_setg(errp, "OAS must be 44 bits when accel=off");
return false;
}
@@ -2000,8 +2000,9 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
return false;
}
- if (s->oas != SMMU_OAS_44BIT && s->oas != SMMU_OAS_48BIT) {
- error_setg(errp, "OAS can only be set to 44 or 48 bits");
+ if (s->oas != OAS_MODE_AUTO && s->oas != OAS_MODE_44 &&
+ s->oas != OAS_MODE_48) {
+ error_setg(errp, "OAS can only be set to auto, 44 bits, or 48 bits");
return false;
}
@@ -2131,7 +2132,7 @@ static const Property smmuv3_properties[] = {
/* RIL can be turned off for accel cases */
DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
- DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
+ DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_AUTO),
DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
SSID_SIZE_MODE_AUTO),
};
@@ -2168,7 +2169,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
"platform has ATS support before enabling this");
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");
+ "are 44 or 48 bits.");
object_class_property_set_description(klass, "ssidsize",
"Number of bits used to represent SubstreamIDs (SSIDs). "
"A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index ae8158a5c3..3bfee63396 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -72,7 +72,7 @@ struct SMMUv3State {
Error *migration_blocker;
OnOffAuto ril;
OnOffAuto ats;
- uint8_t oas;
+ OasMode oas;
SsidSizeMode ssidsize;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
@ 2026-03-10 7:00 ` Markus Armbruster
2026-03-10 9:01 ` Shameer Kolothum Thodi
2026-03-10 7:42 ` Cédric Le Goater
1 sibling, 1 reply; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:00 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake,
Shameer Kolothum
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Introduce smmuv3_accel_auto_finalise() to resolve properties
> that are set to 'auto' for accelerated SMMUv3. This helper
> function allows properties such as ATS, RIL, SSIDSIZE, and OAS
> support to be resolved from host IOMMU values, while avoiding
> triggering auto-resolved values for hot-plugged devices.
>
> Auto mode requires at least one cold-plugged device to retrieve
> and finalise these properties, and we fail boot if that is not
> the case.
>
> Subsequent patches will make use of this helper to set the
> values when we convert the values to OnOffAuto. New auto_mode
> and auto_finalised bool members are added to SMMUv3AccelState.
> smmuv3_accel_init() will set auto_mode to true when 'auto' is
> detected for the accel SMMUv3 properties.
> smmuv3_accel_auto_finalise() will set auto_finalised to true
> after all 'auto' properties are resolved, and subsequent
> calls to this function will return early if auto_finalised is
> set to true.
>
> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
> hw/arm/smmuv3-accel.h | 2 ++
> 2 files changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 17306cd04b..617629bacd 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> return map[oas];
> }
>
> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> + struct iommu_hw_info_arm_smmuv3 *info) {
> + SMMUv3AccelState *accel = s->s_accel;
> +
> + /* Return if no auto for any or finalised already */
> + if (!accel->auto_mode || accel->auto_finalised) {
> + return;
> + }
> +
> + /* We can't update if device is hotplugged */
> + if (DEVICE(pdev)->hotplugged) {
> + warn_report("arm-smmuv3: 'auto' feature property detected, but host "
> + "value cannot be applied for hot-plugged device; using "
> + "existing value");
Why is this warning useful?
Does @auto's meaning depend on whether the device is cold- or
hot-plugged?
> + return;
> + }
> +
> + accel->auto_finalised = true;
> +}
> +
> static bool
> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> struct iommu_hw_info_arm_smmuv3 *info,
> + PCIDevice *pdev,
> Error **errp)
> {
> + smmuv3_accel_auto_finalise(s, pdev, info);
> +
> /* QEMU SMMUv3 supports both linear and 2-level stream tables */
> if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
> FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
> @@ -124,7 +147,7 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>
> static bool
> smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
> - Error **errp)
> + PCIDevice *pdev, Error **errp)
> {
> struct iommu_hw_info_arm_smmuv3 info;
> uint32_t data_type;
> @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
> return false;
> }
>
> - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
> + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
> return false;
> }
> return true;
> @@ -595,6 +618,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> SMMUv3State *s = ARM_SMMUV3(bs);
> SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
> SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
> + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
>
> if (!idev) {
> return true;
> @@ -613,7 +637,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> * Check the host SMMUv3 associated with the dev is compatible with the
> * QEMU SMMUv3 accel.
> */
> - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
> + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
> return false;
> }
>
> @@ -867,8 +891,12 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
>
> void smmuv3_accel_reset(SMMUv3State *s)
> {
> - /* Attach a HWPT based on GBPA reset value */
> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel->auto_finalised) {
> + error_report("AUTO mode specified but properties not finalised.");
> + exit(1);
How can we get here?
> + }
> + /* Attach a HWPT based on GBPA reset value */
> + smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> }
>
> static void smmuv3_accel_as_init(SMMUv3State *s)
> diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> index dba6c71de5..3c1cd55714 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
> uint32_t bypass_hwpt_id;
> uint32_t abort_hwpt_id;
> QLIST_HEAD(, SMMUv3AccelDevice) device_list;
> + bool auto_mode;
> + bool auto_finalised;
> } SMMUv3AccelState;
>
> typedef struct SMMUS1Hwpt {
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
@ 2026-03-10 7:05 ` Markus Armbruster
2026-03-10 17:35 ` Nathan Chen
2026-03-11 15:31 ` Eric Auger
2026-03-11 17:46 ` Eric Auger
2026-03-11 18:10 ` Eric Auger
2 siblings, 2 replies; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:05 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Allow accelerated SMMUv3 Address Translation Services support property
> to be derived from host IOMMU capabilities. Derive host values using
> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>
> Set the default value of ATS to auto. The default for ATS support used
> to be set to off, but we change it to match what the host IOMMU
> properties report.
>
> Add a "ats-enabled" read-only property for smmuv3 to address an
> expected bool for the "ats" property in iort_smmuv3_devices().
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
> hw/arm/smmuv3.c | 12 ++++++++++--
> hw/arm/virt-acpi-build.c | 2 +-
> include/hw/arm/smmuv3.h | 2 +-
> 4 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 617629bacd..8fec335557 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> return;
> }
>
> + /* Update ATS if auto from info */
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
> + FIELD_EX32(info->idr[0], IDR0, ATS));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
> return false;
> }
> + /* Check ATS value opted is compatible with Host SMMUv3 */
> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
> + " Services");
> + return false;
> + }
>
> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>
> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
> + /* Only override ATS if user explicitly set ON or OFF */
> + if (s->ats == ON_OFF_AUTO_ON) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
> + } else if (s->ats == ON_OFF_AUTO_OFF) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
> + }
>
> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
> if (s->oas == SMMU_OAS_48BIT) {
> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> s->s_accel = g_new0(SMMUv3AccelState, 1);
> bs->iommu_ops = &smmuv3_accel_ops;
> smmuv3_accel_as_init(s);
> +
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->s_accel->auto_mode = true;
> + }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 068108e49b..197ba7c77b 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
> smmuv3_accel_idr_override(s);
> }
>
> +static bool get_ats_enabled(Object *obj, Error **errp)
> +{
> + SMMUv3State *s = ARM_SMMUV3(obj);
> + return FIELD_EX32(s->idr[0], IDR0, ATS);
> +}
> +
> static void smmuv3_reset(SMMUv3State *s)
> {
> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "ril can only be disabled if accel=on");
> return false;
> }
> - if (s->ats) {
> + if (s->ats == ON_OFF_AUTO_ON) {
> error_setg(errp, "ats can only be enabled if accel=on");
> return false;
> }
> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> /* RIL can be turned off for accel cases */
> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
Is property "ats" accessible via QMP or JSON command line? If yes, this
is an incompatible change: JSON values false and true no longer work.
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> };
> @@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
> dc->hotpluggable = false;
> dc->user_creatable = true;
>
> + object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
> +
> object_class_property_set_description(klass, "accel",
> "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
> "configured in nested mode for vfio-pci dev assignment");
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 719d2f994e..6c77fc5f6a 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
>
> bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
> sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
> - sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
> + sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
> pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
> sbdev = SYS_BUS_DEVICE(obj);
> sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 26b2fc42fd..2ca49ded36 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -70,7 +70,7 @@ struct SMMUv3State {
> uint64_t msi_gpa;
> Error *migration_blocker;
> bool ril;
> - bool ats;
> + OnOffAuto ats;
> uint8_t oas;
> uint8_t ssidsize;
> };
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL
2026-03-09 19:21 ` [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL Nathan Chen
@ 2026-03-10 7:06 ` Markus Armbruster
0 siblings, 0 replies; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:06 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake,
Markus Armbruster
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Allow accelerated SMMUv3 Range Invalidation support property to be
> derived from host IOMMU capabilities. Derive host values using
> IOMMU_GET_HW_INFO, retrieving RIL capability from IDR3.
>
> Set the default value of RIL to auto. The default for RIL support used
> to be set to on, but we change it to match what the host IOMMU
> properties report so that users do not have to introspect host IDR3 for
> Range Invalidation support. The RIL support needs to be compatible with
> host SMMUv3 if accelerated mode is enabled.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 20 +++++++++++++++++---
> hw/arm/smmuv3.c | 4 ++--
> include/hw/arm/smmuv3.h | 2 +-
> 3 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 8fec335557..02e3f7a9f3 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -58,6 +58,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> FIELD_EX32(info->idr[0], IDR0, ATS));
> }
>
> + /* Update RIL if auto from info */
> + if (s->ril == ON_OFF_AUTO_AUTO) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL,
> + FIELD_EX32(info->idr[3], IDR3, RIL));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -854,8 +860,15 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> return;
> }
>
> - /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
> - s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
> + /*
> + * Only override RIL if user explicitly set ON or OFF.
> + * AUTO will be resolved later when host info is available.
> + */
> + if (s->ril == ON_OFF_AUTO_ON) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
> + } else if (s->ril == ON_OFF_AUTO_OFF) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 0);
> + }
>
> /* Only override ATS if user explicitly set ON or OFF */
> if (s->ats == ON_OFF_AUTO_ON) {
> @@ -941,7 +954,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> bs->iommu_ops = &smmuv3_accel_ops;
> smmuv3_accel_as_init(s);
>
> - if (s->ats == ON_OFF_AUTO_AUTO) {
> + if (s->ats == ON_OFF_AUTO_AUTO ||
> + s->ril == ON_OFF_AUTO_AUTO) {
> s->s_accel->auto_mode = true;
> }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 197ba7c77b..7791e5294d 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1973,7 +1973,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> #endif
>
> if (!s->accel) {
> - if (!s->ril) {
> + if (s->ril == ON_OFF_AUTO_OFF) {
> error_setg(errp, "ril can only be disabled if accel=on");
> return false;
> }
> @@ -2133,7 +2133,7 @@ static const Property smmuv3_properties[] = {
> /* GPA of MSI doorbell, for SMMUv3 accel use. */
> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> /* RIL can be turned off for accel cases */
> - DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> + DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
Is property "ril" accessible via QMP or JSON command line? If yes, this
is an incompatible change: JSON values false and true no longer work.
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 2ca49ded36..9124bfe751 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -69,7 +69,7 @@ struct SMMUv3State {
> struct SMMUv3AccelState *s_accel;
> uint64_t msi_gpa;
> Error *migration_blocker;
> - bool ril;
> + OnOffAuto ril;
> OnOffAuto ats;
> uint8_t oas;
> uint8_t ssidsize;
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 5/8] qdev: Add a SsidSizeMode property
2026-03-09 19:21 ` [RFC PATCH 5/8] qdev: Add a SsidSizeMode property Nathan Chen
@ 2026-03-10 7:14 ` Markus Armbruster
0 siblings, 0 replies; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:14 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake, John Snow
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Introduce a new enum type property allowing to set a Substream ID size
> for HW-accelerated smmuv3. Values are auto and 0..20. The auto value
> allows SSID size property to be derived from host IOMMU capabilities.
> A value of 0 disables SubstreamID, while non-zero values specify the
> SSID size in bits.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
[...]
> diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
> index f921d740f1..b372a3661b 100644
> --- a/qapi/misc-arm.json
> +++ b/qapi/misc-arm.json
> @@ -45,3 +45,18 @@
> # { "version": 3, "emulated": false, "kernel": true } ] }
> ##
> { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
> +
> +##
> +# @SsidSizeMode:
> +#
> +# SMMUv3 SubstreamID size configuration mode.
> +#
> +# @auto: derive from host IOMMU capabilities
> +#
> +# Values 0-20: SSIDSIZE value in bits. 0 disables SubstreamID.
> +#
> +# Since: 11.0
> +##
This renders like
Enum SsidSizeMode (Since: 11.0)
SMMUv3 SubstreamID size configuration mode.
Values:
* auto -- derive from host IOMMU capabilities
* 0 -- Not documented
* 1 -- Not documented
* 2 -- Not documented
* 3 -- Not documented
* 4 -- Not documented
* 5 -- Not documented
* 6 -- Not documented
* 7 -- Not documented
* 8 -- Not documented
* 9 -- Not documented
* 10 -- Not documented
* 11 -- Not documented
* 12 -- Not documented
* 13 -- Not documented
* 14 -- Not documented
* 15 -- Not documented
* 16 -- Not documented
* 17 -- Not documented
* 18 -- Not documented
* 19 -- Not documented
* 20 -- Not documented
Values 0-20: SSIDSIZE value in bits. 0 disables SubstreamID.
Sadly, many existing enums also have undocumented members. Some because
documenting them one by one would be kind of silly (e.g. QKeyCode).
I don't have a better idea right now, so this is just an observation,
not a demand. Maybe John Snow (cc'ed) can some day dream up a better
way to do this.
> +{ 'enum': 'SsidSizeMode',
> + 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
> + '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] }
> diff --git a/qapi/pragma.json b/qapi/pragma.json
> index 193bc39059..24aebbe8f5 100644
> --- a/qapi/pragma.json
> +++ b/qapi/pragma.json
> @@ -68,6 +68,7 @@
> 'S390CpuEntitlement',
> 'S390CpuPolarization',
> 'S390CpuState',
> + 'SsidSizeMode',
> 'String',
> 'StringWrapper',
> 'SysEmuTarget',
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size
2026-03-09 19:21 ` [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size Nathan Chen
@ 2026-03-10 7:21 ` Markus Armbruster
2026-03-10 17:44 ` Nathan Chen
0 siblings, 1 reply; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:21 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> 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.
>
> Set the default ssidsize value to auto. The default SSID size used
> to be 0, but we change it to match what the host IOMMU properties
> report so that users do not have to introspect host IDR1 for the
> Substream ID support. 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.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 30 +++++++++++++++++++++++++++---
> hw/arm/smmuv3.c | 16 ++++++----------
> include/hw/arm/smmuv3.h | 3 ++-
> 3 files changed, 35 insertions(+), 14 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 02e3f7a9f3..bd27b0da7c 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -64,6 +64,13 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> FIELD_EX32(info->idr[3], IDR3, RIL));
> }
>
> + /* Update SSIDSIZE if auto from info */
> + if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
> + /* Store for get_viommu_flags() to determine PASID support */
> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
> + FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -839,7 +846,10 @@ 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 &&
> + s->ssidsize != SSID_SIZE_MODE_AUTO) ||
> + (s->ssidsize == SSID_SIZE_MODE_AUTO &&
> + FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) {
> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
> }
> return flags;
> @@ -854,6 +864,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 */
This relies on how the enum values are ordered in the schema, and on how
the QAPI generator encodes enums. The latter is fine: we document it in
docs/devel/qapi-code-gen.rst section "Enumeration types". The former is
worth a non-doc comment in the schema, like this:
{ 'enum': 'SsidSizeMode',
'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'10', '11', '12', '13', '14', '15', '16', '17', '18',
'19', '20' ] } # order matters, see ssid_size_mode_auto()
> +}
> +
> void smmuv3_accel_idr_override(SMMUv3State *s)
> {
> if (!s->accel) {
> @@ -886,7 +906,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 */
> @@ -955,7 +978,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> smmuv3_accel_as_init(s);
>
> if (s->ats == ON_OFF_AUTO_AUTO ||
> - s->ril == ON_OFF_AUTO_AUTO) {
> + s->ril == ON_OFF_AUTO_AUTO ||
> + s->ssidsize == SSID_SIZE_MODE_AUTO) {
> s->s_accel->auto_mode = true;
> }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 7791e5294d..bc03353759 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"
> @@ -626,7 +627,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");
> @@ -1985,7 +1986,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;
> }
> @@ -2003,11 +2004,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;
> }
> @@ -2136,7 +2132,8 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
> + SSID_SIZE_MODE_AUTO),
Is property "ssidsize" accessible via QMP or JSON command line? If yes,
this is an incompatible change: JSON integer values no longer work.
> };
>
> static void smmuv3_instance_init(Object *obj)
> @@ -2176,8 +2173,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 9124bfe751..ae8158a5c3 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 {
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS
2026-03-09 19:21 ` [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS Nathan Chen
@ 2026-03-10 7:23 ` Markus Armbruster
0 siblings, 0 replies; 49+ messages in thread
From: Markus Armbruster @ 2026-03-10 7:23 UTC (permalink / raw)
To: Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P . Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake,
Markus Armbruster
Nathan Chen <nathanc@nvidia.com> writes:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Allow accelerated SMMUv3 OAS property to be derived from host IOMMU
> capabilities. Derive host values using IOMMU_GET_HW_INFO, retrieving
> OAS from IDR5.
>
> Set the default oas value to auto. The default Output Address Size used
> to be 44-bit, but we change it to match what the host IOMMU properties
> report so that users do not have to introspect host IDR5 for the OAS.
> This keeps the OAS value advertised by the virtual SMMU compatible with
> the capabilities of the host SMMUv3, so that the intermediate physical
> addresses (IPA) consumed by host SMMU for stage-2 translation do not
> exceed the host's max supported IPA size.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 11 +++++++++--
> hw/arm/smmuv3.c | 11 ++++++-----
> include/hw/arm/smmuv3.h | 2 +-
> 3 files changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index bd27b0da7c..03950a4cef 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -71,6 +71,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
> }
>
> + /* Update OAS if auto from info */
> + if (s->oas == OAS_MODE_AUTO) {
> + s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS,
> + FIELD_EX32(info->idr[5], IDR5, OAS));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -898,7 +904,7 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> }
>
> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
> - if (s->oas == SMMU_OAS_48BIT) {
> + if (s->oas == OAS_MODE_48) {
> s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48);
> }
>
> @@ -979,7 +985,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>
> if (s->ats == ON_OFF_AUTO_AUTO ||
> s->ril == ON_OFF_AUTO_AUTO ||
> - s->ssidsize == SSID_SIZE_MODE_AUTO) {
> + s->ssidsize == SSID_SIZE_MODE_AUTO ||
> + s->oas == OAS_MODE_AUTO) {
> s->s_accel->auto_mode = true;
> }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index bc03353759..4fc4ed2c06 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1982,7 +1982,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "ats can only be enabled if accel=on");
> return false;
> }
> - if (s->oas != SMMU_OAS_44BIT) {
> + if (s->oas > OAS_MODE_44) {
> error_setg(errp, "OAS must be 44 bits when accel=off");
> return false;
> }
> @@ -2000,8 +2000,9 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> return false;
> }
>
> - if (s->oas != SMMU_OAS_44BIT && s->oas != SMMU_OAS_48BIT) {
> - error_setg(errp, "OAS can only be set to 44 or 48 bits");
> + if (s->oas != OAS_MODE_AUTO && s->oas != OAS_MODE_44 &&
> + s->oas != OAS_MODE_48) {
> + error_setg(errp, "OAS can only be set to auto, 44 bits, or 48 bits");
> return false;
> }
>
> @@ -2131,7 +2132,7 @@ static const Property smmuv3_properties[] = {
> /* RIL can be turned off for accel cases */
> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> - DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> + DEFINE_PROP_OAS_MODE("oas", SMMUv3State, oas, OAS_MODE_AUTO),
Is property "oas" accessible via QMP or JSON command line? If yes, this
is an incompatible change: JSON integer values no longer work.
> DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
> SSID_SIZE_MODE_AUTO),
> };
> @@ -2168,7 +2169,7 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
> "platform has ATS support before enabling this");
> 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");
> + "are 44 or 48 bits.");
> object_class_property_set_description(klass, "ssidsize",
> "Number of bits used to represent SubstreamIDs (SSIDs). "
> "A value of N allows SSIDs in the range [0 .. 2^N - 1]. "
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index ae8158a5c3..3bfee63396 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -72,7 +72,7 @@ struct SMMUv3State {
> Error *migration_blocker;
> OnOffAuto ril;
> OnOffAuto ats;
> - uint8_t oas;
> + OasMode oas;
> SsidSizeMode ssidsize;
> };
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
2026-03-10 7:00 ` Markus Armbruster
@ 2026-03-10 7:42 ` Cédric Le Goater
2026-03-10 8:40 ` Shameer Kolothum Thodi
2026-03-10 17:13 ` Nathan Chen
1 sibling, 2 replies; 49+ messages in thread
From: Cédric Le Goater @ 2026-03-10 7:42 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Eric Blake,
Markus Armbruster, Shameer Kolothum
On 3/9/26 20:21, Nathan Chen wrote:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Introduce smmuv3_accel_auto_finalise() to resolve properties
> that are set to 'auto' for accelerated SMMUv3. This helper
> function allows properties such as ATS, RIL, SSIDSIZE, and OAS
> support to be resolved from host IOMMU values, while avoiding
> triggering auto-resolved values for hot-plugged devices.
>
> Auto mode requires at least one cold-plugged device to retrieve
> and finalise these properties, and we fail boot if that is not
> the case.
IIUC, QEMU will require a minimum of one PCI device if
arm-smmuv3,accel=on is passed on the command line and if the
smmu properties are set to 'auto'.
I would try to enforce this requirement in the realize routine.
Can't we leverage the supports_address_space() handler ? See :
static bool smmuv3_accel_supports_as(PCIBus *bus, void *opaque, int devfn,
Error **errp)
{
PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
bool vfio_pci = false;
if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
if (vfio_pci) {
error_setg(errp, "vfio-pci endpoint devices without an iommufd "
"backend not allowed when using arm-smmuv3,accel=on");
...
>
> Subsequent patches will make use of this helper to set the
> values when we convert the values to OnOffAuto. New auto_mode
> and auto_finalised bool members are added to SMMUv3AccelState.
> smmuv3_accel_init() will set auto_mode to true when 'auto' is
> detected for the accel SMMUv3 properties.
> smmuv3_accel_auto_finalise() will set auto_finalised to true
> after all 'auto' properties are resolved, and subsequent
> calls to this function will return early if auto_finalised is
> set to true.
>
> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
> hw/arm/smmuv3-accel.h | 2 ++
> 2 files changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 17306cd04b..617629bacd 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> return map[oas];
> }
>
> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> + struct iommu_hw_info_arm_smmuv3 *info) {
> + SMMUv3AccelState *accel = s->s_accel;
> +
> + /* Return if no auto for any or finalised already */
> + if (!accel->auto_mode || accel->auto_finalised) {
> + return;
> + }
> +
> + /* We can't update if device is hotplugged */
> + if (DEVICE(pdev)->hotplugged) {
> + warn_report("arm-smmuv3: 'auto' feature property detected, but host "
> + "value cannot be applied for hot-plugged device; using "
> + "existing value");
Please add an 'Error **' parameter instead.
> + return;
> + }
> +
> + accel->auto_finalised = true;
> +}
> +
> static bool
> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> struct iommu_hw_info_arm_smmuv3 *info,
> + PCIDevice *pdev,
> Error **errp)
> {
> + smmuv3_accel_auto_finalise(s, pdev, info);
> +
> /* QEMU SMMUv3 supports both linear and 2-level stream tables */
> if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
> FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
> @@ -124,7 +147,7 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>
> static bool
> smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
> - Error **errp)
> + PCIDevice *pdev, Error **errp)
> {
> struct iommu_hw_info_arm_smmuv3 info;
> uint32_t data_type;
> @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
> return false;
> }
>
> - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
> + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
> return false;
> }
> return true;
> @@ -595,6 +618,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> SMMUv3State *s = ARM_SMMUV3(bs);
> SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
> SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn);
> + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
>
> if (!idev) {
> return true;
> @@ -613,7 +637,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> * Check the host SMMUv3 associated with the dev is compatible with the
> * QEMU SMMUv3 accel.
> */
> - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
> + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
> return false;
> }
>
> @@ -867,8 +891,12 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
>
> void smmuv3_accel_reset(SMMUv3State *s)
> {
> - /* Attach a HWPT based on GBPA reset value */
> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel->auto_finalised) {
> + error_report("AUTO mode specified but properties not finalised.");
This is not a very friendly message for the user.
> + exit(1);
QEMU should not exit in the reset phase. Can this check be done during
the realize stage ?
Thanks,
C.
> + }
> + /* Attach a HWPT based on GBPA reset value */
> + smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> }
>
> static void smmuv3_accel_as_init(SMMUv3State *s)
> diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> index dba6c71de5..3c1cd55714 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
> uint32_t bypass_hwpt_id;
> uint32_t abort_hwpt_id;
> QLIST_HEAD(, SMMUv3AccelDevice) device_list;
> + bool auto_mode;
> + bool auto_finalised;
> } SMMUv3AccelState;
>
> typedef struct SMMUS1Hwpt {
^ permalink raw reply [flat|nested] 49+ messages in thread
* RE: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-10 7:42 ` Cédric Le Goater
@ 2026-03-10 8:40 ` Shameer Kolothum Thodi
2026-03-12 8:37 ` Cédric Le Goater
2026-03-10 17:13 ` Nathan Chen
1 sibling, 1 reply; 49+ messages in thread
From: Shameer Kolothum Thodi @ 2026-03-10 8:40 UTC (permalink / raw)
To: Cédric Le Goater, Nathan Chen, qemu-devel@nongnu.org,
qemu-arm@nongnu.org
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Eric Blake,
Markus Armbruster
> -----Original Message-----
> From: Cédric Le Goater <clg@redhat.com>
> Sent: 10 March 2026 07:42
> To: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org
> Cc: Yi Liu <yi.l.liu@intel.com>; Eric Auger <eric.auger@redhat.com>;
> Zhenzhong Duan <zhenzhong.duan@intel.com>; Peter Maydell
> <peter.maydell@linaro.org>; Shannon Zhao <shannon.zhaosl@gmail.com>;
> Michael S . Tsirkin <mst@redhat.com>; Igor Mammedov
> <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>; Paolo
> Bonzini <pbonzini@redhat.com>; Daniel P . Berrangé
> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Eric Blake
> <eblake@redhat.com>; Markus Armbruster <armbru@redhat.com>;
> Shameer Kolothum Thodi <skolothumtho@nvidia.com>
> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
> auto parameters
>
> External email: Use caution opening links or attachments
>
>
> On 3/9/26 20:21, Nathan Chen wrote:
> > From: Nathan Chen <nathanc@nvidia.com>
> >
> > Introduce smmuv3_accel_auto_finalise() to resolve properties
> > that are set to 'auto' for accelerated SMMUv3. This helper
> > function allows properties such as ATS, RIL, SSIDSIZE, and OAS
> > support to be resolved from host IOMMU values, while avoiding
> > triggering auto-resolved values for hot-plugged devices.
> >
> > Auto mode requires at least one cold-plugged device to retrieve
> > and finalise these properties, and we fail boot if that is not
> > the case.
>
> IIUC, QEMU will require a minimum of one PCI device if
> arm-smmuv3,accel=on is passed on the command line and if the
> smmu properties are set to 'auto'.
Yes, that’s correct.
> I would try to enforce this requirement in the realize routine.
> Can't we leverage the supports_address_space() handler ? See :
>
>
> static bool smmuv3_accel_supports_as(PCIBus *bus, void *opaque, int
> devfn,
> Error **errp)
> {
> PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
> bool vfio_pci = false;
>
> if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
> if (vfio_pci) {
> error_setg(errp, "vfio-pci endpoint devices without an iommufd "
> "backend not allowed when using arm-smmuv3,accel=on");
> ...
Hmm..i doubt we can do it here as we need HostIOMMUDeviceIOMMUFD *idev
for retrieving the IOMMU_GET_HW_INFO.
supports_address_space() is invoked very early during do_pci_register_device()
and there are no associated idev available at that time.
> >
> > Subsequent patches will make use of this helper to set the
> > values when we convert the values to OnOffAuto. New auto_mode
> > and auto_finalised bool members are added to SMMUv3AccelState.
> > smmuv3_accel_init() will set auto_mode to true when 'auto' is
> > detected for the accel SMMUv3 properties.
> > smmuv3_accel_auto_finalise() will set auto_finalised to true
> > after all 'auto' properties are resolved, and subsequent
> > calls to this function will return early if auto_finalised is
> > set to true.
> >
> > Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> > Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> > ---
> > hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
> > hw/arm/smmuv3-accel.h | 2 ++
> > 2 files changed, 35 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> > index 17306cd04b..617629bacd 100644
> > --- a/hw/arm/smmuv3-accel.c
> > +++ b/hw/arm/smmuv3-accel.c
> > @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> > return map[oas];
> > }
> >
> > +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
> *pdev,
> > + struct iommu_hw_info_arm_smmuv3 *info) {
> > + SMMUv3AccelState *accel = s->s_accel;
> > +
> > + /* Return if no auto for any or finalised already */
> > + if (!accel->auto_mode || accel->auto_finalised) {
> > + return;
> > + }
> > +
> > + /* We can't update if device is hotplugged */
> > + if (DEVICE(pdev)->hotplugged) {
> > + warn_report("arm-smmuv3: 'auto' feature property detected, but host
> "
> > + "value cannot be applied for hot-plugged device; using "
> > + "existing value");
>
> Please add an 'Error **' parameter instead.
>
> > + return;
> > + }
> > +
> > + accel->auto_finalised = true;
> > +}
> > +
> > static bool
> > smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> > struct iommu_hw_info_arm_smmuv3 *info,
> > + PCIDevice *pdev,
> > Error **errp)
> > {
> > + smmuv3_accel_auto_finalise(s, pdev, info);
> > +
> > /* QEMU SMMUv3 supports both linear and 2-level stream tables */
> > if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
> > FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
> > @@ -124,7 +147,7 @@
> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> >
> > static bool
> > smmuv3_accel_hw_compatible(SMMUv3State *s,
> HostIOMMUDeviceIOMMUFD *idev,
> > - Error **errp)
> > + PCIDevice *pdev, Error **errp)
> > {
> > struct iommu_hw_info_arm_smmuv3 info;
> > uint32_t data_type;
> > @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s,
> HostIOMMUDeviceIOMMUFD *idev,
> > return false;
> > }
> >
> > - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
> > + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
> > return false;
> > }
> > return true;
> > @@ -595,6 +618,7 @@ static bool
> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> > SMMUv3State *s = ARM_SMMUV3(bs);
> > SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
> > SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus,
> bus, devfn);
> > + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
> >
> > if (!idev) {
> > return true;
> > @@ -613,7 +637,7 @@ static bool
> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> > * Check the host SMMUv3 associated with the dev is compatible with
> the
> > * QEMU SMMUv3 accel.
> > */
> > - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
> > + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
> > return false;
> > }
> >
> > @@ -867,8 +891,12 @@ bool
> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
> >
> > void smmuv3_accel_reset(SMMUv3State *s)
> > {
> > - /* Attach a HWPT based on GBPA reset value */
> > - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> > + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel-
> >auto_finalised) {
> > + error_report("AUTO mode specified but properties not finalised.");
>
> This is not a very friendly message for the user.
>
>
> > + exit(1);
>
> QEMU should not exit in the reset phase. Can this check be done during
> the realize stage ?
SMMUv3 realize stage happens before the cold-plugged device
set_iommu_device(), and therefore we can't check whether the SMMUv3
properties have been retrieved and finalised at that point.
Not sure there is any other place we can do this other than in the reset
path.
Is avoiding exit(1) in the reset phase a strict requirement or a nice to
have one?
Thanks,
Shameer
>
> Thanks,
>
> C.
>
> > + }
> > + /* Attach a HWPT based on GBPA reset value */
> > + smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> > }
> >
> > static void smmuv3_accel_as_init(SMMUv3State *s)
> > diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> > index dba6c71de5..3c1cd55714 100644
> > --- a/hw/arm/smmuv3-accel.h
> > +++ b/hw/arm/smmuv3-accel.h
> > @@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
> > uint32_t bypass_hwpt_id;
> > uint32_t abort_hwpt_id;
> > QLIST_HEAD(, SMMUv3AccelDevice) device_list;
> > + bool auto_mode;
> > + bool auto_finalised;
> > } SMMUv3AccelState;
> >
> > typedef struct SMMUS1Hwpt {
^ permalink raw reply [flat|nested] 49+ messages in thread
* RE: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-10 7:00 ` Markus Armbruster
@ 2026-03-10 9:01 ` Shameer Kolothum Thodi
2026-03-12 8:20 ` Markus Armbruster
0 siblings, 1 reply; 49+ messages in thread
From: Shameer Kolothum Thodi @ 2026-03-10 9:01 UTC (permalink / raw)
To: Markus Armbruster, Nathan Chen
Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Yi Liu, Eric Auger,
Zhenzhong Duan, Peter Maydell, Shannon Zhao, Michael S . Tsirkin,
Igor Mammedov, Ani Sinha, Paolo Bonzini, Daniel P.Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake
> -----Original Message-----
> From: Markus Armbruster <armbru@redhat.com>
> Sent: 10 March 2026 07:01
> To: Nathan Chen <nathanc@nvidia.com>
> Cc: qemu-devel@nongnu.org; qemu-arm@nongnu.org; Yi Liu
> <yi.l.liu@intel.com>; Eric Auger <eric.auger@redhat.com>; Zhenzhong Duan
> <zhenzhong.duan@intel.com>; Peter Maydell <peter.maydell@linaro.org>;
> Shannon Zhao <shannon.zhaosl@gmail.com>; Michael S . Tsirkin
> <mst@redhat.com>; Igor Mammedov <imammedo@redhat.com>; Ani Sinha
> <anisinha@redhat.com>; Paolo Bonzini <pbonzini@redhat.com>; Daniel
> P.Berrangé <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>;
> Cédric Le Goater <clg@redhat.com>; Eric Blake <eblake@redhat.com>;
> Shameer Kolothum Thodi <skolothumtho@nvidia.com>
> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
> auto parameters
>
> External email: Use caution opening links or attachments
>
>
> Nathan Chen <nathanc@nvidia.com> writes:
>
> > From: Nathan Chen <nathanc@nvidia.com>
> >
> > Introduce smmuv3_accel_auto_finalise() to resolve properties
> > that are set to 'auto' for accelerated SMMUv3. This helper
> > function allows properties such as ATS, RIL, SSIDSIZE, and OAS
> > support to be resolved from host IOMMU values, while avoiding
> > triggering auto-resolved values for hot-plugged devices.
> >
> > Auto mode requires at least one cold-plugged device to retrieve
> > and finalise these properties, and we fail boot if that is not
> > the case.
> >
> > Subsequent patches will make use of this helper to set the
> > values when we convert the values to OnOffAuto. New auto_mode
> > and auto_finalised bool members are added to SMMUv3AccelState.
> > smmuv3_accel_init() will set auto_mode to true when 'auto' is
> > detected for the accel SMMUv3 properties.
> > smmuv3_accel_auto_finalise() will set auto_finalised to true
> > after all 'auto' properties are resolved, and subsequent
> > calls to this function will return early if auto_finalised is
> > set to true.
> >
> > Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> > Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> > ---
> > hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++--
> ---
> > hw/arm/smmuv3-accel.h | 2 ++
> > 2 files changed, 35 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> > index 17306cd04b..617629bacd 100644
> > --- a/hw/arm/smmuv3-accel.c
> > +++ b/hw/arm/smmuv3-accel.c
> > @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> > return map[oas];
> > }
> >
> > +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
> *pdev,
> > + struct iommu_hw_info_arm_smmuv3 *info) {
> > + SMMUv3AccelState *accel = s->s_accel;
> > +
> > + /* Return if no auto for any or finalised already */
> > + if (!accel->auto_mode || accel->auto_finalised) {
> > + return;
> > + }
> > +
> > + /* We can't update if device is hotplugged */
> > + if (DEVICE(pdev)->hotplugged) {
> > + warn_report("arm-smmuv3: 'auto' feature property detected, but host
> "
> > + "value cannot be applied for hot-plugged device; using "
> > + "existing value");
>
> Why is this warning useful?
>
> Does @auto's meaning depend on whether the device is cold- or
> hot-plugged?
If SMMUv3 accel=on and properties are set to "auto", we require
at least one cold-plugged vfio-pci device to retrieve the associated
host SMMUv3 information and finalise the QEMU SMMUv3 properties.
In this series, "auto_mode" is set if any accel property is specified as
"auto". The properties are then finalised using the first cold-plugged
device and "auto_finalised" is set.
Since we later fail the guest boot(see below) in the reset phase if
auto_mode is set but auto_finalised is still false, the above hotplug
case should not really happen. In that case the VM would not boot.
So likely we can get rid of the hotplug check above. Need to do
a bit more testing to confirm we cover all corner cases.
>
> > + return;
> > + }
> > +
> > + accel->auto_finalised = true;
> > +}
> > +
> > static bool
> > smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> > struct iommu_hw_info_arm_smmuv3 *info,
> > + PCIDevice *pdev,
> > Error **errp)
> > {
> > + smmuv3_accel_auto_finalise(s, pdev, info);
> > +
> > /* QEMU SMMUv3 supports both linear and 2-level stream tables */
> > if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
> > FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
> > @@ -124,7 +147,7 @@
> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> >
> > static bool
> > smmuv3_accel_hw_compatible(SMMUv3State *s,
> HostIOMMUDeviceIOMMUFD *idev,
> > - Error **errp)
> > + PCIDevice *pdev, Error **errp)
> > {
> > struct iommu_hw_info_arm_smmuv3 info;
> > uint32_t data_type;
> > @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s,
> HostIOMMUDeviceIOMMUFD *idev,
> > return false;
> > }
> >
> > - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
> > + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
> > return false;
> > }
> > return true;
> > @@ -595,6 +618,7 @@ static bool
> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> > SMMUv3State *s = ARM_SMMUV3(bs);
> > SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
> > SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus, bus,
> devfn);
> > + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
> >
> > if (!idev) {
> > return true;
> > @@ -613,7 +637,7 @@ static bool
> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
> > * Check the host SMMUv3 associated with the dev is compatible with the
> > * QEMU SMMUv3 accel.
> > */
> > - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
> > + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
> > return false;
> > }
> >
> > @@ -867,8 +891,12 @@ bool
> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
> >
> > void smmuv3_accel_reset(SMMUv3State *s)
> > {
> > - /* Attach a HWPT based on GBPA reset value */
> > - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> > + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel->auto_finalised)
> {
> > + error_report("AUTO mode specified but properties not finalised.");
> > + exit(1);
>
> How can we get here?
This is reached from the SMMUv3 reset handler when auto mode is
specified but no cold-plugged device has been attached to finalise the
accelerated SMMUv3 properties.
If no such device is present, "auto_finalised" remains false and we hit
this path during reset.
Cédric mentioned that we should not exit during the reset phase. If that
is the case, we likely need another way to handle the scenario where
auto mode is specified but no cold-plugged device is present.
Thanks,
Shameer
> > + }
> > + /* Attach a HWPT based on GBPA reset value */
> > + smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> > }
> >
> > static void smmuv3_accel_as_init(SMMUv3State *s)
> > diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> > index dba6c71de5..3c1cd55714 100644
> > --- a/hw/arm/smmuv3-accel.h
> > +++ b/hw/arm/smmuv3-accel.h
> > @@ -26,6 +26,8 @@ typedef struct SMMUv3AccelState {
> > uint32_t bypass_hwpt_id;
> > uint32_t abort_hwpt_id;
> > QLIST_HEAD(, SMMUv3AccelDevice) device_list;
> > + bool auto_mode;
> > + bool auto_finalised;
> > } SMMUv3AccelState;
> >
> > typedef struct SMMUS1Hwpt {
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-10 7:42 ` Cédric Le Goater
2026-03-10 8:40 ` Shameer Kolothum Thodi
@ 2026-03-10 17:13 ` Nathan Chen
1 sibling, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-10 17:13 UTC (permalink / raw)
To: Cédric Le Goater, qemu-devel, qemu-arm
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Eric Blake,
Markus Armbruster, Shameer Kolothum
On 3/10/2026 12:42 AM, Cédric Le Goater wrote:
>>
>> Subsequent patches will make use of this helper to set the
>> values when we convert the values to OnOffAuto. New auto_mode
>> and auto_finalised bool members are added to SMMUv3AccelState.
>> smmuv3_accel_init() will set auto_mode to true when 'auto' is
>> detected for the accel SMMUv3 properties.
>> smmuv3_accel_auto_finalise() will set auto_finalised to true
>> after all 'auto' properties are resolved, and subsequent
>> calls to this function will return early if auto_finalised is
>> set to true.
>>
>> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
>> hw/arm/smmuv3-accel.h | 2 ++
>> 2 files changed, 35 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 17306cd04b..617629bacd 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
>> return map[oas];
>> }
>> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> + struct
>> iommu_hw_info_arm_smmuv3 *info) {
>> + SMMUv3AccelState *accel = s->s_accel;
>> +
>> + /* Return if no auto for any or finalised already */
>> + if (!accel->auto_mode || accel->auto_finalised) {
>> + return;
>> + }
>> +
>> + /* We can't update if device is hotplugged */
>> + if (DEVICE(pdev)->hotplugged) {
>> + warn_report("arm-smmuv3: 'auto' feature property detected,
>> but host "
>> + "value cannot be applied for hot-plugged device;
>> using "
>> + "existing value");
>
> Please add an 'Error **' parameter instead.
Ok, if we decide to keep this hotplug check I will use the 'Error **'
parameter instead here in the next revision. Per Shameer's reply to
Markus on this patch, we may end up removing this check as we plan to
fail boot if auto_mode is set but auto_finalised is still false from the
lack of a cold-plugged device.
>
>> + return;
>> + }
>> +
>> + accel->auto_finalised = true;
>> +}
>> +
>> static bool
>> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> struct iommu_hw_info_arm_smmuv3 *info,
>> + PCIDevice *pdev,
>> Error **errp)
>> {
>> + smmuv3_accel_auto_finalise(s, pdev, info);
>> +
>> /* QEMU SMMUv3 supports both linear and 2-level stream tables */
>> if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
>> FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
>> @@ -124,7 +147,7 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> static bool
>> smmuv3_accel_hw_compatible(SMMUv3State *s, HostIOMMUDeviceIOMMUFD
>> *idev,
>> - Error **errp)
>> + PCIDevice *pdev, Error **errp)
>> {
>> struct iommu_hw_info_arm_smmuv3 info;
>> uint32_t data_type;
>> @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s,
>> HostIOMMUDeviceIOMMUFD *idev,
>> return false;
>> }
>> - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
>> + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
>> return false;
>> }
>> return true;
>> @@ -595,6 +618,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus
>> *bus, void *opaque, int devfn,
>> SMMUv3State *s = ARM_SMMUV3(bs);
>> SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
>> SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus,
>> bus, devfn);
>> + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
>> if (!idev) {
>> return true;
>> @@ -613,7 +637,7 @@ static bool smmuv3_accel_set_iommu_device(PCIBus
>> *bus, void *opaque, int devfn,
>> * Check the host SMMUv3 associated with the dev is compatible
>> with the
>> * QEMU SMMUv3 accel.
>> */
>> - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
>> + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
>> return false;
>> }
>> @@ -867,8 +891,12 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State
>> *s, Error **errp)
>> void smmuv3_accel_reset(SMMUv3State *s)
>> {
>> - /* Attach a HWPT based on GBPA reset value */
>> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
>> + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel-
>> >auto_finalised) {
>> + error_report("AUTO mode specified but properties not
>> finalised.");
>
> This is not a very friendly message for the user.
Agreed, instead of 'properties not finalised' we will note that the
properties were not introspected from host IDR registers, and that a
cold-plugged device attached to the SMMUv3 must be present to do so.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-10 7:05 ` Markus Armbruster
@ 2026-03-10 17:35 ` Nathan Chen
2026-03-11 15:31 ` Eric Auger
1 sibling, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-10 17:35 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/10/2026 12:05 AM, Markus Armbruster wrote:
> Nathan Chen<nathanc@nvidia.com> writes:
>
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Allow accelerated SMMUv3 Address Translation Services support property
>> to be derived from host IOMMU capabilities. Derive host values using
>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>
>> Set the default value of ATS to auto. The default for ATS support used
>> to be set to off, but we change it to match what the host IOMMU
>> properties report.
>>
>> Add a "ats-enabled" read-only property for smmuv3 to address an
>> expected bool for the "ats" property in iort_smmuv3_devices().
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>> hw/arm/smmuv3.c | 12 ++++++++++--
>> hw/arm/virt-acpi-build.c | 2 +-
>> include/hw/arm/smmuv3.h | 2 +-
>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 617629bacd..8fec335557 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> return;
>> }
>>
>> + /* Update ATS if auto from info */
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>> + }
>> +
>> accel->auto_finalised = true;
>> }
>>
>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
>> return false;
>> }
>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
>> + " Services");
>> + return false;
>> + }
>>
>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>
>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>> + /* Only override ATS if user explicitly set ON or OFF */
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>> + }
>>
>> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
>> if (s->oas == SMMU_OAS_48BIT) {
>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>> bs->iommu_ops = &smmuv3_accel_ops;
>> smmuv3_accel_as_init(s);
>> +
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->s_accel->auto_mode = true;
>> + }
>> }
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index 068108e49b..197ba7c77b 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>> smmuv3_accel_idr_override(s);
>> }
>>
>> +static bool get_ats_enabled(Object *obj, Error **errp)
>> +{
>> + SMMUv3State *s = ARM_SMMUV3(obj);
>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>> +}
>> +
>> static void smmuv3_reset(SMMUv3State *s)
>> {
>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "ril can only be disabled if accel=on");
>> return false;
>> }
>> - if (s->ats) {
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> error_setg(errp, "ats can only be enabled if accel=on");
>> return false;
>> }
>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>> /* RIL can be turned off for accel cases */
>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> Is property "ats" accessible via QMP or JSON command line? If yes, this
> is an incompatible change: JSON values false and true no longer work.
Yes it is accessible. I will implement both the ATS and RIL properties
differently, calling object_class_property_add() from
smmuv3_class_init() with an ats property setter function that accepts
both bool and on/off/auto strings, rather than using
DEFINE_PROP_ON_OFF_AUTO() here.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size
2026-03-10 7:21 ` Markus Armbruster
@ 2026-03-10 17:44 ` Nathan Chen
0 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-10 17:44 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Eric Auger, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/10/2026 12:21 AM, Markus Armbruster wrote:
> Nathan Chen<nathanc@nvidia.com> writes:
>
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> 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.
>>
>> Set the default ssidsize value to auto. The default SSID size used
>> to be 0, but we change it to match what the host IOMMU properties
>> report so that users do not have to introspect host IDR1 for the
>> Substream ID support. 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.
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 30 +++++++++++++++++++++++++++---
>> hw/arm/smmuv3.c | 16 ++++++----------
>> include/hw/arm/smmuv3.h | 3 ++-
>> 3 files changed, 35 insertions(+), 14 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 02e3f7a9f3..bd27b0da7c 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -64,6 +64,13 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> FIELD_EX32(info->idr[3], IDR3, RIL));
>> }
>>
>> + /* Update SSIDSIZE if auto from info */
>> + if (s->ssidsize == SSID_SIZE_MODE_AUTO) {
>> + /* Store for get_viommu_flags() to determine PASID support */
>> + s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SSIDSIZE,
>> + FIELD_EX32(info->idr[1], IDR1, SSIDSIZE));
>> + }
>> +
>> accel->auto_finalised = true;
>> }
>>
>> @@ -839,7 +846,10 @@ 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 &&
>> + s->ssidsize != SSID_SIZE_MODE_AUTO) ||
>> + (s->ssidsize == SSID_SIZE_MODE_AUTO &&
>> + FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) {
>> flags |= VIOMMU_FLAG_PASID_SUPPORTED;
>> }
>> return flags;
>> @@ -854,6 +864,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 */
> This relies on how the enum values are ordered in the schema, and on how
> the QAPI generator encodes enums. The latter is fine: we document it in
> docs/devel/qapi-code-gen.rst section "Enumeration types". The former is
> worth a non-doc comment in the schema, like this:
>
> { 'enum': 'SsidSizeMode',
> 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
> '10', '11', '12', '13', '14', '15', '16', '17', '18',
> '19', '20' ] } # order matters, see ssid_size_mode_auto()
>
>
I see, I will include a comment in the schema to make this clear. Thanks!
>> +}
>> +
>> void smmuv3_accel_idr_override(SMMUv3State *s)
>> {
>> if (!s->accel) {
>> @@ -886,7 +906,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 */
>> @@ -955,7 +978,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>> smmuv3_accel_as_init(s);
>>
>> if (s->ats == ON_OFF_AUTO_AUTO ||
>> - s->ril == ON_OFF_AUTO_AUTO) {
>> + s->ril == ON_OFF_AUTO_AUTO ||
>> + s->ssidsize == SSID_SIZE_MODE_AUTO) {
>> s->s_accel->auto_mode = true;
>> }
>> }
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index 7791e5294d..bc03353759 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"
>> @@ -626,7 +627,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");
>> @@ -1985,7 +1986,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;
>> }
>> @@ -2003,11 +2004,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;
>> }
>> @@ -2136,7 +2132,8 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
>> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
>> - DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
>> + DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize,
>> + SSID_SIZE_MODE_AUTO),
> Is property "ssidsize" accessible via QMP or JSON command line? If yes,
> this is an incompatible change: JSON integer values no longer work.
Yes, I will update the SSID size and OAS properties to accept both
integer and string values in the next revision.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-10 7:05 ` Markus Armbruster
2026-03-10 17:35 ` Nathan Chen
@ 2026-03-11 15:31 ` Eric Auger
2026-03-11 17:08 ` Nathan Chen
1 sibling, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-11 15:31 UTC (permalink / raw)
To: Markus Armbruster, Nathan Chen
Cc: qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan, Peter Maydell,
Shannon Zhao, Michael S . Tsirkin, Igor Mammedov, Ani Sinha,
Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/10/26 8:05 AM, Markus Armbruster wrote:
> Nathan Chen <nathanc@nvidia.com> writes:
>
>> From: Nathan Chen <nathanc@nvidia.com>
>>
>> Allow accelerated SMMUv3 Address Translation Services support property
>> to be derived from host IOMMU capabilities. Derive host values using
>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>
>> Set the default value of ATS to auto. The default for ATS support used
>> to be set to off, but we change it to match what the host IOMMU
>> properties report.
>>
>> Add a "ats-enabled" read-only property for smmuv3 to address an
>> expected bool for the "ats" property in iort_smmuv3_devices().
>>
>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>> hw/arm/smmuv3.c | 12 ++++++++++--
>> hw/arm/virt-acpi-build.c | 2 +-
>> include/hw/arm/smmuv3.h | 2 +-
>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 617629bacd..8fec335557 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> return;
>> }
>>
>> + /* Update ATS if auto from info */
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>> + }
>> +
>> accel->auto_finalised = true;
>> }
>>
>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
>> return false;
>> }
>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
>> + " Services");
>> + return false;
>> + }
>>
>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>
>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>> + /* Only override ATS if user explicitly set ON or OFF */
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>> + }
>>
>> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
>> if (s->oas == SMMU_OAS_48BIT) {
>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>> bs->iommu_ops = &smmuv3_accel_ops;
>> smmuv3_accel_as_init(s);
>> +
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->s_accel->auto_mode = true;
>> + }
>> }
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index 068108e49b..197ba7c77b 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>> smmuv3_accel_idr_override(s);
>> }
>>
>> +static bool get_ats_enabled(Object *obj, Error **errp)
>> +{
>> + SMMUv3State *s = ARM_SMMUV3(obj);
>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>> +}
>> +
>> static void smmuv3_reset(SMMUv3State *s)
>> {
>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "ril can only be disabled if accel=on");
>> return false;
>> }
>> - if (s->ats) {
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> error_setg(errp, "ats can only be enabled if accel=on");
>> return false;
>> }
>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>> /* RIL can be turned off for accel cases */
>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> Is property "ats" accessible via QMP or JSON command line? If yes, this
> is an incompatible change: JSON values false and true no longer work.
So what do you recommend to extend the property values. I guess we had
some existing scenarios happening in the past. What is the best way to
proceed?
Eric
>
>> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
>> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
>> };
>> @@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
>> dc->hotpluggable = false;
>> dc->user_creatable = true;
>>
>> + object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
>> +
>> object_class_property_set_description(klass, "accel",
>> "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
>> "configured in nested mode for vfio-pci dev assignment");
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 719d2f994e..6c77fc5f6a 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
>>
>> bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
>> sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
>> - sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
>> + sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
>> pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
>> sbdev = SYS_BUS_DEVICE(obj);
>> sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
>> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
>> index 26b2fc42fd..2ca49ded36 100644
>> --- a/include/hw/arm/smmuv3.h
>> +++ b/include/hw/arm/smmuv3.h
>> @@ -70,7 +70,7 @@ struct SMMUv3State {
>> uint64_t msi_gpa;
>> Error *migration_blocker;
>> bool ril;
>> - bool ats;
>> + OnOffAuto ats;
>> uint8_t oas;
>> uint8_t ssidsize;
>> };
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 15:31 ` Eric Auger
@ 2026-03-11 17:08 ` Nathan Chen
2026-03-11 17:16 ` Eric Auger
2026-03-11 17:24 ` Eric Auger
0 siblings, 2 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-11 17:08 UTC (permalink / raw)
To: eric.auger, Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan, Peter Maydell,
Shannon Zhao, Michael S . Tsirkin, Igor Mammedov, Ani Sinha,
Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/11/2026 8:31 AM, Eric Auger wrote:
> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>> Nathan Chen<nathanc@nvidia.com> writes:
>>
>>> From: Nathan Chen<nathanc@nvidia.com>
>>>
>>> Allow accelerated SMMUv3 Address Translation Services support property
>>> to be derived from host IOMMU capabilities. Derive host values using
>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>
>>> Set the default value of ATS to auto. The default for ATS support used
>>> to be set to off, but we change it to match what the host IOMMU
>>> properties report.
>>>
>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>
>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>>> ---
>>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>>> hw/arm/smmuv3.c | 12 ++++++++++--
>>> hw/arm/virt-acpi-build.c | 2 +-
>>> include/hw/arm/smmuv3.h | 2 +-
>>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>>> index 617629bacd..8fec335557 100644
>>> --- a/hw/arm/smmuv3-accel.c
>>> +++ b/hw/arm/smmuv3-accel.c
>>> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>>> return;
>>> }
>>>
>>> + /* Update ATS if auto from info */
>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>>> + }
>>> +
>>> accel->auto_finalised = true;
>>> }
>>>
>>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
>>> return false;
>>> }
>>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>>> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
>>> + " Services");
>>> + return false;
>>> + }
>>>
>>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
>>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
>>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>>
>>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
>>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>>> + /* Only override ATS if user explicitly set ON or OFF */
>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>>> + }
>>>
>>> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
>>> if (s->oas == SMMU_OAS_48BIT) {
>>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>>> bs->iommu_ops = &smmuv3_accel_ops;
>>> smmuv3_accel_as_init(s);
>>> +
>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>> + s->s_accel->auto_mode = true;
>>> + }
>>> }
>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>> index 068108e49b..197ba7c77b 100644
>>> --- a/hw/arm/smmuv3.c
>>> +++ b/hw/arm/smmuv3.c
>>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>>> smmuv3_accel_idr_override(s);
>>> }
>>>
>>> +static bool get_ats_enabled(Object *obj, Error **errp)
>>> +{
>>> + SMMUv3State *s = ARM_SMMUV3(obj);
>>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>>> +}
>>> +
>>> static void smmuv3_reset(SMMUv3State *s)
>>> {
>>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>>> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>>> error_setg(errp, "ril can only be disabled if accel=on");
>>> return false;
>>> }
>>> - if (s->ats) {
>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>> error_setg(errp, "ats can only be enabled if accel=on");
>>> return false;
>>> }
>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>> /* RIL can be turned off for accel cases */
>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>> Is property "ats" accessible via QMP or JSON command line? If yes, this
>> is an incompatible change: JSON values false and true no longer work.
> So what do you recommend to extend the property values. I guess we had
> some existing scenarios happening in the past. What is the best way to
> proceed?
Is it a requirement to ensure boolean values are still supported when
switching to OnOffAuto? I found that the x86-iommu intremap property had
a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
Should I add a custom property setter that accepts both boolean and
on/off/auto for backward compatibility, or is following the intremap
precedent acceptable? I'm happy to implement either approach.
[0]
https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 17:08 ` Nathan Chen
@ 2026-03-11 17:16 ` Eric Auger
2026-03-11 18:09 ` Pavel Hrdina
2026-03-12 8:39 ` Markus Armbruster
2026-03-11 17:24 ` Eric Auger
1 sibling, 2 replies; 49+ messages in thread
From: Eric Auger @ 2026-03-11 17:16 UTC (permalink / raw)
To: Nathan Chen, Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan, Peter Maydell,
Shannon Zhao, Michael S . Tsirkin, Igor Mammedov, Ani Sinha,
Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/11/26 6:08 PM, Nathan Chen wrote:
>
>
> On 3/11/2026 8:31 AM, Eric Auger wrote:
>> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>>> Nathan Chen<nathanc@nvidia.com> writes:
>>>
>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>
>>>> Allow accelerated SMMUv3 Address Translation Services support property
>>>> to be derived from host IOMMU capabilities. Derive host values using
>>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>>
>>>> Set the default value of ATS to auto. The default for ATS support used
>>>> to be set to off, but we change it to match what the host IOMMU
>>>> properties report.
>>>>
>>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>>
>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>>>> ---
>>>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>>>> hw/arm/smmuv3.c | 12 ++++++++++--
>>>> hw/arm/virt-acpi-build.c | 2 +-
>>>> include/hw/arm/smmuv3.h | 2 +-
>>>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>>>> index 617629bacd..8fec335557 100644
>>>> --- a/hw/arm/smmuv3-accel.c
>>>> +++ b/hw/arm/smmuv3-accel.c
>>>> @@ -52,6 +52,12 @@ static void
>>>> smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>>>> return;
>>>> }
>>>> + /* Update ATS if auto from info */
>>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>>>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>>>> + }
>>>> +
>>>> accel->auto_finalised = true;
>>>> }
>>>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State
>>>> *s,
>>>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5,
>>>> OAS)));
>>>> return false;
>>>> }
>>>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>>>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>>>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>>>> + error_setg(errp, "Host SMMUv3 doesn't support Address
>>>> Translation"
>>>> + " Services");
>>>> + return false;
>>>> + }
>>>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation
>>>> granules */
>>>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>>>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>>>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has
>>>> disabled it */
>>>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by
>>>> property */
>>>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>>>> + /* Only override ATS if user explicitly set ON or OFF */
>>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>>>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>>>> + }
>>>> /* Advertise 48-bit OAS in IDR5 when requested (default is
>>>> 44 bits). */
>>>> if (s->oas == SMMU_OAS_48BIT) {
>>>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>>>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>>>> bs->iommu_ops = &smmuv3_accel_ops;
>>>> smmuv3_accel_as_init(s);
>>>> +
>>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>>> + s->s_accel->auto_mode = true;
>>>> + }
>>>> }
>>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>>> index 068108e49b..197ba7c77b 100644
>>>> --- a/hw/arm/smmuv3.c
>>>> +++ b/hw/arm/smmuv3.c
>>>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>>>> smmuv3_accel_idr_override(s);
>>>> }
>>>> +static bool get_ats_enabled(Object *obj, Error **errp)
>>>> +{
>>>> + SMMUv3State *s = ARM_SMMUV3(obj);
>>>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>>>> +}
>>>> +
>>>> static void smmuv3_reset(SMMUv3State *s)
>>>> {
>>>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>>>> @@ -1971,7 +1977,7 @@ static bool
>>>> smmu_validate_property(SMMUv3State *s, Error **errp)
>>>> error_setg(errp, "ril can only be disabled if
>>>> accel=on");
>>>> return false;
>>>> }
>>>> - if (s->ats) {
>>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>>> error_setg(errp, "ats can only be enabled if accel=on");
>>>> return false;
>>>> }
>>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>>> /* RIL can be turned off for accel cases */
>>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats,
>>>> ON_OFF_AUTO_AUTO),
>>> Is property "ats" accessible via QMP or JSON command line? If yes,
>>> this
>>> is an incompatible change: JSON values false and true no longer work.
>> So what do you recommend to extend the property values. I guess we had
>> some existing scenarios happening in the past. What is the best way to
>> proceed?
>
> Is it a requirement to ensure boolean values are still supported when
> switching to OnOffAuto? I found that the x86-iommu intremap property
> had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
>
> Should I add a custom property setter that accepts both boolean and
> on/off/auto for backward compatibility, or is following the intremap
> precedent acceptable? I'm happy to implement either approach.
>
> [0]
> https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
Maybe we also need to emphasize that libvirt integration is still under
work (and waiting for that conversion to happen at qemu level). So do we
really care about keeping the compat wrt QMP and JSON.
Thanks
Eric
>
> Thanks,
> Nathan
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 17:08 ` Nathan Chen
2026-03-11 17:16 ` Eric Auger
@ 2026-03-11 17:24 ` Eric Auger
1 sibling, 0 replies; 49+ messages in thread
From: Eric Auger @ 2026-03-11 17:24 UTC (permalink / raw)
To: Nathan Chen, Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan, Peter Maydell,
Shannon Zhao, Michael S . Tsirkin, Igor Mammedov, Ani Sinha,
Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/11/26 6:08 PM, Nathan Chen wrote:
>
>
> On 3/11/2026 8:31 AM, Eric Auger wrote:
>> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>>> Nathan Chen<nathanc@nvidia.com> writes:
>>>
>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>
>>>> Allow accelerated SMMUv3 Address Translation Services support property
>>>> to be derived from host IOMMU capabilities. Derive host values using
>>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>>
>>>> Set the default value of ATS to auto. The default for ATS support used
>>>> to be set to off, but we change it to match what the host IOMMU
>>>> properties report.
>>>>
>>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>>
>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>>>> ---
>>>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>>>> hw/arm/smmuv3.c | 12 ++++++++++--
>>>> hw/arm/virt-acpi-build.c | 2 +-
>>>> include/hw/arm/smmuv3.h | 2 +-
>>>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>>>> index 617629bacd..8fec335557 100644
>>>> --- a/hw/arm/smmuv3-accel.c
>>>> +++ b/hw/arm/smmuv3-accel.c
>>>> @@ -52,6 +52,12 @@ static void
>>>> smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>>>> return;
>>>> }
>>>> + /* Update ATS if auto from info */
>>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>>>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>>>> + }
>>>> +
>>>> accel->auto_finalised = true;
>>>> }
>>>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State
>>>> *s,
>>>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5,
>>>> OAS)));
>>>> return false;
>>>> }
>>>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>>>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>>>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>>>> + error_setg(errp, "Host SMMUv3 doesn't support Address
>>>> Translation"
>>>> + " Services");
>>>> + return false;
>>>> + }
>>>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation
>>>> granules */
>>>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>>>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>>>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has
>>>> disabled it */
>>>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by
>>>> property */
>>>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>>>> + /* Only override ATS if user explicitly set ON or OFF */
>>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>>>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>>>> + }
>>>> /* Advertise 48-bit OAS in IDR5 when requested (default is
>>>> 44 bits). */
>>>> if (s->oas == SMMU_OAS_48BIT) {
>>>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>>>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>>>> bs->iommu_ops = &smmuv3_accel_ops;
>>>> smmuv3_accel_as_init(s);
>>>> +
>>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>>>> + s->s_accel->auto_mode = true;
>>>> + }
>>>> }
>>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>>> index 068108e49b..197ba7c77b 100644
>>>> --- a/hw/arm/smmuv3.c
>>>> +++ b/hw/arm/smmuv3.c
>>>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>>>> smmuv3_accel_idr_override(s);
>>>> }
>>>> +static bool get_ats_enabled(Object *obj, Error **errp)
>>>> +{
>>>> + SMMUv3State *s = ARM_SMMUV3(obj);
>>>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>>>> +}
>>>> +
>>>> static void smmuv3_reset(SMMUv3State *s)
>>>> {
>>>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>>>> @@ -1971,7 +1977,7 @@ static bool
>>>> smmu_validate_property(SMMUv3State *s, Error **errp)
>>>> error_setg(errp, "ril can only be disabled if
>>>> accel=on");
>>>> return false;
>>>> }
>>>> - if (s->ats) {
>>>> + if (s->ats == ON_OFF_AUTO_ON) {
>>>> error_setg(errp, "ats can only be enabled if accel=on");
>>>> return false;
>>>> }
>>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>>> /* RIL can be turned off for accel cases */
>>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats,
>>>> ON_OFF_AUTO_AUTO),
>>> Is property "ats" accessible via QMP or JSON command line? If yes,
>>> this
>>> is an incompatible change: JSON values false and true no longer work.
>> So what do you recommend to extend the property values. I guess we had
>> some existing scenarios happening in the past. What is the best way to
>> proceed?
>
> Is it a requirement to ensure boolean values are still supported when
> switching to OnOffAuto? I found that the x86-iommu intremap property
> had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
>
> Should I add a custom property setter that accepts both boolean and
> on/off/auto for backward compatibility, or is following the intremap
> precedent acceptable? I'm happy to implement either approach.
>
> [0]
> https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
For the notice, this happened in 2020:
a924b3d8df55 (HEAD) x86-iommu: switch intr_supported to OnOffAuto type
and the previous bool properties was introduced in 1121e0afdcf (in 2016)
By the way I don't say this is something that is good ;-)
Eric
>
> Thanks,
> Nathan
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
` (7 preceding siblings ...)
2026-03-09 19:21 ` [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS Nathan Chen
@ 2026-03-11 17:43 ` Eric Auger
2026-03-11 17:55 ` Nathan Chen
8 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-11 17:43 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/9/26 8:21 PM, Nathan Chen wrote:
> Hi,
>
> This series introduces support for specifying 'auto' for arm-smmuv3
> accelerated mode's ATS, RIL, SSIDSIZE, and OAS feature properties.
> When set to 'auto', these feature values are derived directly from
> host IOMMU capabilities, avoiding the need for management layers to
> introspect host settings.
>
> Accelerated SMMUv3 Address Translation Services support is derived
> from IDR0, Range Invalidation support is derived from IDR3, Substream
> ID size is derived from IDR1, and output address space is derived from
> IDR5.
>
> Additionally, an OnOffAuto "ats" property is added for vfio-pci devices,
> where setting 'auto' detects the per-device presence of
> IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED from the kernel, and the ATS cap can
> be advertised or hidden by setting 'on' or 'off'. This is dependent
> on Shameer's recent kernel series for reporting effective ATS support
> status [0].
>
> The default values are set to 'auto' for all properties.
>
> A complete branch can be found here:
> https://github.com/NathanChenNVIDIA/qemu/tree/smmuv3-accel-auto
I have just noticed we are missing documentation for smmuv3 accel options in
qemu-options.hx
At the moment we just have:
``-device arm-smmuv3,primary-bus=id``
This is only supported by ``-machine virt`` (ARM).
``primary-bus=id``
Accepts either the default root complex (pcie.0) or a
pxb-pcie based root complex.
Eric
>
> Please take a look and let me know your feedback.
>
> Thanks,
> Nathan
>
> Example usage:
> qemu-system-aarch64 \
> -object iommufd,id=iommufd0 \
> -machine virt,accel=kvm,gic-version=3,ras=on,highmem-mmio-size=4T \
> -cpu host -smp cpus=4 -m size=16G -nographic \
> -object memory-backend-ram,size=16G,id=m0 \
> -numa node,memdev=m0,cpus=0-3,nodeid=0 \
> -numa node,nodeid=1 -numa node,nodeid=2 -numa node,nodeid=3 -numa node,nodeid=4 \
> -numa node,nodeid=5 -numa node,nodeid=6 -numa node,nodeid=7 -numa node,nodeid=8 \
> -device pxb-pcie,id=pcie.1,bus_nr=1,bus=pcie.0,numa_node=0 \
> -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1,accel=on,ats=auto,ssidsize=auto,ril=auto,oas=auto \
> -device pcie-root-port,id=pcie.port1,bus=pcie.1,chassis=1,io-reserve=0 \
> -device vfio-pci-nohotplug,host=0009:06:00.0,bus=pcie.port1,rombar=0,id=dev0,iommufd=iommufd0,ats=auto \
> -object acpi-generic-initiator,id=gi0,pci-dev=dev0,node=1 \
> -object acpi-generic-initiator,id=gi1,pci-dev=dev0,node=2 \
> -object acpi-generic-initiator,id=gi2,pci-dev=dev0,node=3 \
> -object acpi-generic-initiator,id=gi3,pci-dev=dev0,node=4 \
> -object acpi-generic-initiator,id=gi4,pci-dev=dev0,node=5 \
> -object acpi-generic-initiator,id=gi5,pci-dev=dev0,node=6 \
> -object acpi-generic-initiator,id=gi6,pci-dev=dev0,node=7 \
> -object acpi-generic-initiator,id=gi7,pci-dev=dev0,node=8 \
> -bios /usr/share/AAVMF/AAVMF_CODE.fd \
> -device nvme,drive=nvme0,serial=deadbeaf1,bus=pcie.0 \
> -drive file=/var/lib/libvirt/images/guest.qcow2,index=0,media=disk,format=qcow2,if=none,id=nvme0 \
> -device e1000,romfile=/usr/local/share/qemu/efi-e1000.rom,netdev=net0,bus=pcie.0 \
> -netdev user,id=net0,hostfwd=tcp::5558-:22,hostfwd=tcp::5586-:5586
>
> The properties may also be omitted as they are set to auto by default:
>
> -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1,accel=on \
> -device vfio-pci-nohotplug,host=0009:06:00.0,bus=pcie.port1,rombar=0,id=dev0,iommufd=iommufd0 \
>
> Testing:
> Basic sanity testing was performed on an NVIDIA Grace platform with GPU
> device assignment and running CUDA test apps on the guest. Observed the
> feature properties being set based on host IOMMU capabilities and the
> ATS capability for a vfio-pci device reported based on what was reported
> from the host. Additional testing and feedback are welcome.
>
> [0] https://lore.kernel.org/all/20260303150348.233997-1-skolothumtho@nvidia.com/#r
>
> Nathan Chen (8):
> hw/arm/smmuv3-accel: Add helper for resolving auto parameters
> hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
> vfio/pci: Add ats property and mask ATS cap when not exposed
> hw/arm/smmuv3-accel: Introduce _AUTO support for RIL
> qdev: Add a SsidSizeMode property
> hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size
> qdev: Add an OasMode property
> hw/arm/smmuv3-accel: Introduce _AUTO support for OAS
>
> backends/iommufd.c | 15 +++
> hw/arm/smmuv3-accel.c | 118 ++++++++++++++++++++---
> hw/arm/smmuv3-accel.h | 2 +
> hw/arm/smmuv3.c | 43 +++++----
> hw/arm/virt-acpi-build.c | 2 +-
> hw/core/qdev-properties-system.c | 27 ++++++
> hw/vfio/pci.c | 63 ++++++++++++
> hw/vfio/pci.h | 1 +
> include/hw/arm/smmuv3.h | 9 +-
> include/hw/core/qdev-properties-system.h | 6 ++
> include/system/host_iommu_device.h | 10 ++
> qapi/misc-arm.json | 31 ++++++
> qapi/pragma.json | 1 +
> 13 files changed, 292 insertions(+), 36 deletions(-)
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
2026-03-10 7:05 ` Markus Armbruster
@ 2026-03-11 17:46 ` Eric Auger
2026-03-11 17:53 ` Nathan Chen
2026-03-11 18:10 ` Eric Auger
2 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-11 17:46 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/9/26 8:21 PM, Nathan Chen wrote:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Allow accelerated SMMUv3 Address Translation Services support property
> to be derived from host IOMMU capabilities. Derive host values using
> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>
> Set the default value of ATS to auto. The default for ATS support used
> to be set to off, but we change it to match what the host IOMMU
> properties report.
>
> Add a "ats-enabled" read-only property for smmuv3 to address an
> expected bool for the "ats" property in iort_smmuv3_devices().
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
> hw/arm/smmuv3.c | 12 ++++++++++--
> hw/arm/virt-acpi-build.c | 2 +-
> include/hw/arm/smmuv3.h | 2 +-
> 4 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 617629bacd..8fec335557 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> return;
> }
>
> + /* Update ATS if auto from info */
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
> + FIELD_EX32(info->idr[0], IDR0, ATS));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
> return false;
> }
> + /* Check ATS value opted is compatible with Host SMMUv3 */
> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
> + " Services");
> + return false;
> + }
>
> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>
> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
> + /* Only override ATS if user explicitly set ON or OFF */
> + if (s->ats == ON_OFF_AUTO_ON) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
> + } else if (s->ats == ON_OFF_AUTO_OFF) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
> + }
>
> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
> if (s->oas == SMMU_OAS_48BIT) {
> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> s->s_accel = g_new0(SMMUv3AccelState, 1);
> bs->iommu_ops = &smmuv3_accel_ops;
> smmuv3_accel_as_init(s);
> +
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->s_accel->auto_mode = true;
> + }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 068108e49b..197ba7c77b 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
> smmuv3_accel_idr_override(s);
> }
>
> +static bool get_ats_enabled(Object *obj, Error **errp)
> +{
> + SMMUv3State *s = ARM_SMMUV3(obj);
> + return FIELD_EX32(s->idr[0], IDR0, ATS);
> +}
> +
> static void smmuv3_reset(SMMUv3State *s)
> {
> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "ril can only be disabled if accel=on");
> return false;
> }
> - if (s->ats) {
> + if (s->ats == ON_OFF_AUTO_ON) {
> error_setg(errp, "ats can only be enabled if accel=on");
> return false;
> }
> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> /* RIL can be turned off for accel cases */
> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
In general you cannot change the default value like that. This requires
compat handling
in virt machine: See
https://lore.kernel.org/all/20240307134445.92296-4-eric.auger@redhat.com/
for instance
Eric
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> };
> @@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
> dc->hotpluggable = false;
> dc->user_creatable = true;
>
> + object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
> +
> object_class_property_set_description(klass, "accel",
> "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
> "configured in nested mode for vfio-pci dev assignment");
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 719d2f994e..6c77fc5f6a 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
>
> bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
> sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
> - sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
> + sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
> pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
> sbdev = SYS_BUS_DEVICE(obj);
> sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 26b2fc42fd..2ca49ded36 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -70,7 +70,7 @@ struct SMMUv3State {
> uint64_t msi_gpa;
> Error *migration_blocker;
> bool ril;
> - bool ats;
> + OnOffAuto ats;
> uint8_t oas;
> uint8_t ssidsize;
> };
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 17:46 ` Eric Auger
@ 2026-03-11 17:53 ` Nathan Chen
0 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-11 17:53 UTC (permalink / raw)
To: eric.auger, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/11/2026 10:46 AM, Eric Auger wrote:
>
> On 3/9/26 8:21 PM, Nathan Chen wrote:
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Allow accelerated SMMUv3 Address Translation Services support property
>> to be derived from host IOMMU capabilities. Derive host values using
>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>
>> Set the default value of ATS to auto. The default for ATS support used
>> to be set to off, but we change it to match what the host IOMMU
>> properties report.
>>
>> Add a "ats-enabled" read-only property for smmuv3 to address an
>> expected bool for the "ats" property in iort_smmuv3_devices().
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>> hw/arm/smmuv3.c | 12 ++++++++++--
>> hw/arm/virt-acpi-build.c | 2 +-
>> include/hw/arm/smmuv3.h | 2 +-
>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 617629bacd..8fec335557 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> return;
>> }
>>
>> + /* Update ATS if auto from info */
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>> + }
>> +
>> accel->auto_finalised = true;
>> }
>>
>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
>> return false;
>> }
>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
>> + " Services");
>> + return false;
>> + }
>>
>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>
>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>> + /* Only override ATS if user explicitly set ON or OFF */
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>> + }
>>
>> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
>> if (s->oas == SMMU_OAS_48BIT) {
>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>> bs->iommu_ops = &smmuv3_accel_ops;
>> smmuv3_accel_as_init(s);
>> +
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->s_accel->auto_mode = true;
>> + }
>> }
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index 068108e49b..197ba7c77b 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>> smmuv3_accel_idr_override(s);
>> }
>>
>> +static bool get_ats_enabled(Object *obj, Error **errp)
>> +{
>> + SMMUv3State *s = ARM_SMMUV3(obj);
>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>> +}
>> +
>> static void smmuv3_reset(SMMUv3State *s)
>> {
>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "ril can only be disabled if accel=on");
>> return false;
>> }
>> - if (s->ats) {
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> error_setg(errp, "ats can only be enabled if accel=on");
>> return false;
>> }
>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>> /* RIL can be turned off for accel cases */
>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> In general you cannot change the default value like that. This requires
> compat handling
> in virt machine: See
> https://lore.kernel.org/all/20240307134445.92296-4-eric.auger@redhat.com/
> for instance
Ok, I will handle the default value change similarly in the next
revision to account for virt machine compat handling.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties
2026-03-11 17:43 ` [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Eric Auger
@ 2026-03-11 17:55 ` Nathan Chen
2026-03-11 18:25 ` Eric Auger
0 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-11 17:55 UTC (permalink / raw)
To: eric.auger, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/11/2026 10:43 AM, Eric Auger wrote:
>
> On 3/9/26 8:21 PM, Nathan Chen wrote:
>> Hi,
>>
>> This series introduces support for specifying 'auto' for arm-smmuv3
>> accelerated mode's ATS, RIL, SSIDSIZE, and OAS feature properties.
>> When set to 'auto', these feature values are derived directly from
>> host IOMMU capabilities, avoiding the need for management layers to
>> introspect host settings.
>>
>> Accelerated SMMUv3 Address Translation Services support is derived
>> from IDR0, Range Invalidation support is derived from IDR3, Substream
>> ID size is derived from IDR1, and output address space is derived from
>> IDR5.
>>
>> Additionally, an OnOffAuto "ats" property is added for vfio-pci devices,
>> where setting 'auto' detects the per-device presence of
>> IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED from the kernel, and the ATS cap can
>> be advertised or hidden by setting 'on' or 'off'. This is dependent
>> on Shameer's recent kernel series for reporting effective ATS support
>> status [0].
>>
>> The default values are set to 'auto' for all properties.
>>
>> A complete branch can be found here:
>> https://github.com/NathanChenNVIDIA/qemu/tree/smmuv3-accel-auto
> I have just noticed we are missing documentation for smmuv3 accel options in
>
> qemu-options.hx
>
> At the moment we just have:
>
> ``-device arm-smmuv3,primary-bus=id``
> This is only supported by ``-machine virt`` (ARM).
>
> ``primary-bus=id``
> Accepts either the default root complex (pcie.0) or a
> pxb-pcie based root complex.
I will add a commit to include documentation for the smmuv3 accel
options in the next refresh.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 17:16 ` Eric Auger
@ 2026-03-11 18:09 ` Pavel Hrdina
2026-03-12 8:39 ` Markus Armbruster
1 sibling, 0 replies; 49+ messages in thread
From: Pavel Hrdina @ 2026-03-11 18:09 UTC (permalink / raw)
To: Eric Auger
Cc: Nathan Chen, Markus Armbruster, qemu-devel, qemu-arm, Yi Liu,
Zhenzhong Duan, Peter Maydell, Shannon Zhao, Michael S . Tsirkin,
Igor Mammedov, Ani Sinha, Paolo Bonzini, Daniel P.Berrangé,
Alex Williamson, Cédric Le Goater, Eric Blake
[-- Attachment #1: Type: text/plain, Size: 7036 bytes --]
On Wed, Mar 11, 2026 at 06:16:09PM +0100, Eric Auger wrote:
>
>
> On 3/11/26 6:08 PM, Nathan Chen wrote:
> >
> >
> > On 3/11/2026 8:31 AM, Eric Auger wrote:
> >> On 3/10/26 8:05 AM, Markus Armbruster wrote:
> >>> Nathan Chen<nathanc@nvidia.com> writes:
> >>>
> >>>> From: Nathan Chen<nathanc@nvidia.com>
> >>>>
> >>>> Allow accelerated SMMUv3 Address Translation Services support property
> >>>> to be derived from host IOMMU capabilities. Derive host values using
> >>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
> >>>>
> >>>> Set the default value of ATS to auto. The default for ATS support used
> >>>> to be set to off, but we change it to match what the host IOMMU
> >>>> properties report.
> >>>>
> >>>> Add a "ats-enabled" read-only property for smmuv3 to address an
> >>>> expected bool for the "ats" property in iort_smmuv3_devices().
> >>>>
> >>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
> >>>> ---
> >>>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
> >>>> hw/arm/smmuv3.c | 12 ++++++++++--
> >>>> hw/arm/virt-acpi-build.c | 2 +-
> >>>> include/hw/arm/smmuv3.h | 2 +-
> >>>> 4 files changed, 35 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> >>>> index 617629bacd..8fec335557 100644
> >>>> --- a/hw/arm/smmuv3-accel.c
> >>>> +++ b/hw/arm/smmuv3-accel.c
> >>>> @@ -52,6 +52,12 @@ static void
> >>>> smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> >>>> return;
> >>>> }
> >>>> + /* Update ATS if auto from info */
> >>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
> >>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
> >>>> + FIELD_EX32(info->idr[0], IDR0, ATS));
> >>>> + }
> >>>> +
> >>>> accel->auto_finalised = true;
> >>>> }
> >>>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State
> >>>> *s,
> >>>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5,
> >>>> OAS)));
> >>>> return false;
> >>>> }
> >>>> + /* Check ATS value opted is compatible with Host SMMUv3 */
> >>>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
> >>>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
> >>>> + error_setg(errp, "Host SMMUv3 doesn't support Address
> >>>> Translation"
> >>>> + " Services");
> >>>> + return false;
> >>>> + }
> >>>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation
> >>>> granules */
> >>>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
> >>>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> >>>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has
> >>>> disabled it */
> >>>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
> >>>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by
> >>>> property */
> >>>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
> >>>> + /* Only override ATS if user explicitly set ON or OFF */
> >>>> + if (s->ats == ON_OFF_AUTO_ON) {
> >>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
> >>>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
> >>>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
> >>>> + }
> >>>> /* Advertise 48-bit OAS in IDR5 when requested (default is
> >>>> 44 bits). */
> >>>> if (s->oas == SMMU_OAS_48BIT) {
> >>>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> >>>> s->s_accel = g_new0(SMMUv3AccelState, 1);
> >>>> bs->iommu_ops = &smmuv3_accel_ops;
> >>>> smmuv3_accel_as_init(s);
> >>>> +
> >>>> + if (s->ats == ON_OFF_AUTO_AUTO) {
> >>>> + s->s_accel->auto_mode = true;
> >>>> + }
> >>>> }
> >>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> >>>> index 068108e49b..197ba7c77b 100644
> >>>> --- a/hw/arm/smmuv3.c
> >>>> +++ b/hw/arm/smmuv3.c
> >>>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
> >>>> smmuv3_accel_idr_override(s);
> >>>> }
> >>>> +static bool get_ats_enabled(Object *obj, Error **errp)
> >>>> +{
> >>>> + SMMUv3State *s = ARM_SMMUV3(obj);
> >>>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
> >>>> +}
> >>>> +
> >>>> static void smmuv3_reset(SMMUv3State *s)
> >>>> {
> >>>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
> >>>> @@ -1971,7 +1977,7 @@ static bool
> >>>> smmu_validate_property(SMMUv3State *s, Error **errp)
> >>>> error_setg(errp, "ril can only be disabled if
> >>>> accel=on");
> >>>> return false;
> >>>> }
> >>>> - if (s->ats) {
> >>>> + if (s->ats == ON_OFF_AUTO_ON) {
> >>>> error_setg(errp, "ats can only be enabled if accel=on");
> >>>> return false;
> >>>> }
> >>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
> >>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> >>>> /* RIL can be turned off for accel cases */
> >>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> >>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
> >>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats,
> >>>> ON_OFF_AUTO_AUTO),
> >>> Is property "ats" accessible via QMP or JSON command line? If yes,
> >>> this
> >>> is an incompatible change: JSON values false and true no longer work.
> >> So what do you recommend to extend the property values. I guess we had
> >> some existing scenarios happening in the past. What is the best way to
> >> proceed?
> >
> > Is it a requirement to ensure boolean values are still supported when
> > switching to OnOffAuto? I found that the x86-iommu intremap property
> > had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
> >
> > Should I add a custom property setter that accepts both boolean and
> > on/off/auto for backward compatibility, or is following the intremap
> > precedent acceptable? I'm happy to implement either approach.
> >
> > [0]
> > https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
>
> Maybe we also need to emphasize that libvirt integration is still under
> work (and waiting for that conversion to happen at qemu level). So do we
> really care about keeping the compat wrt QMP and JSON.
> Thanks
I think it should be safe and to change the type of the property, it's
not part of any QEMU release and not even implemented in libvirt.
Pavel
>
> Eric
> >
> > Thanks,
> > Nathan
> >
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
2026-03-10 7:05 ` Markus Armbruster
2026-03-11 17:46 ` Eric Auger
@ 2026-03-11 18:10 ` Eric Auger
2026-03-11 18:21 ` Nathan Chen
2 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-11 18:10 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
Hi Nathan,
On 3/9/26 8:21 PM, Nathan Chen wrote:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Allow accelerated SMMUv3 Address Translation Services support property
> to be derived from host IOMMU capabilities. Derive host values using
> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>
> Set the default value of ATS to auto. The default for ATS support used
> to be set to off, but we change it to match what the host IOMMU
> properties report.
>
> Add a "ats-enabled" read-only property for smmuv3 to address an
> expected bool for the "ats" property in iort_smmuv3_devices().
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
> hw/arm/smmuv3.c | 12 ++++++++++--
> hw/arm/virt-acpi-build.c | 2 +-
> include/hw/arm/smmuv3.h | 2 +-
> 4 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 617629bacd..8fec335557 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
> return;
> }
>
> + /* Update ATS if auto from info */
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
> + FIELD_EX32(info->idr[0], IDR0, ATS));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
> return false;
> }
> + /* Check ATS value opted is compatible with Host SMMUv3 */
> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
> + " Services");
> + return false;
> + }
Shouldn't this chunk be a separate fix for previous accel SMMU series?
>
> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>
> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
> + /* Only override ATS if user explicitly set ON or OFF */
> + if (s->ats == ON_OFF_AUTO_ON) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
> + } else if (s->ats == ON_OFF_AUTO_OFF) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
> + }
>
> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
> if (s->oas == SMMU_OAS_48BIT) {
> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> s->s_accel = g_new0(SMMUv3AccelState, 1);
> bs->iommu_ops = &smmuv3_accel_ops;
> smmuv3_accel_as_init(s);
> +
> + if (s->ats == ON_OFF_AUTO_AUTO) {
> + s->s_accel->auto_mode = true;
> + }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 068108e49b..197ba7c77b 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
> smmuv3_accel_idr_override(s);
> }
>
> +static bool get_ats_enabled(Object *obj, Error **errp)
> +{
> + SMMUv3State *s = ARM_SMMUV3(obj);
> + return FIELD_EX32(s->idr[0], IDR0, ATS);
> +}
> +
> static void smmuv3_reset(SMMUv3State *s)
> {
> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
> error_setg(errp, "ril can only be disabled if accel=on");
> return false;
> }
> - if (s->ats) {
> + if (s->ats == ON_OFF_AUTO_ON) {
> error_setg(errp, "ats can only be enabled if accel=on");
> return false;
> }
> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> /* RIL can be turned off for accel cases */
> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> };
> @@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
> dc->hotpluggable = false;
> dc->user_creatable = true;
>
> + object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
> +
> object_class_property_set_description(klass, "accel",
> "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
> "configured in nested mode for vfio-pci dev assignment");
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 719d2f994e..6c77fc5f6a 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
>
> bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
> sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
> - sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
> + sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
are we obliged to use a prop here.
we can dynamic cast to the TYPE_ARM_SMMUV3 and use an exported helper, no?
> pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
> sbdev = SYS_BUS_DEVICE(obj);
> sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 26b2fc42fd..2ca49ded36 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -70,7 +70,7 @@ struct SMMUv3State {
> uint64_t msi_gpa;
> Error *migration_blocker;
> bool ril;
> - bool ats;
> + OnOffAuto ats;
> uint8_t oas;
> uint8_t ssidsize;
> };
Thanks
Eric
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 7/8] qdev: Add an OasMode property
2026-03-09 19:21 ` [RFC PATCH 7/8] qdev: Add an OasMode property Nathan Chen
@ 2026-03-11 18:20 ` Eric Auger
2026-03-11 18:24 ` Nathan Chen
0 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-11 18:20 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
Hi Nathan,
On 3/9/26 8:21 PM, Nathan Chen wrote:
> From: Nathan Chen <nathanc@nvidia.com>
>
> Introduce a new enum type property allowing to set an Output Address
> Size. Values are auto, 44, and 48, where a value of N specifies an
> N-bit OAS.
>
> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> ---
> hw/core/qdev-properties-system.c | 13 +++++++++++++
> include/hw/core/qdev-properties-system.h | 3 +++
> qapi/misc-arm.json | 16 ++++++++++++++++
> 3 files changed, 32 insertions(+)
>
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 4aca1d4326..a805ee2e1f 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
> .set_default_value = qdev_propinfo_set_default_value_enum,
> };
>
> +/* --- OasMode --- */
> +
> +QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
> +
> +const PropertyInfo qdev_prop_oas_mode = {
> + .type = "OasMode",
> + .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
> + .enum_table = &OasMode_lookup,
> + .get = qdev_propinfo_get_enum,
> + .set = qdev_propinfo_set_enum,
> + .set_default_value = qdev_propinfo_set_default_value_enum,
> +};
> +
> /* --- Reserved Region --- */
>
> /*
> diff --git a/include/hw/core/qdev-properties-system.h b/include/hw/core/qdev-properties-system.h
> index 4708885164..2cbea16d61 100644
> --- a/include/hw/core/qdev-properties-system.h
> +++ b/include/hw/core/qdev-properties-system.h
> @@ -15,6 +15,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
> extern const PropertyInfo qdev_prop_granule_mode;
> extern const PropertyInfo qdev_prop_zero_page_detection;
> extern const PropertyInfo qdev_prop_ssidsize_mode;
> +extern const PropertyInfo qdev_prop_oas_mode;
> extern const PropertyInfo qdev_prop_losttickpolicy;
> extern const PropertyInfo qdev_prop_blockdev_on_error;
> extern const PropertyInfo qdev_prop_bios_chs_trans;
> @@ -64,6 +65,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
> ZeroPageDetection)
> #define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
> +#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
> + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
> #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
> LostTickPolicy)
> diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
> index b372a3661b..76b6965502 100644
> --- a/qapi/misc-arm.json
> +++ b/qapi/misc-arm.json
> @@ -60,3 +60,19 @@
> { 'enum': 'SsidSizeMode',
> 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
> '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] }
> +
> +##
> +# @OasMode:
> +#
> +# SMMUv3 Output Address Size configuration mode.
> +#
> +# @auto: derive from host IOMMU capabilities
> +#
> +# @44: 44-bit output address size
> +#
> +# @48: 48-bit output address size
> +#
> +# Since: 11.0
> +##
> +{ 'enum': 'OasMode',
> + 'data': [ 'auto', '44', '48' ] }
you also miss other enum values
Thanks
Eric
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 18:10 ` Eric Auger
@ 2026-03-11 18:21 ` Nathan Chen
0 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-11 18:21 UTC (permalink / raw)
To: eric.auger, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/11/2026 11:10 AM, Eric Auger wrote:
> On 3/9/26 8:21 PM, Nathan Chen wrote:
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Allow accelerated SMMUv3 Address Translation Services support property
>> to be derived from host IOMMU capabilities. Derive host values using
>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>
>> Set the default value of ATS to auto. The default for ATS support used
>> to be set to off, but we change it to match what the host IOMMU
>> properties report.
>>
>> Add a "ats-enabled" read-only property for smmuv3 to address an
>> expected bool for the "ats" property in iort_smmuv3_devices().
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/arm/smmuv3-accel.c | 25 +++++++++++++++++++++++--
>> hw/arm/smmuv3.c | 12 ++++++++++--
>> hw/arm/virt-acpi-build.c | 2 +-
>> include/hw/arm/smmuv3.h | 2 +-
>> 4 files changed, 35 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> index 617629bacd..8fec335557 100644
>> --- a/hw/arm/smmuv3-accel.c
>> +++ b/hw/arm/smmuv3-accel.c
>> @@ -52,6 +52,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> return;
>> }
>>
>> + /* Update ATS if auto from info */
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS,
>> + FIELD_EX32(info->idr[0], IDR0, ATS));
>> + }
>> +
>> accel->auto_finalised = true;
>> }
>>
>> @@ -124,6 +130,13 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>> smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS)));
>> return false;
>> }
>> + /* Check ATS value opted is compatible with Host SMMUv3 */
>> + if (FIELD_EX32(info->idr[0], IDR0, ATS) <
>> + FIELD_EX32(s->idr[0], IDR0, ATS)) {
>> + error_setg(errp, "Host SMMUv3 doesn't support Address Translation"
>> + " Services");
>> + return false;
>> + }
> Shouldn't this chunk be a separate fix for previous accel SMMU series?
>
Yes, I'll separate this out to be a separate commit in the next refresh.
>>
>> /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */
>> if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=
>> @@ -844,8 +857,12 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
>> /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
>> s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
>>
>> - /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */
>> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, s->ats);
>> + /* Only override ATS if user explicitly set ON or OFF */
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 1);
>> + } else if (s->ats == ON_OFF_AUTO_OFF) {
>> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ATS, 0);
>> + }
>>
>> /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */
>> if (s->oas == SMMU_OAS_48BIT) {
>> @@ -923,4 +940,8 @@ void smmuv3_accel_init(SMMUv3State *s)
>> s->s_accel = g_new0(SMMUv3AccelState, 1);
>> bs->iommu_ops = &smmuv3_accel_ops;
>> smmuv3_accel_as_init(s);
>> +
>> + if (s->ats == ON_OFF_AUTO_AUTO) {
>> + s->s_accel->auto_mode = true;
>> + }
>> }
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index 068108e49b..197ba7c77b 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -317,6 +317,12 @@ static void smmuv3_init_id_regs(SMMUv3State *s)
>> smmuv3_accel_idr_override(s);
>> }
>>
>> +static bool get_ats_enabled(Object *obj, Error **errp)
>> +{
>> + SMMUv3State *s = ARM_SMMUV3(obj);
>> + return FIELD_EX32(s->idr[0], IDR0, ATS);
>> +}
>> +
>> static void smmuv3_reset(SMMUv3State *s)
>> {
>> s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
>> @@ -1971,7 +1977,7 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp)
>> error_setg(errp, "ril can only be disabled if accel=on");
>> return false;
>> }
>> - if (s->ats) {
>> + if (s->ats == ON_OFF_AUTO_ON) {
>> error_setg(errp, "ats can only be enabled if accel=on");
>> return false;
>> }
>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>> /* RIL can be turned off for accel cases */
>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
>> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
>> };
>> @@ -2153,6 +2159,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
>> dc->hotpluggable = false;
>> dc->user_creatable = true;
>>
>> + object_class_property_add_bool(klass, "ats-enabled", get_ats_enabled, NULL);
>> +
>> object_class_property_set_description(klass, "accel",
>> "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be "
>> "configured in nested mode for vfio-pci dev assignment");
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 719d2f994e..6c77fc5f6a 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -402,7 +402,7 @@ static int iort_smmuv3_devices(Object *obj, void *opaque)
>>
>> bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
>> sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
>> - sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
>> + sdev.ats = object_property_get_bool(obj, "ats-enabled", &error_abort);
> are we obliged to use a prop here.
> we can dynamic cast to the TYPE_ARM_SMMUV3 and use an exported helper, no?
I'll look into replacing this ats-enabled prop with a helper that
accepts the dynamic casted TYPE_ARM_SMMUV3 object and determines whether
ATS support is being advertised.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 7/8] qdev: Add an OasMode property
2026-03-11 18:20 ` Eric Auger
@ 2026-03-11 18:24 ` Nathan Chen
2026-03-12 9:29 ` Eric Auger
0 siblings, 1 reply; 49+ messages in thread
From: Nathan Chen @ 2026-03-11 18:24 UTC (permalink / raw)
To: eric.auger, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
Hi Eric,
On 3/11/2026 11:20 AM, Eric Auger wrote:
> Hi Nathan,
>
> On 3/9/26 8:21 PM, Nathan Chen wrote:
>> From: Nathan Chen<nathanc@nvidia.com>
>>
>> Introduce a new enum type property allowing to set an Output Address
>> Size. Values are auto, 44, and 48, where a value of N specifies an
>> N-bit OAS.
>>
>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>> ---
>> hw/core/qdev-properties-system.c | 13 +++++++++++++
>> include/hw/core/qdev-properties-system.h | 3 +++
>> qapi/misc-arm.json | 16 ++++++++++++++++
>> 3 files changed, 32 insertions(+)
>>
>> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
>> index 4aca1d4326..a805ee2e1f 100644
>> --- a/hw/core/qdev-properties-system.c
>> +++ b/hw/core/qdev-properties-system.c
>> @@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
>> .set_default_value = qdev_propinfo_set_default_value_enum,
>> };
>>
>> +/* --- OasMode --- */
>> +
>> +QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
>> +
>> +const PropertyInfo qdev_prop_oas_mode = {
>> + .type = "OasMode",
>> + .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
>> + .enum_table = &OasMode_lookup,
>> + .get = qdev_propinfo_get_enum,
>> + .set = qdev_propinfo_set_enum,
>> + .set_default_value = qdev_propinfo_set_default_value_enum,
>> +};
>> +
>> /* --- Reserved Region --- */
>>
>> /*
>> diff --git a/include/hw/core/qdev-properties-system.h b/include/hw/core/qdev-properties-system.h
>> index 4708885164..2cbea16d61 100644
>> --- a/include/hw/core/qdev-properties-system.h
>> +++ b/include/hw/core/qdev-properties-system.h
>> @@ -15,6 +15,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
>> extern const PropertyInfo qdev_prop_granule_mode;
>> extern const PropertyInfo qdev_prop_zero_page_detection;
>> extern const PropertyInfo qdev_prop_ssidsize_mode;
>> +extern const PropertyInfo qdev_prop_oas_mode;
>> extern const PropertyInfo qdev_prop_losttickpolicy;
>> extern const PropertyInfo qdev_prop_blockdev_on_error;
>> extern const PropertyInfo qdev_prop_bios_chs_trans;
>> @@ -64,6 +65,8 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
>> ZeroPageDetection)
>> #define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode, SsidSizeMode)
>> +#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
>> + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
>> #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
>> LostTickPolicy)
>> diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
>> index b372a3661b..76b6965502 100644
>> --- a/qapi/misc-arm.json
>> +++ b/qapi/misc-arm.json
>> @@ -60,3 +60,19 @@
>> { 'enum': 'SsidSizeMode',
>> 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
>> '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20' ] }
>> +
>> +##
>> +# @OasMode:
>> +#
>> +# SMMUv3 Output Address Size configuration mode.
>> +#
>> +# @auto: derive from host IOMMU capabilities
>> +#
>> +# @44: 44-bit output address size
>> +#
>> +# @48: 48-bit output address size
>> +#
>> +# Since: 11.0
>> +##
>> +{ 'enum': 'OasMode',
>> + 'data': [ 'auto', '44', '48' ] }
> you also miss other enum values
I left out the other possible OAS values because only 44 and 48 are
supported per the previous accel SMMUv3 series. Should we still include
the other possible OAS values according to the SMMUv3 spec? If we do, we
would end up hitting that check for 44 or 48 bit OAS when a different
value is specified.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties
2026-03-11 17:55 ` Nathan Chen
@ 2026-03-11 18:25 ` Eric Auger
0 siblings, 0 replies; 49+ messages in thread
From: Eric Auger @ 2026-03-11 18:25 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/11/26 6:55 PM, Nathan Chen wrote:
>
>
> On 3/11/2026 10:43 AM, Eric Auger wrote:
>>
>> On 3/9/26 8:21 PM, Nathan Chen wrote:
>>> Hi,
>>>
>>> This series introduces support for specifying 'auto' for arm-smmuv3
>>> accelerated mode's ATS, RIL, SSIDSIZE, and OAS feature properties.
>>> When set to 'auto', these feature values are derived directly from
>>> host IOMMU capabilities, avoiding the need for management layers to
>>> introspect host settings.
>>>
>>> Accelerated SMMUv3 Address Translation Services support is derived
>>> from IDR0, Range Invalidation support is derived from IDR3, Substream
>>> ID size is derived from IDR1, and output address space is derived from
>>> IDR5.
>>>
>>> Additionally, an OnOffAuto "ats" property is added for vfio-pci
>>> devices,
>>> where setting 'auto' detects the per-device presence of
>>> IOMMU_HW_CAP_PCI_ATS_NOT_SUPPORTED from the kernel, and the ATS cap can
>>> be advertised or hidden by setting 'on' or 'off'. This is dependent
>>> on Shameer's recent kernel series for reporting effective ATS support
>>> status [0].
>>>
>>> The default values are set to 'auto' for all properties.
>>>
>>> A complete branch can be found here:
>>> https://github.com/NathanChenNVIDIA/qemu/tree/smmuv3-accel-auto
>> I have just noticed we are missing documentation for smmuv3 accel
>> options in
>>
>> qemu-options.hx
>>
>> At the moment we just have:
>>
>> ``-device arm-smmuv3,primary-bus=id``
>> This is only supported by ``-machine virt`` (ARM).
>>
>> ``primary-bus=id``
>> Accepts either the default root complex (pcie.0) or a
>> pxb-pcie based root complex.
>
> I will add a commit to include documentation for the smmuv3 accel
> options in the next refresh.
Great. Thanks!
>
> Thanks,
> Nathan
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-10 9:01 ` Shameer Kolothum Thodi
@ 2026-03-12 8:20 ` Markus Armbruster
2026-03-12 8:33 ` Shameer Kolothum Thodi
0 siblings, 1 reply; 49+ messages in thread
From: Markus Armbruster @ 2026-03-12 8:20 UTC (permalink / raw)
To: Shameer Kolothum Thodi
Cc: Nathan Chen, qemu-devel@nongnu.org, qemu-arm@nongnu.org, Yi Liu,
Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P.Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake
Shameer Kolothum Thodi <skolothumtho@nvidia.com> writes:
>> -----Original Message-----
>> From: Markus Armbruster <armbru@redhat.com>
[...]
>> Nathan Chen <nathanc@nvidia.com> writes:
>>
>> > From: Nathan Chen <nathanc@nvidia.com>
>> >
>> > Introduce smmuv3_accel_auto_finalise() to resolve properties
>> > that are set to 'auto' for accelerated SMMUv3. This helper
>> > function allows properties such as ATS, RIL, SSIDSIZE, and OAS
>> > support to be resolved from host IOMMU values, while avoiding
>> > triggering auto-resolved values for hot-plugged devices.
>> >
>> > Auto mode requires at least one cold-plugged device to retrieve
>> > and finalise these properties, and we fail boot if that is not
>> > the case.
>> >
>> > Subsequent patches will make use of this helper to set the
>> > values when we convert the values to OnOffAuto. New auto_mode
>> > and auto_finalised bool members are added to SMMUv3AccelState.
>> > smmuv3_accel_init() will set auto_mode to true when 'auto' is
>> > detected for the accel SMMUv3 properties.
>> > smmuv3_accel_auto_finalise() will set auto_finalised to true
>> > after all 'auto' properties are resolved, and subsequent
>> > calls to this function will return early if auto_finalised is
>> > set to true.
>> >
>> > Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
>> > Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>> > ---
>> > hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++--
>> ---
>> > hw/arm/smmuv3-accel.h | 2 ++
>> > 2 files changed, 35 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>> > index 17306cd04b..617629bacd 100644
>> > --- a/hw/arm/smmuv3-accel.c
>> > +++ b/hw/arm/smmuv3-accel.c
>> > @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
>> > return map[oas];
>> > }
>> >
>> > +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice *pdev,
>> > + struct iommu_hw_info_arm_smmuv3 *info) {
>> > + SMMUv3AccelState *accel = s->s_accel;
>> > +
>> > + /* Return if no auto for any or finalised already */
>> > + if (!accel->auto_mode || accel->auto_finalised) {
>> > + return;
>> > + }
>> > +
>> > + /* We can't update if device is hotplugged */
>> > + if (DEVICE(pdev)->hotplugged) {
>> > + warn_report("arm-smmuv3: 'auto' feature property detected, but host
>> "
>> > + "value cannot be applied for hot-plugged device; using "
>> > + "existing value");
>>
>> Why is this warning useful?
>>
>> Does @auto's meaning depend on whether the device is cold- or
>> hot-plugged?
>
> If SMMUv3 accel=on and properties are set to "auto", we require
> at least one cold-plugged vfio-pci device to retrieve the associated
> host SMMUv3 information and finalise the QEMU SMMUv3 properties.
>
> In this series, "auto_mode" is set if any accel property is specified as
> "auto". The properties are then finalised using the first cold-plugged
> device and "auto_finalised" is set.
>
> Since we later fail the guest boot(see below) in the reset phase if
> auto_mode is set but auto_finalised is still false, the above hotplug
> case should not really happen. In that case the VM would not boot.
Sounds complicated.
> So likely we can get rid of the hotplug check above. Need to do
> a bit more testing to confirm we cover all corner cases.
>
>>
>> > + return;
>> > + }
>> > +
>> > + accel->auto_finalised = true;
>> > +}
[...]
>> > @@ -867,8 +891,12 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
>> >
>> > void smmuv3_accel_reset(SMMUv3State *s)
>> > {
>> > - /* Attach a HWPT based on GBPA reset value */
>> > - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
>> > + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel->auto_finalised)
>> {
>> > + error_report("AUTO mode specified but properties not finalised.");
>> > + exit(1);
>>
>> How can we get here?
>
> This is reached from the SMMUv3 reset handler when auto mode is
> specified but no cold-plugged device has been attached to finalise the
> accelerated SMMUv3 properties.
>
> If no such device is present, "auto_finalised" remains false and we hit
> this path during reset.
>
> Cédric mentioned that we should not exit during the reset phase. If that
> is the case, we likely need another way to handle the scenario where
> auto mode is specified but no cold-plugged device is present.
What exactly does the "auto" feature buy us? Is it worth the
complexity?
^ permalink raw reply [flat|nested] 49+ messages in thread
* RE: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-12 8:20 ` Markus Armbruster
@ 2026-03-12 8:33 ` Shameer Kolothum Thodi
2026-03-12 8:39 ` Cédric Le Goater
0 siblings, 1 reply; 49+ messages in thread
From: Shameer Kolothum Thodi @ 2026-03-12 8:33 UTC (permalink / raw)
To: Markus Armbruster
Cc: Nathan Chen, qemu-devel@nongnu.org, qemu-arm@nongnu.org, Yi Liu,
Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P.Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake
> -----Original Message-----
> From: Markus Armbruster <armbru@redhat.com>
> Sent: 12 March 2026 08:21
> To: Shameer Kolothum Thodi <skolothumtho@nvidia.com>
> Cc: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org; Yi Liu <yi.l.liu@intel.com>; Eric Auger
> <eric.auger@redhat.com>; Zhenzhong Duan <zhenzhong.duan@intel.com>;
> Peter Maydell <peter.maydell@linaro.org>; Shannon Zhao
> <shannon.zhaosl@gmail.com>; Michael S . Tsirkin <mst@redhat.com>; Igor
> Mammedov <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>;
> Paolo Bonzini <pbonzini@redhat.com>; Daniel P.Berrangé
> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Cédric Le
> Goater <clg@redhat.com>; Eric Blake <eblake@redhat.com>
> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
> auto parameters
>
> External email: Use caution opening links or attachments
>
>
> Shameer Kolothum Thodi <skolothumtho@nvidia.com> writes:
>
> >> -----Original Message-----
> >> From: Markus Armbruster <armbru@redhat.com>
>
> [...]
>
> >> Nathan Chen <nathanc@nvidia.com> writes:
> >>
> >> > From: Nathan Chen <nathanc@nvidia.com>
> >> >
> >> > Introduce smmuv3_accel_auto_finalise() to resolve properties that
> >> > are set to 'auto' for accelerated SMMUv3. This helper function
> >> > allows properties such as ATS, RIL, SSIDSIZE, and OAS support to be
> >> > resolved from host IOMMU values, while avoiding triggering
> >> > auto-resolved values for hot-plugged devices.
> >> >
> >> > Auto mode requires at least one cold-plugged device to retrieve and
> >> > finalise these properties, and we fail boot if that is not the
> >> > case.
> >> >
> >> > Subsequent patches will make use of this helper to set the values
> >> > when we convert the values to OnOffAuto. New auto_mode and
> >> > auto_finalised bool members are added to SMMUv3AccelState.
> >> > smmuv3_accel_init() will set auto_mode to true when 'auto' is
> >> > detected for the accel SMMUv3 properties.
> >> > smmuv3_accel_auto_finalise() will set auto_finalised to true after
> >> > all 'auto' properties are resolved, and subsequent calls to this
> >> > function will return early if auto_finalised is set to true.
> >> >
> >> > Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> >> > Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> >> > ---
> >> > hw/arm/smmuv3-accel.c | 38
> +++++++++++++++++++++++++++++++++--
> >> ---
> >> > hw/arm/smmuv3-accel.h | 2 ++
> >> > 2 files changed, 35 insertions(+), 5 deletions(-)
> >> >
> >> > diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index
> >> > 17306cd04b..617629bacd 100644
> >> > --- a/hw/arm/smmuv3-accel.c
> >> > +++ b/hw/arm/smmuv3-accel.c
> >> > @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> >> > return map[oas];
> >> > }
> >> >
> >> > +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
> *pdev,
> >> > + struct iommu_hw_info_arm_smmuv3 *info) {
> >> > + SMMUv3AccelState *accel = s->s_accel;
> >> > +
> >> > + /* Return if no auto for any or finalised already */
> >> > + if (!accel->auto_mode || accel->auto_finalised) {
> >> > + return;
> >> > + }
> >> > +
> >> > + /* We can't update if device is hotplugged */
> >> > + if (DEVICE(pdev)->hotplugged) {
> >> > + warn_report("arm-smmuv3: 'auto' feature property detected,
> >> > + but host
> >> "
> >> > + "value cannot be applied for hot-plugged device; using "
> >> > + "existing value");
> >>
> >> Why is this warning useful?
> >>
> >> Does @auto's meaning depend on whether the device is cold- or
> >> hot-plugged?
> >
> > If SMMUv3 accel=on and properties are set to "auto", we require at
> > least one cold-plugged vfio-pci device to retrieve the associated host
> > SMMUv3 information and finalise the QEMU SMMUv3 properties.
> >
> > In this series, "auto_mode" is set if any accel property is specified
> > as "auto". The properties are then finalised using the first
> > cold-plugged device and "auto_finalised" is set.
> >
> > Since we later fail the guest boot(see below) in the reset phase if
> > auto_mode is set but auto_finalised is still false, the above hotplug
> > case should not really happen. In that case the VM would not boot.
>
> Sounds complicated.
>
> > So likely we can get rid of the hotplug check above. Need to do a bit
> > more testing to confirm we cover all corner cases.
> >
> >>
> >> > + return;
> >> > + }
> >> > +
> >> > + accel->auto_finalised = true;
> >> > +}
>
> [...]
>
> >> > @@ -867,8 +891,12 @@ bool
> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State
> >> > *s, Error **errp)
> >> >
> >> > void smmuv3_accel_reset(SMMUv3State *s) {
> >> > - /* Attach a HWPT based on GBPA reset value */
> >> > - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> >> > + if (s->s_accel && s->s_accel->auto_mode &&
> >> > + !s->s_accel->auto_finalised)
> >> {
> >> > + error_report("AUTO mode specified but properties not finalised.");
> >> > + exit(1);
> >>
> >> How can we get here?
> >
> > This is reached from the SMMUv3 reset handler when auto mode is
> > specified but no cold-plugged device has been attached to finalise the
> > accelerated SMMUv3 properties.
> >
> > If no such device is present, "auto_finalised" remains false and we hit
> > this path during reset.
> >
> > Cédric mentioned that we should not exit during the reset phase. If that
> > is the case, we likely need another way to handle the scenario where
> > auto mode is specified but no cold-plugged device is present.
>
> What exactly does the "auto" feature buy us? Is it worth the
> complexity?
The requirement came from the KubeVirt folks. It is easier for them if
QEMU can probe the platform and set these values, instead of specifying
them for each platform.
See:
https://lore.kernel.org/qemu-devel/d9192ae6-a94f-479a-b19f-734cc52a6be0@redhat.com/
Without "auto", the management layer needs to know the values supported
on each platform.
eg: on a GB200, it will look like,
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on,ats=on,ril=off,ssidsize=20,oas=48
With "auto" it can simply be:
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on
(provided a vfio-pci device is cold-plugged).
Thanks,
Shameer
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-10 8:40 ` Shameer Kolothum Thodi
@ 2026-03-12 8:37 ` Cédric Le Goater
2026-03-12 9:29 ` Shameer Kolothum Thodi
0 siblings, 1 reply; 49+ messages in thread
From: Cédric Le Goater @ 2026-03-12 8:37 UTC (permalink / raw)
To: Shameer Kolothum Thodi, Nathan Chen, qemu-devel@nongnu.org,
qemu-arm@nongnu.org
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Eric Blake,
Markus Armbruster
Hello Shameer
On 3/10/26 09:40, Shameer Kolothum Thodi wrote:
>
>
>> -----Original Message-----
>> From: Cédric Le Goater <clg@redhat.com>
>> Sent: 10 March 2026 07:42
>> To: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-
>> arm@nongnu.org
>> Cc: Yi Liu <yi.l.liu@intel.com>; Eric Auger <eric.auger@redhat.com>;
>> Zhenzhong Duan <zhenzhong.duan@intel.com>; Peter Maydell
>> <peter.maydell@linaro.org>; Shannon Zhao <shannon.zhaosl@gmail.com>;
>> Michael S . Tsirkin <mst@redhat.com>; Igor Mammedov
>> <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>; Paolo
>> Bonzini <pbonzini@redhat.com>; Daniel P . Berrangé
>> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Eric Blake
>> <eblake@redhat.com>; Markus Armbruster <armbru@redhat.com>;
>> Shameer Kolothum Thodi <skolothumtho@nvidia.com>
>> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
>> auto parameters
>>
>> External email: Use caution opening links or attachments
>>
>>
>> On 3/9/26 20:21, Nathan Chen wrote:
>>> From: Nathan Chen <nathanc@nvidia.com>
>>>
>>> Introduce smmuv3_accel_auto_finalise() to resolve properties
>>> that are set to 'auto' for accelerated SMMUv3. This helper
>>> function allows properties such as ATS, RIL, SSIDSIZE, and OAS
>>> support to be resolved from host IOMMU values, while avoiding
>>> triggering auto-resolved values for hot-plugged devices.
>>>
>>> Auto mode requires at least one cold-plugged device to retrieve
>>> and finalise these properties, and we fail boot if that is not
>>> the case.
>>
>> IIUC, QEMU will require a minimum of one PCI device if
>> arm-smmuv3,accel=on is passed on the command line and if the
>> smmu properties are set to 'auto'.
>
> Yes, that’s correct.
>
>> I would try to enforce this requirement in the realize routine.
>> Can't we leverage the supports_address_space() handler ? See :
>>
>>
>> static bool smmuv3_accel_supports_as(PCIBus *bus, void *opaque, int
>> devfn,
>> Error **errp)
>> {
>> PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
>> bool vfio_pci = false;
>>
>> if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
>> if (vfio_pci) {
>> error_setg(errp, "vfio-pci endpoint devices without an iommufd "
>> "backend not allowed when using arm-smmuv3,accel=on");
>> ...
> Hmm..i doubt we can do it here as we need HostIOMMUDeviceIOMMUFD *idev
> for retrieving the IOMMU_GET_HW_INFO.
>
> supports_address_space() is invoked very early during do_pci_register_device()
> and there are no associated idev available at that time.
yes. Have your considered adding an 'iommufd' property to smmuv3
instead ? I think this should solve a lot of potential issues
and would be more model friendly.
Sorry if that was proposed already. I have been through all the
emails.
>
>>>
>>> Subsequent patches will make use of this helper to set the
>>> values when we convert the values to OnOffAuto. New auto_mode
>>> and auto_finalised bool members are added to SMMUv3AccelState.
>>> smmuv3_accel_init() will set auto_mode to true when 'auto' is
>>> detected for the accel SMMUv3 properties.
>>> smmuv3_accel_auto_finalise() will set auto_finalised to true
>>> after all 'auto' properties are resolved, and subsequent
>>> calls to this function will return early if auto_finalised is
>>> set to true.
>>>
>>> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
>>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>>> ---
>>> hw/arm/smmuv3-accel.c | 38 +++++++++++++++++++++++++++++++++-----
>>> hw/arm/smmuv3-accel.h | 2 ++
>>> 2 files changed, 35 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
>>> index 17306cd04b..617629bacd 100644
>>> --- a/hw/arm/smmuv3-accel.c
>>> +++ b/hw/arm/smmuv3-accel.c
>>> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
>>> return map[oas];
>>> }
>>>
>>> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
>> *pdev,
>>> + struct iommu_hw_info_arm_smmuv3 *info) {
>>> + SMMUv3AccelState *accel = s->s_accel;
>>> +
>>> + /* Return if no auto for any or finalised already */
>>> + if (!accel->auto_mode || accel->auto_finalised) {
>>> + return;
>>> + }
>>> +
>>> + /* We can't update if device is hotplugged */
>>> + if (DEVICE(pdev)->hotplugged) {
>>> + warn_report("arm-smmuv3: 'auto' feature property detected, but host
>> "
>>> + "value cannot be applied for hot-plugged device; using "
>>> + "existing value");
>>
>> Please add an 'Error **' parameter instead.
>>
>>> + return;
>>> + }
>>> +
>>> + accel->auto_finalised = true;
>>> +}
>>> +
>>> static bool
>>> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>>> struct iommu_hw_info_arm_smmuv3 *info,
>>> + PCIDevice *pdev,
>>> Error **errp)
>>> {
>>> + smmuv3_accel_auto_finalise(s, pdev, info);
>>> +
>>> /* QEMU SMMUv3 supports both linear and 2-level stream tables */
>>> if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=
>>> FIELD_EX32(s->idr[0], IDR0, STLEVEL)) {
>>> @@ -124,7 +147,7 @@
>> smmuv3_accel_check_hw_compatible(SMMUv3State *s,
>>>
>>> static bool
>>> smmuv3_accel_hw_compatible(SMMUv3State *s,
>> HostIOMMUDeviceIOMMUFD *idev,
>>> - Error **errp)
>>> + PCIDevice *pdev, Error **errp)
>>> {
>>> struct iommu_hw_info_arm_smmuv3 info;
>>> uint32_t data_type;
>>> @@ -142,7 +165,7 @@ smmuv3_accel_hw_compatible(SMMUv3State *s,
>> HostIOMMUDeviceIOMMUFD *idev,
>>> return false;
>>> }
>>>
>>> - if (!smmuv3_accel_check_hw_compatible(s, &info, errp)) {
>>> + if (!smmuv3_accel_check_hw_compatible(s, &info, pdev, errp)) {
>>> return false;
>>> }
>>> return true;
>>> @@ -595,6 +618,7 @@ static bool
>> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
>>> SMMUv3State *s = ARM_SMMUV3(bs);
>>> SMMUPciBus *sbus = smmu_get_sbus(bs, bus);
>>> SMMUv3AccelDevice *accel_dev = smmuv3_accel_get_dev(bs, sbus,
>> bus, devfn);
>>> + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
>>>
>>> if (!idev) {
>>> return true;
>>> @@ -613,7 +637,7 @@ static bool
>> smmuv3_accel_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
>>> * Check the host SMMUv3 associated with the dev is compatible with
>> the
>>> * QEMU SMMUv3 accel.
>>> */
>>> - if (!smmuv3_accel_hw_compatible(s, idev, errp)) {
>>> + if (!smmuv3_accel_hw_compatible(s, idev, pdev, errp)) {
>>> return false;
>>> }
>>>
>>> @@ -867,8 +891,12 @@ bool
>> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
>>>
>>> void smmuv3_accel_reset(SMMUv3State *s)
>>> {
>>> - /* Attach a HWPT based on GBPA reset value */
>>> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
>>> + if (s->s_accel && s->s_accel->auto_mode && !s->s_accel-
>>> auto_finalised) {
>>> + error_report("AUTO mode specified but properties not finalised.");
>>
>> This is not a very friendly message for the user.
>>
>>
>>> + exit(1);
>>
>> QEMU should not exit in the reset phase. Can this check be done during
>> the realize stage ?
>
> SMMUv3 realize stage happens before the cold-plugged device
> set_iommu_device(), and therefore we can't check whether the SMMUv3
> properties have been retrieved and finalised at that point.
>
> Not sure there is any other place we can do this other than in the reset
> path.
>
> Is avoiding exit(1) in the reset phase a strict requirement or a nice to
> have one?
reset is a runtime handler called at each reboot. One should not
exit.
We should try to verify that the conditions to run the machine
are correct before reaching the reset phase.
Thanks,
C.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-12 8:33 ` Shameer Kolothum Thodi
@ 2026-03-12 8:39 ` Cédric Le Goater
2026-03-12 8:44 ` Shameer Kolothum Thodi
0 siblings, 1 reply; 49+ messages in thread
From: Cédric Le Goater @ 2026-03-12 8:39 UTC (permalink / raw)
To: Shameer Kolothum Thodi, Markus Armbruster
Cc: Nathan Chen, qemu-devel@nongnu.org, qemu-arm@nongnu.org, Yi Liu,
Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P.Berrangé, Alex Williamson, Eric Blake
On 3/12/26 09:33, Shameer Kolothum Thodi wrote:
>
>
>> -----Original Message-----
>> From: Markus Armbruster <armbru@redhat.com>
>> Sent: 12 March 2026 08:21
>> To: Shameer Kolothum Thodi <skolothumtho@nvidia.com>
>> Cc: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-
>> arm@nongnu.org; Yi Liu <yi.l.liu@intel.com>; Eric Auger
>> <eric.auger@redhat.com>; Zhenzhong Duan <zhenzhong.duan@intel.com>;
>> Peter Maydell <peter.maydell@linaro.org>; Shannon Zhao
>> <shannon.zhaosl@gmail.com>; Michael S . Tsirkin <mst@redhat.com>; Igor
>> Mammedov <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>;
>> Paolo Bonzini <pbonzini@redhat.com>; Daniel P.Berrangé
>> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Cédric Le
>> Goater <clg@redhat.com>; Eric Blake <eblake@redhat.com>
>> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
>> auto parameters
>>
>> External email: Use caution opening links or attachments
>>
>>
>> Shameer Kolothum Thodi <skolothumtho@nvidia.com> writes:
>>
>>>> -----Original Message-----
>>>> From: Markus Armbruster <armbru@redhat.com>
>>
>> [...]
>>
>>>> Nathan Chen <nathanc@nvidia.com> writes:
>>>>
>>>>> From: Nathan Chen <nathanc@nvidia.com>
>>>>>
>>>>> Introduce smmuv3_accel_auto_finalise() to resolve properties that
>>>>> are set to 'auto' for accelerated SMMUv3. This helper function
>>>>> allows properties such as ATS, RIL, SSIDSIZE, and OAS support to be
>>>>> resolved from host IOMMU values, while avoiding triggering
>>>>> auto-resolved values for hot-plugged devices.
>>>>>
>>>>> Auto mode requires at least one cold-plugged device to retrieve and
>>>>> finalise these properties, and we fail boot if that is not the
>>>>> case.
>>>>>
>>>>> Subsequent patches will make use of this helper to set the values
>>>>> when we convert the values to OnOffAuto. New auto_mode and
>>>>> auto_finalised bool members are added to SMMUv3AccelState.
>>>>> smmuv3_accel_init() will set auto_mode to true when 'auto' is
>>>>> detected for the accel SMMUv3 properties.
>>>>> smmuv3_accel_auto_finalise() will set auto_finalised to true after
>>>>> all 'auto' properties are resolved, and subsequent calls to this
>>>>> function will return early if auto_finalised is set to true.
>>>>>
>>>>> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
>>>>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
>>>>> ---
>>>>> hw/arm/smmuv3-accel.c | 38
>> +++++++++++++++++++++++++++++++++--
>>>> ---
>>>>> hw/arm/smmuv3-accel.h | 2 ++
>>>>> 2 files changed, 35 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index
>>>>> 17306cd04b..617629bacd 100644
>>>>> --- a/hw/arm/smmuv3-accel.c
>>>>> +++ b/hw/arm/smmuv3-accel.c
>>>>> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
>>>>> return map[oas];
>>>>> }
>>>>>
>>>>> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
>> *pdev,
>>>>> + struct iommu_hw_info_arm_smmuv3 *info) {
>>>>> + SMMUv3AccelState *accel = s->s_accel;
>>>>> +
>>>>> + /* Return if no auto for any or finalised already */
>>>>> + if (!accel->auto_mode || accel->auto_finalised) {
>>>>> + return;
>>>>> + }
>>>>> +
>>>>> + /* We can't update if device is hotplugged */
>>>>> + if (DEVICE(pdev)->hotplugged) {
>>>>> + warn_report("arm-smmuv3: 'auto' feature property detected,
>>>>> + but host
>>>> "
>>>>> + "value cannot be applied for hot-plugged device; using "
>>>>> + "existing value");
>>>>
>>>> Why is this warning useful?
>>>>
>>>> Does @auto's meaning depend on whether the device is cold- or
>>>> hot-plugged?
>>>
>>> If SMMUv3 accel=on and properties are set to "auto", we require at
>>> least one cold-plugged vfio-pci device to retrieve the associated host
>>> SMMUv3 information and finalise the QEMU SMMUv3 properties.
>>>
>>> In this series, "auto_mode" is set if any accel property is specified
>>> as "auto". The properties are then finalised using the first
>>> cold-plugged device and "auto_finalised" is set.
>>>
>>> Since we later fail the guest boot(see below) in the reset phase if
>>> auto_mode is set but auto_finalised is still false, the above hotplug
>>> case should not really happen. In that case the VM would not boot.
>>
>> Sounds complicated.
>>
>>> So likely we can get rid of the hotplug check above. Need to do a bit
>>> more testing to confirm we cover all corner cases.
>>>
>>>>
>>>>> + return;
>>>>> + }
>>>>> +
>>>>> + accel->auto_finalised = true;
>>>>> +}
>>
>> [...]
>>
>>>>> @@ -867,8 +891,12 @@ bool
>> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State
>>>>> *s, Error **errp)
>>>>>
>>>>> void smmuv3_accel_reset(SMMUv3State *s) {
>>>>> - /* Attach a HWPT based on GBPA reset value */
>>>>> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
>>>>> + if (s->s_accel && s->s_accel->auto_mode &&
>>>>> + !s->s_accel->auto_finalised)
>>>> {
>>>>> + error_report("AUTO mode specified but properties not finalised.");
>>>>> + exit(1);
>>>>
>>>> How can we get here?
>>>
>>> This is reached from the SMMUv3 reset handler when auto mode is
>>> specified but no cold-plugged device has been attached to finalise the
>>> accelerated SMMUv3 properties.
>>>
>>> If no such device is present, "auto_finalised" remains false and we hit
>>> this path during reset.
>>>
>>> Cédric mentioned that we should not exit during the reset phase. If that
>>> is the case, we likely need another way to handle the scenario where
>>> auto mode is specified but no cold-plugged device is present.
>>
>> What exactly does the "auto" feature buy us? Is it worth the
>> complexity?
>
> The requirement came from the KubeVirt folks. It is easier for them if
> QEMU can probe the platform and set these values, instead of specifying
> them for each platform.
>
> See:
> https://lore.kernel.org/qemu-devel/d9192ae6-a94f-479a-b19f-734cc52a6be0@redhat.com/
>
> Without "auto", the management layer needs to know the values supported
> on each platform.
>
> eg: on a GB200, it will look like,
>
> -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on,ats=on,ril=off,ssidsize=20,oas=48
>
> With "auto" it can simply be:
>
> -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on
>
> (provided a vfio-pci device is cold-plugged).
how about,
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on,iommufd=iommufd0
and smmuv3_accel_init() would check that the conditions are correct.
Thanks,
C.
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-11 17:16 ` Eric Auger
2026-03-11 18:09 ` Pavel Hrdina
@ 2026-03-12 8:39 ` Markus Armbruster
2026-03-12 8:51 ` Eric Auger
2026-03-12 8:52 ` Eric Auger
1 sibling, 2 replies; 49+ messages in thread
From: Markus Armbruster @ 2026-03-12 8:39 UTC (permalink / raw)
To: Eric Auger
Cc: Nathan Chen, qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
Eric Auger <eric.auger@redhat.com> writes:
> On 3/11/26 6:08 PM, Nathan Chen wrote:
>>
>>
>> On 3/11/2026 8:31 AM, Eric Auger wrote:
>>> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>>>> Nathan Chen<nathanc@nvidia.com> writes:
>>>>
>>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>>
>>>>> Allow accelerated SMMUv3 Address Translation Services support property
>>>>> to be derived from host IOMMU capabilities. Derive host values using
>>>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>>>
>>>>> Set the default value of ATS to auto. The default for ATS support used
>>>>> to be set to off, but we change it to match what the host IOMMU
>>>>> properties report.
>>>>>
>>>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>>>
>>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
[...]
>>>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>>>> index 068108e49b..197ba7c77b 100644
>>>>> --- a/hw/arm/smmuv3.c
>>>>> +++ b/hw/arm/smmuv3.c
[...]
>>>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>>>> /* RIL can be turned off for accel cases */
>>>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>>>>
>>>> Is property "ats" accessible via QMP or JSON command line? If yes,
>>>> this
>>>> is an incompatible change: JSON values false and true no longer work.
>>> So what do you recommend to extend the property values. I guess we had
>>> some existing scenarios happening in the past. What is the best way to
>>> proceed?
>>
>> Is it a requirement to ensure boolean values are still supported when
>> switching to OnOffAuto? I found that the x86-iommu intremap property
>> had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
We promise to follow a certain process when changing external
interfaces: docs/about/deprecated.rst.
This is why I inquired about external access. No external access, no
compatibility worries.
I specifically asked about JSON, because going from bool to OnOffAuto is
mostly compatible in key=value syntax: values "on" and "off" keep
working.
Mostly compatible, because qapi_bool_parse() also recognizes "yes",
"true", "y", "no", "false", and "n" for convenience, and these stop
working. We have a knack for inventing convenience features that later
bite us.
JSON breaks entirely, of course: all values stop working.
Even with external access, compatibility worries start only after we
shipped the interface in a release. Did we?
If the interface was released, we should keep our promise to follow the
process. From time to time, that's so onerous and we're so certain that
nobody actually cares, we bend the rules. This should not be done
lightly.
>> Should I add a custom property setter that accepts both boolean and
>> on/off/auto for backward compatibility, or is following the intremap
>> precedent acceptable? I'm happy to implement either approach.
>>
>> [0]
>> https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
>
> Maybe we also need to emphasize that libvirt integration is still under
> work (and waiting for that conversion to happen at qemu level). So do we
> really care about keeping the compat wrt QMP and JSON.
I can explain our promise and the process to you, but I can't make the
decision to bend the rules for you.
^ permalink raw reply [flat|nested] 49+ messages in thread
* RE: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-12 8:39 ` Cédric Le Goater
@ 2026-03-12 8:44 ` Shameer Kolothum Thodi
0 siblings, 0 replies; 49+ messages in thread
From: Shameer Kolothum Thodi @ 2026-03-12 8:44 UTC (permalink / raw)
To: Cédric Le Goater, Markus Armbruster
Cc: Nathan Chen, qemu-devel@nongnu.org, qemu-arm@nongnu.org, Yi Liu,
Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P.Berrangé, Alex Williamson, Eric Blake
> -----Original Message-----
> From: Cédric Le Goater <clg@redhat.com>
> Sent: 12 March 2026 08:39
> To: Shameer Kolothum Thodi <skolothumtho@nvidia.com>; Markus
> Armbruster <armbru@redhat.com>
> Cc: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org; Yi Liu <yi.l.liu@intel.com>; Eric Auger
> <eric.auger@redhat.com>; Zhenzhong Duan <zhenzhong.duan@intel.com>;
> Peter Maydell <peter.maydell@linaro.org>; Shannon Zhao
> <shannon.zhaosl@gmail.com>; Michael S . Tsirkin <mst@redhat.com>; Igor
> Mammedov <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>;
> Paolo Bonzini <pbonzini@redhat.com>; Daniel P.Berrangé
> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Eric Blake
> <eblake@redhat.com>
> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
> auto parameters
>
> External email: Use caution opening links or attachments
>
>
> On 3/12/26 09:33, Shameer Kolothum Thodi wrote:
> >
> >
> >> -----Original Message-----
> >> From: Markus Armbruster <armbru@redhat.com>
> >> Sent: 12 March 2026 08:21
> >> To: Shameer Kolothum Thodi <skolothumtho@nvidia.com>
> >> Cc: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org;
> qemu-
> >> arm@nongnu.org; Yi Liu <yi.l.liu@intel.com>; Eric Auger
> >> <eric.auger@redhat.com>; Zhenzhong Duan
> <zhenzhong.duan@intel.com>;
> >> Peter Maydell <peter.maydell@linaro.org>; Shannon Zhao
> >> <shannon.zhaosl@gmail.com>; Michael S . Tsirkin <mst@redhat.com>;
> >> Igor Mammedov <imammedo@redhat.com>; Ani Sinha
> <anisinha@redhat.com>;
> >> Paolo Bonzini <pbonzini@redhat.com>; Daniel P.Berrangé
> >> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Cédric Le
> >> Goater <clg@redhat.com>; Eric Blake <eblake@redhat.com>
> >> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for
> >> resolving auto parameters
> >>
> >> External email: Use caution opening links or attachments
> >>
> >>
> >> Shameer Kolothum Thodi <skolothumtho@nvidia.com> writes:
> >>
> >>>> -----Original Message-----
> >>>> From: Markus Armbruster <armbru@redhat.com>
> >>
> >> [...]
> >>
> >>>> Nathan Chen <nathanc@nvidia.com> writes:
> >>>>
> >>>>> From: Nathan Chen <nathanc@nvidia.com>
> >>>>>
> >>>>> Introduce smmuv3_accel_auto_finalise() to resolve properties that
> >>>>> are set to 'auto' for accelerated SMMUv3. This helper function
> >>>>> allows properties such as ATS, RIL, SSIDSIZE, and OAS support to
> >>>>> be resolved from host IOMMU values, while avoiding triggering
> >>>>> auto-resolved values for hot-plugged devices.
> >>>>>
> >>>>> Auto mode requires at least one cold-plugged device to retrieve
> >>>>> and finalise these properties, and we fail boot if that is not the
> >>>>> case.
> >>>>>
> >>>>> Subsequent patches will make use of this helper to set the values
> >>>>> when we convert the values to OnOffAuto. New auto_mode and
> >>>>> auto_finalised bool members are added to SMMUv3AccelState.
> >>>>> smmuv3_accel_init() will set auto_mode to true when 'auto' is
> >>>>> detected for the accel SMMUv3 properties.
> >>>>> smmuv3_accel_auto_finalise() will set auto_finalised to true after
> >>>>> all 'auto' properties are resolved, and subsequent calls to this
> >>>>> function will return early if auto_finalised is set to true.
> >>>>>
> >>>>> Suggested-by: Shameer Kolothum <skolothumtho@nvidia.com>
> >>>>> Signed-off-by: Nathan Chen <nathanc@nvidia.com>
> >>>>> ---
> >>>>> hw/arm/smmuv3-accel.c | 38
> >> +++++++++++++++++++++++++++++++++--
> >>>> ---
> >>>>> hw/arm/smmuv3-accel.h | 2 ++
> >>>>> 2 files changed, 35 insertions(+), 5 deletions(-)
> >>>>>
> >>>>> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index
> >>>>> 17306cd04b..617629bacd 100644
> >>>>> --- a/hw/arm/smmuv3-accel.c
> >>>>> +++ b/hw/arm/smmuv3-accel.c
> >>>>> @@ -35,11 +35,34 @@ static int smmuv3_oas_bits(uint32_t oas)
> >>>>> return map[oas];
> >>>>> }
> >>>>>
> >>>>> +static void smmuv3_accel_auto_finalise(SMMUv3State *s, PCIDevice
> >> *pdev,
> >>>>> + struct iommu_hw_info_arm_smmuv3 *info) {
> >>>>> + SMMUv3AccelState *accel = s->s_accel;
> >>>>> +
> >>>>> + /* Return if no auto for any or finalised already */
> >>>>> + if (!accel->auto_mode || accel->auto_finalised) {
> >>>>> + return;
> >>>>> + }
> >>>>> +
> >>>>> + /* We can't update if device is hotplugged */
> >>>>> + if (DEVICE(pdev)->hotplugged) {
> >>>>> + warn_report("arm-smmuv3: 'auto' feature property
> >>>>> + detected, but host
> >>>> "
> >>>>> + "value cannot be applied for hot-plugged device; using "
> >>>>> + "existing value");
> >>>>
> >>>> Why is this warning useful?
> >>>>
> >>>> Does @auto's meaning depend on whether the device is cold- or
> >>>> hot-plugged?
> >>>
> >>> If SMMUv3 accel=on and properties are set to "auto", we require at
> >>> least one cold-plugged vfio-pci device to retrieve the associated
> >>> host
> >>> SMMUv3 information and finalise the QEMU SMMUv3 properties.
> >>>
> >>> In this series, "auto_mode" is set if any accel property is
> >>> specified as "auto". The properties are then finalised using the
> >>> first cold-plugged device and "auto_finalised" is set.
> >>>
> >>> Since we later fail the guest boot(see below) in the reset phase if
> >>> auto_mode is set but auto_finalised is still false, the above
> >>> hotplug case should not really happen. In that case the VM would not
> boot.
> >>
> >> Sounds complicated.
> >>
> >>> So likely we can get rid of the hotplug check above. Need to do a
> >>> bit more testing to confirm we cover all corner cases.
> >>>
> >>>>
> >>>>> + return;
> >>>>> + }
> >>>>> +
> >>>>> + accel->auto_finalised = true; }
> >>
> >> [...]
> >>
> >>>>> @@ -867,8 +891,12 @@ bool
> >> smmuv3_accel_attach_gbpa_hwpt(SMMUv3State
> >>>>> *s, Error **errp)
> >>>>>
> >>>>> void smmuv3_accel_reset(SMMUv3State *s) {
> >>>>> - /* Attach a HWPT based on GBPA reset value */
> >>>>> - smmuv3_accel_attach_gbpa_hwpt(s, NULL);
> >>>>> + if (s->s_accel && s->s_accel->auto_mode &&
> >>>>> + !s->s_accel->auto_finalised)
> >>>> {
> >>>>> + error_report("AUTO mode specified but properties not finalised.");
> >>>>> + exit(1);
> >>>>
> >>>> How can we get here?
> >>>
> >>> This is reached from the SMMUv3 reset handler when auto mode is
> >>> specified but no cold-plugged device has been attached to finalise
> >>> the accelerated SMMUv3 properties.
> >>>
> >>> If no such device is present, "auto_finalised" remains false and we
> >>> hit this path during reset.
> >>>
> >>> Cédric mentioned that we should not exit during the reset phase. If
> >>> that is the case, we likely need another way to handle the scenario
> >>> where auto mode is specified but no cold-plugged device is present.
> >>
> >> What exactly does the "auto" feature buy us? Is it worth the
> >> complexity?
> >
> > The requirement came from the KubeVirt folks. It is easier for them if
> > QEMU can probe the platform and set these values, instead of
> > specifying them for each platform.
> >
> > See:
> > https://lore.kernel.org/qemu-devel/d9192ae6-a94f-479a-b19f-
> 734cc52a6be
> > 0@redhat.com/
> >
> > Without "auto", the management layer needs to know the values
> > supported on each platform.
> >
> > eg: on a GB200, it will look like,
> >
> > -device
> > arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on,ats=on,ril=off,ssid
> > size=20,oas=48
> >
> > With "auto" it can simply be:
> >
> > -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.0,accel=on
> >
> > (provided a vfio-pci device is cold-plugged).
>
> how about,
>
> -device arm-smmuv3,primary-
> bus=pcie.1,id=smmuv3.0,accel=on,iommufd=iommufd0
>
> and smmuv3_accel_init() would check that the conditions are correct.
>
We need both iommufd and idev for iommufd_backend_get_device_info()
as kernel uses that to find the host SMMUv3 attached to that device.
/**
* struct iommu_hw_info - ioctl(IOMMU_GET_HW_INFO)
* @size: sizeof(struct iommu_hw_info)
* @flags: Must be 0
* @dev_id: The device bound to the iommufd
...
Thanks,
Shameer
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-12 8:39 ` Markus Armbruster
@ 2026-03-12 8:51 ` Eric Auger
2026-03-12 9:20 ` Markus Armbruster
2026-03-12 8:52 ` Eric Auger
1 sibling, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-12 8:51 UTC (permalink / raw)
To: Markus Armbruster
Cc: Nathan Chen, qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/12/26 9:39 AM, Markus Armbruster wrote:
> Eric Auger <eric.auger@redhat.com> writes:
>
>> On 3/11/26 6:08 PM, Nathan Chen wrote:
>>>
>>> On 3/11/2026 8:31 AM, Eric Auger wrote:
>>>> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>>>>> Nathan Chen<nathanc@nvidia.com> writes:
>>>>>
>>>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>>>
>>>>>> Allow accelerated SMMUv3 Address Translation Services support property
>>>>>> to be derived from host IOMMU capabilities. Derive host values using
>>>>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>>>>
>>>>>> Set the default value of ATS to auto. The default for ATS support used
>>>>>> to be set to off, but we change it to match what the host IOMMU
>>>>>> properties report.
>>>>>>
>>>>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>>>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>>>>
>>>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
> [...]
>
>>>>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>>>>> index 068108e49b..197ba7c77b 100644
>>>>>> --- a/hw/arm/smmuv3.c
>>>>>> +++ b/hw/arm/smmuv3.c
> [...]
>
>>>>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>>>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>>>>> /* RIL can be turned off for accel cases */
>>>>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>>>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>>>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>>>>> Is property "ats" accessible via QMP or JSON command line? If yes,
>>>>> this
>>>>> is an incompatible change: JSON values false and true no longer work.
>>>> So what do you recommend to extend the property values. I guess we had
>>>> some existing scenarios happening in the past. What is the best way to
>>>> proceed?
>>> Is it a requirement to ensure boolean values are still supported when
>>> switching to OnOffAuto? I found that the x86-iommu intremap property
>>> had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
> We promise to follow a certain process when changing external
> interfaces: docs/about/deprecated.rst.
>
> This is why I inquired about external access. No external access, no
> compatibility worries.
>
> I specifically asked about JSON, because going from bool to OnOffAuto is
> mostly compatible in key=value syntax: values "on" and "off" keep
> working.
>
> Mostly compatible, because qapi_bool_parse() also recognizes "yes",
> "true", "y", "no", "false", and "n" for convenience, and these stop
> working. We have a knack for inventing convenience features that later
> bite us.
>
> JSON breaks entirely, of course: all values stop working.
>
> Even with external access, compatibility worries start only after we
> shipped the interface in a release. Did we?
those options were introduced in qemu 11.0. Fixing them in -rc is still
an option but it is a very tight schedule
Thanks
Eric
>
> If the interface was released, we should keep our promise to follow the
> process. From time to time, that's so onerous and we're so certain that
> nobody actually cares, we bend the rules. This should not be done
> lightly.
>
>>> Should I add a custom property setter that accepts both boolean and
>>> on/off/auto for backward compatibility, or is following the intremap
>>> precedent acceptable? I'm happy to implement either approach.
>>>
>>> [0]
>>> https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
>> Maybe we also need to emphasize that libvirt integration is still under
>> work (and waiting for that conversion to happen at qemu level). So do we
>> really care about keeping the compat wrt QMP and JSON.
> I can explain our promise and the process to you, but I can't make the
> decision to bend the rules for you.
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-12 8:39 ` Markus Armbruster
2026-03-12 8:51 ` Eric Auger
@ 2026-03-12 8:52 ` Eric Auger
1 sibling, 0 replies; 49+ messages in thread
From: Eric Auger @ 2026-03-12 8:52 UTC (permalink / raw)
To: Markus Armbruster
Cc: Nathan Chen, qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/12/26 9:39 AM, Markus Armbruster wrote:
> Eric Auger <eric.auger@redhat.com> writes:
>
>> On 3/11/26 6:08 PM, Nathan Chen wrote:
>>>
>>> On 3/11/2026 8:31 AM, Eric Auger wrote:
>>>> On 3/10/26 8:05 AM, Markus Armbruster wrote:
>>>>> Nathan Chen<nathanc@nvidia.com> writes:
>>>>>
>>>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>>>
>>>>>> Allow accelerated SMMUv3 Address Translation Services support property
>>>>>> to be derived from host IOMMU capabilities. Derive host values using
>>>>>> IOMMU_GET_HW_INFO, retrieving ATS capability from IDR0.
>>>>>>
>>>>>> Set the default value of ATS to auto. The default for ATS support used
>>>>>> to be set to off, but we change it to match what the host IOMMU
>>>>>> properties report.
>>>>>>
>>>>>> Add a "ats-enabled" read-only property for smmuv3 to address an
>>>>>> expected bool for the "ats" property in iort_smmuv3_devices().
>>>>>>
>>>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
> [...]
>
>>>>>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>>>>>> index 068108e49b..197ba7c77b 100644
>>>>>> --- a/hw/arm/smmuv3.c
>>>>>> +++ b/hw/arm/smmuv3.c
> [...]
>
>>>>>> @@ -2128,7 +2134,7 @@ static const Property smmuv3_properties[] = {
>>>>>> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
>>>>>> /* RIL can be turned off for accel cases */
>>>>>> DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
>>>>>> - DEFINE_PROP_BOOL("ats", SMMUv3State, ats, false),
>>>>>> + DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
>>>>> Is property "ats" accessible via QMP or JSON command line? If yes,
>>>>> this
>>>>> is an incompatible change: JSON values false and true no longer work.
>>>> So what do you recommend to extend the property values. I guess we had
>>>> some existing scenarios happening in the past. What is the best way to
>>>> proceed?
>>> Is it a requirement to ensure boolean values are still supported when
>>> switching to OnOffAuto? I found that the x86-iommu intremap property
>>> had a change from DEFINE_PROP_BOOL to DEFINE_PROP_ON_OFF_AUTO [0].
> We promise to follow a certain process when changing external
> interfaces: docs/about/deprecated.rst.
>
> This is why I inquired about external access. No external access, no
> compatibility worries.
>
> I specifically asked about JSON, because going from bool to OnOffAuto is
> mostly compatible in key=value syntax: values "on" and "off" keep
> working.
>
> Mostly compatible, because qapi_bool_parse() also recognizes "yes",
> "true", "y", "no", "false", and "n" for convenience, and these stop
> working. We have a knack for inventing convenience features that later
> bite us.
>
> JSON breaks entirely, of course: all values stop working.
>
> Even with external access, compatibility worries start only after we
> shipped the interface in a release. Did we?
those options were introduced in qemu 11.0. Fixing them in -rc is still
an option but it is a very tight schedule
Thanks
Eric
>
> If the interface was released, we should keep our promise to follow the
> process. From time to time, that's so onerous and we're so certain that
> nobody actually cares, we bend the rules. This should not be done
> lightly.
>
>>> Should I add a custom property setter that accepts both boolean and
>>> on/off/auto for backward compatibility, or is following the intremap
>>> precedent acceptable? I'm happy to implement either approach.
>>>
>>> [0]
>>> https://github.com/qemu/qemu/commit/a924b3d8df55a395891fd5ed341d0deb135d9aa6
>> Maybe we also need to emphasize that libvirt integration is still under
>> work (and waiting for that conversion to happen at qemu level). So do we
>> really care about keeping the compat wrt QMP and JSON.
> I can explain our promise and the process to you, but I can't make the
> decision to bend the rules for you.
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-12 8:51 ` Eric Auger
@ 2026-03-12 9:20 ` Markus Armbruster
2026-03-12 9:25 ` Eric Auger
0 siblings, 1 reply; 49+ messages in thread
From: Markus Armbruster @ 2026-03-12 9:20 UTC (permalink / raw)
To: Eric Auger
Cc: Nathan Chen, qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
Eric Auger <eric.auger@redhat.com> writes:
> On 3/12/26 9:39 AM, Markus Armbruster wrote:
[...]
>> We promise to follow a certain process when changing external
>> interfaces: docs/about/deprecated.rst.
>>
>> This is why I inquired about external access. No external access, no
>> compatibility worries.
>>
>> I specifically asked about JSON, because going from bool to OnOffAuto is
>> mostly compatible in key=value syntax: values "on" and "off" keep
>> working.
>>
>> Mostly compatible, because qapi_bool_parse() also recognizes "yes",
>> "true", "y", "no", "false", and "n" for convenience, and these stop
>> working. We have a knack for inventing convenience features that later
>> bite us.
>>
>> JSON breaks entirely, of course: all values stop working.
>>
>> Even with external access, compatibility worries start only after we
>> shipped the interface in a release. Did we?
> those options were introduced in qemu 11.0. Fixing them in -rc is still
> an option but it is a very tight schedule
If it turns out to be too tight, rever them or declare them
experimental? Then you can revise them without process hassle in the
next release.
[...]
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-12 9:20 ` Markus Armbruster
@ 2026-03-12 9:25 ` Eric Auger
2026-03-12 16:35 ` Nathan Chen
0 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-12 9:25 UTC (permalink / raw)
To: Markus Armbruster
Cc: Nathan Chen, qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan,
Peter Maydell, Shannon Zhao, Michael S . Tsirkin, Igor Mammedov,
Ani Sinha, Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
Nathan,
On 3/12/26 10:20 AM, Markus Armbruster wrote:
> Eric Auger <eric.auger@redhat.com> writes:
>
>> On 3/12/26 9:39 AM, Markus Armbruster wrote:
> [...]
>
>>> We promise to follow a certain process when changing external
>>> interfaces: docs/about/deprecated.rst.
>>>
>>> This is why I inquired about external access. No external access, no
>>> compatibility worries.
>>>
>>> I specifically asked about JSON, because going from bool to OnOffAuto is
>>> mostly compatible in key=value syntax: values "on" and "off" keep
>>> working.
>>>
>>> Mostly compatible, because qapi_bool_parse() also recognizes "yes",
>>> "true", "y", "no", "false", and "n" for convenience, and these stop
>>> working. We have a knack for inventing convenience features that later
>>> bite us.
>>>
>>> JSON breaks entirely, of course: all values stop working.
>>>
>>> Even with external access, compatibility worries start only after we
>>> shipped the interface in a release. Did we?
>> those options were introduced in qemu 11.0. Fixing them in -rc is still
>> an option but it is a very tight schedule
> If it turns out to be too tight, rever them or declare them
> experimental? Then you can revise them without process hassle in the
> next release.
Maybe Nathan, in a first step, you could just respin and convert the
options to the auto form, keeping the current default value and not
implementing the auto mode yet.
+ the ATS check fix? Shameer, Nathan, would that be sensible within the
qemu 11.0 -rc timeframe.
Eric
>
> [...]
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 7/8] qdev: Add an OasMode property
2026-03-11 18:24 ` Nathan Chen
@ 2026-03-12 9:29 ` Eric Auger
2026-03-12 16:32 ` Nathan Chen
0 siblings, 1 reply; 49+ messages in thread
From: Eric Auger @ 2026-03-12 9:29 UTC (permalink / raw)
To: Nathan Chen, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/11/26 7:24 PM, Nathan Chen wrote:
> Hi Eric,
>
> On 3/11/2026 11:20 AM, Eric Auger wrote:
>> Hi Nathan,
>>
>> On 3/9/26 8:21 PM, Nathan Chen wrote:
>>> From: Nathan Chen<nathanc@nvidia.com>
>>>
>>> Introduce a new enum type property allowing to set an Output Address
>>> Size. Values are auto, 44, and 48, where a value of N specifies an
>>> N-bit OAS.
>>>
>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>>> ---
>>> hw/core/qdev-properties-system.c | 13 +++++++++++++
>>> include/hw/core/qdev-properties-system.h | 3 +++
>>> qapi/misc-arm.json | 16 ++++++++++++++++
>>> 3 files changed, 32 insertions(+)
>>>
>>> diff --git a/hw/core/qdev-properties-system.c
>>> b/hw/core/qdev-properties-system.c
>>> index 4aca1d4326..a805ee2e1f 100644
>>> --- a/hw/core/qdev-properties-system.c
>>> +++ b/hw/core/qdev-properties-system.c
>>> @@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
>>> .set_default_value = qdev_propinfo_set_default_value_enum,
>>> };
>>> +/* --- OasMode --- */
>>> +
>>> +QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
>>> +
>>> +const PropertyInfo qdev_prop_oas_mode = {
>>> + .type = "OasMode",
>>> + .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
>>> + .enum_table = &OasMode_lookup,
>>> + .get = qdev_propinfo_get_enum,
>>> + .set = qdev_propinfo_set_enum,
>>> + .set_default_value = qdev_propinfo_set_default_value_enum,
>>> +};
>>> +
>>> /* --- Reserved Region --- */
>>> /*
>>> diff --git a/include/hw/core/qdev-properties-system.h
>>> b/include/hw/core/qdev-properties-system.h
>>> index 4708885164..2cbea16d61 100644
>>> --- a/include/hw/core/qdev-properties-system.h
>>> +++ b/include/hw/core/qdev-properties-system.h
>>> @@ -15,6 +15,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
>>> extern const PropertyInfo qdev_prop_granule_mode;
>>> extern const PropertyInfo qdev_prop_zero_page_detection;
>>> extern const PropertyInfo qdev_prop_ssidsize_mode;
>>> +extern const PropertyInfo qdev_prop_oas_mode;
>>> extern const PropertyInfo qdev_prop_losttickpolicy;
>>> extern const PropertyInfo qdev_prop_blockdev_on_error;
>>> extern const PropertyInfo qdev_prop_bios_chs_trans;
>>> @@ -64,6 +65,8 @@ extern const PropertyInfo
>>> qdev_prop_virtio_gpu_output_list;
>>> ZeroPageDetection)
>>> #define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
>>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode,
>>> SsidSizeMode)
>>> +#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
>>> + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
>>> #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
>>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
>>> LostTickPolicy)
>>> diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
>>> index b372a3661b..76b6965502 100644
>>> --- a/qapi/misc-arm.json
>>> +++ b/qapi/misc-arm.json
>>> @@ -60,3 +60,19 @@
>>> { 'enum': 'SsidSizeMode',
>>> 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
>>> '10', '11', '12', '13', '14', '15', '16', '17', '18',
>>> '19', '20' ] }
>>> +
>>> +##
>>> +# @OasMode:
>>> +#
>>> +# SMMUv3 Output Address Size configuration mode.
>>> +#
>>> +# @auto: derive from host IOMMU capabilities
>>> +#
>>> +# @44: 44-bit output address size
>>> +#
>>> +# @48: 48-bit output address size
>>> +#
>>> +# Since: 11.0
>>> +##
>>> +{ 'enum': 'OasMode',
>>> + 'data': [ 'auto', '44', '48' ] }
>> you also miss other enum values
>
> I left out the other possible OAS values because only 44 and 48 are
> supported per the previous accel SMMUv3 series. Should we still
> include the other possible OAS values according to the SMMUv3 spec? If
> we do, we would end up hitting that check for 44 or 48 bit OAS when a
> different value is specified.
I think we want to want to provision for all values supported by the
SMMUv3 spec
Eric
>
> Thanks,
> Nathan
>
^ permalink raw reply [flat|nested] 49+ messages in thread
* RE: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters
2026-03-12 8:37 ` Cédric Le Goater
@ 2026-03-12 9:29 ` Shameer Kolothum Thodi
0 siblings, 0 replies; 49+ messages in thread
From: Shameer Kolothum Thodi @ 2026-03-12 9:29 UTC (permalink / raw)
To: Cédric Le Goater, Nathan Chen, qemu-devel@nongnu.org,
qemu-arm@nongnu.org
Cc: Yi Liu, Eric Auger, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Eric Blake,
Markus Armbruster
> -----Original Message-----
> From: Cédric Le Goater <clg@redhat.com>
> Sent: 12 March 2026 08:37
> To: Shameer Kolothum Thodi <skolothumtho@nvidia.com>; Nathan Chen
> <nathanc@nvidia.com>; qemu-devel@nongnu.org; qemu-arm@nongnu.org
> Cc: Yi Liu <yi.l.liu@intel.com>; Eric Auger <eric.auger@redhat.com>;
> Zhenzhong Duan <zhenzhong.duan@intel.com>; Peter Maydell
> <peter.maydell@linaro.org>; Shannon Zhao <shannon.zhaosl@gmail.com>;
> Michael S . Tsirkin <mst@redhat.com>; Igor Mammedov
> <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>; Paolo
> Bonzini <pbonzini@redhat.com>; Daniel P . Berrangé
> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Eric Blake
> <eblake@redhat.com>; Markus Armbruster <armbru@redhat.com>
> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving
> auto parameters
>
> External email: Use caution opening links or attachments
>
>
> Hello Shameer
>
> On 3/10/26 09:40, Shameer Kolothum Thodi wrote:
> >
> >
> >> -----Original Message-----
> >> From: Cédric Le Goater <clg@redhat.com>
> >> Sent: 10 March 2026 07:42
> >> To: Nathan Chen <nathanc@nvidia.com>; qemu-devel@nongnu.org;
> qemu-
> >> arm@nongnu.org
> >> Cc: Yi Liu <yi.l.liu@intel.com>; Eric Auger <eric.auger@redhat.com>;
> >> Zhenzhong Duan <zhenzhong.duan@intel.com>; Peter Maydell
> >> <peter.maydell@linaro.org>; Shannon Zhao
> <shannon.zhaosl@gmail.com>;
> >> Michael S . Tsirkin <mst@redhat.com>; Igor Mammedov
> >> <imammedo@redhat.com>; Ani Sinha <anisinha@redhat.com>; Paolo
> >> Bonzini <pbonzini@redhat.com>; Daniel P . Berrangé
> >> <berrange@redhat.com>; Alex Williamson <alex@shazbot.org>; Eric Blake
> >> <eblake@redhat.com>; Markus Armbruster <armbru@redhat.com>;
> >> Shameer Kolothum Thodi <skolothumtho@nvidia.com>
> >> Subject: Re: [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for
> resolving
> >> auto parameters
> >>
> >> External email: Use caution opening links or attachments
> >>
> >>
> >> On 3/9/26 20:21, Nathan Chen wrote:
> >>> From: Nathan Chen <nathanc@nvidia.com>
> >>>
> >>> Introduce smmuv3_accel_auto_finalise() to resolve properties
> >>> that are set to 'auto' for accelerated SMMUv3. This helper
> >>> function allows properties such as ATS, RIL, SSIDSIZE, and OAS
> >>> support to be resolved from host IOMMU values, while avoiding
> >>> triggering auto-resolved values for hot-plugged devices.
> >>>
> >>> Auto mode requires at least one cold-plugged device to retrieve
> >>> and finalise these properties, and we fail boot if that is not
> >>> the case.
> >>
> >> IIUC, QEMU will require a minimum of one PCI device if
> >> arm-smmuv3,accel=on is passed on the command line and if the
> >> smmu properties are set to 'auto'.
> >
> > Yes, that’s correct.
> >
> >> I would try to enforce this requirement in the realize routine.
> >> Can't we leverage the supports_address_space() handler ? See :
> >>
> >>
> >> static bool smmuv3_accel_supports_as(PCIBus *bus, void *opaque, int
> >> devfn,
> >> Error **errp)
> >> {
> >> PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
> >> bool vfio_pci = false;
> >>
> >> if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) {
> >> if (vfio_pci) {
> >> error_setg(errp, "vfio-pci endpoint devices without an iommufd
> "
> >> "backend not allowed when using arm-
> smmuv3,accel=on");
> >> ...
> > Hmm..i doubt we can do it here as we need HostIOMMUDeviceIOMMUFD
> *idev
> > for retrieving the IOMMU_GET_HW_INFO.
> >
> > supports_address_space() is invoked very early during
> do_pci_register_device()
> > and there are no associated idev available at that time.
>
>
> yes. Have your considered adding an 'iommufd' property to smmuv3
> instead ? I think this should solve a lot of potential issues
> and would be more model friendly.
>
> Sorry if that was proposed already. I have been through all the
> emails.
As I replied in the other thread, we need an idev for retrieving hw info.
[...]
> >>
> >>> + exit(1);
> >>
> >> QEMU should not exit in the reset phase. Can this check be done during
> >> the realize stage ?
> >
> > SMMUv3 realize stage happens before the cold-plugged device
> > set_iommu_device(), and therefore we can't check whether the SMMUv3
> > properties have been retrieved and finalised at that point.
> >
> > Not sure there is any other place we can do this other than in the reset
> > path.
> >
> > Is avoiding exit(1) in the reset phase a strict requirement or a nice to
> > have one?
>
> reset is a runtime handler called at each reboot. One should not
> exit.
>
> We should try to verify that the conditions to run the machine
> are correct before reaching the reset phase.
>
Ok. In that case, could we register a qemu_add_machine_init_done_notifier()
for SMMUv3 and move this verification there?
Thanks,
Shameer
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 7/8] qdev: Add an OasMode property
2026-03-12 9:29 ` Eric Auger
@ 2026-03-12 16:32 ` Nathan Chen
0 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-12 16:32 UTC (permalink / raw)
To: eric.auger, qemu-devel, qemu-arm
Cc: Yi Liu, Zhenzhong Duan, Peter Maydell, Shannon Zhao,
Michael S . Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Daniel P . Berrangé, Alex Williamson, Cédric Le Goater,
Eric Blake, Markus Armbruster
On 3/12/2026 2:29 AM, Eric Auger wrote:
>
> On 3/11/26 7:24 PM, Nathan Chen wrote:
>> Hi Eric,
>>
>> On 3/11/2026 11:20 AM, Eric Auger wrote:
>>> Hi Nathan,
>>>
>>> On 3/9/26 8:21 PM, Nathan Chen wrote:
>>>> From: Nathan Chen<nathanc@nvidia.com>
>>>>
>>>> Introduce a new enum type property allowing to set an Output Address
>>>> Size. Values are auto, 44, and 48, where a value of N specifies an
>>>> N-bit OAS.
>>>>
>>>> Signed-off-by: Nathan Chen<nathanc@nvidia.com>
>>>> ---
>>>> hw/core/qdev-properties-system.c | 13 +++++++++++++
>>>> include/hw/core/qdev-properties-system.h | 3 +++
>>>> qapi/misc-arm.json | 16 ++++++++++++++++
>>>> 3 files changed, 32 insertions(+)
>>>>
>>>> diff --git a/hw/core/qdev-properties-system.c
>>>> b/hw/core/qdev-properties-system.c
>>>> index 4aca1d4326..a805ee2e1f 100644
>>>> --- a/hw/core/qdev-properties-system.c
>>>> +++ b/hw/core/qdev-properties-system.c
>>>> @@ -737,6 +737,19 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
>>>> .set_default_value = qdev_propinfo_set_default_value_enum,
>>>> };
>>>> +/* --- OasMode --- */
>>>> +
>>>> +QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
>>>> +
>>>> +const PropertyInfo qdev_prop_oas_mode = {
>>>> + .type = "OasMode",
>>>> + .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
>>>> + .enum_table = &OasMode_lookup,
>>>> + .get = qdev_propinfo_get_enum,
>>>> + .set = qdev_propinfo_set_enum,
>>>> + .set_default_value = qdev_propinfo_set_default_value_enum,
>>>> +};
>>>> +
>>>> /* --- Reserved Region --- */
>>>> /*
>>>> diff --git a/include/hw/core/qdev-properties-system.h
>>>> b/include/hw/core/qdev-properties-system.h
>>>> index 4708885164..2cbea16d61 100644
>>>> --- a/include/hw/core/qdev-properties-system.h
>>>> +++ b/include/hw/core/qdev-properties-system.h
>>>> @@ -15,6 +15,7 @@ extern const PropertyInfo qdev_prop_mig_mode;
>>>> extern const PropertyInfo qdev_prop_granule_mode;
>>>> extern const PropertyInfo qdev_prop_zero_page_detection;
>>>> extern const PropertyInfo qdev_prop_ssidsize_mode;
>>>> +extern const PropertyInfo qdev_prop_oas_mode;
>>>> extern const PropertyInfo qdev_prop_losttickpolicy;
>>>> extern const PropertyInfo qdev_prop_blockdev_on_error;
>>>> extern const PropertyInfo qdev_prop_bios_chs_trans;
>>>> @@ -64,6 +65,8 @@ extern const PropertyInfo
>>>> qdev_prop_virtio_gpu_output_list;
>>>> ZeroPageDetection)
>>>> #define DEFINE_PROP_SSIDSIZE_MODE(_n, _s, _f, _d) \
>>>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_ssidsize_mode,
>>>> SsidSizeMode)
>>>> +#define DEFINE_PROP_OAS_MODE(_n, _s, _f, _d) \
>>>> + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_oas_mode, OasMode)
>>>> #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
>>>> DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
>>>> LostTickPolicy)
>>>> diff --git a/qapi/misc-arm.json b/qapi/misc-arm.json
>>>> index b372a3661b..76b6965502 100644
>>>> --- a/qapi/misc-arm.json
>>>> +++ b/qapi/misc-arm.json
>>>> @@ -60,3 +60,19 @@
>>>> { 'enum': 'SsidSizeMode',
>>>> 'data': [ 'auto', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
>>>> '10', '11', '12', '13', '14', '15', '16', '17', '18',
>>>> '19', '20' ] }
>>>> +
>>>> +##
>>>> +# @OasMode:
>>>> +#
>>>> +# SMMUv3 Output Address Size configuration mode.
>>>> +#
>>>> +# @auto: derive from host IOMMU capabilities
>>>> +#
>>>> +# @44: 44-bit output address size
>>>> +#
>>>> +# @48: 48-bit output address size
>>>> +#
>>>> +# Since: 11.0
>>>> +##
>>>> +{ 'enum': 'OasMode',
>>>> + 'data': [ 'auto', '44', '48' ] }
>>> you also miss other enum values
>> I left out the other possible OAS values because only 44 and 48 are
>> supported per the previous accel SMMUv3 series. Should we still
>> include the other possible OAS values according to the SMMUv3 spec? If
>> we do, we would end up hitting that check for 44 or 48 bit OAS when a
>> different value is specified.
> I think we want to want to provision for all values supported by the
> SMMUv3 spec
Ok, I will include all the values in the next refresh.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS
2026-03-12 9:25 ` Eric Auger
@ 2026-03-12 16:35 ` Nathan Chen
0 siblings, 0 replies; 49+ messages in thread
From: Nathan Chen @ 2026-03-12 16:35 UTC (permalink / raw)
To: eric.auger, Markus Armbruster
Cc: qemu-devel, qemu-arm, Yi Liu, Zhenzhong Duan, Peter Maydell,
Shannon Zhao, Michael S . Tsirkin, Igor Mammedov, Ani Sinha,
Paolo Bonzini, Daniel P.Berrangé, Alex Williamson,
Cédric Le Goater, Eric Blake
On 3/12/2026 2:25 AM, Eric Auger wrote:
> On 3/12/26 10:20 AM, Markus Armbruster wrote:
>> Eric Auger<eric.auger@redhat.com> writes:
>>
>>> On 3/12/26 9:39 AM, Markus Armbruster wrote:
>> [...]
>>
>>>> We promise to follow a certain process when changing external
>>>> interfaces: docs/about/deprecated.rst.
>>>>
>>>> This is why I inquired about external access. No external access, no
>>>> compatibility worries.
>>>>
>>>> I specifically asked about JSON, because going from bool to OnOffAuto is
>>>> mostly compatible in key=value syntax: values "on" and "off" keep
>>>> working.
>>>>
>>>> Mostly compatible, because qapi_bool_parse() also recognizes "yes",
>>>> "true", "y", "no", "false", and "n" for convenience, and these stop
>>>> working. We have a knack for inventing convenience features that later
>>>> bite us.
>>>>
>>>> JSON breaks entirely, of course: all values stop working.
>>>>
>>>> Even with external access, compatibility worries start only after we
>>>> shipped the interface in a release. Did we?
>>> those options were introduced in qemu 11.0. Fixing them in -rc is still
>>> an option but it is a very tight schedule
>> If it turns out to be too tight, rever them or declare them
>> experimental? Then you can revise them without process hassle in the
>> next release.
> Maybe Nathan, in a first step, you could just respin and convert the
> options to the auto form, keeping the current default value and not
> implementing the auto mode yet.
> + the ATS check fix? Shameer, Nathan, would that be sensible within the
> qemu 11.0 -rc timeframe.
Yes, we will respin with just the auto form conversion and include the
ATS check fix.
Thanks,
Nathan
^ permalink raw reply [flat|nested] 49+ messages in thread
end of thread, other threads:[~2026-03-12 16:36 UTC | newest]
Thread overview: 49+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 19:21 [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 1/8] hw/arm/smmuv3-accel: Add helper for resolving auto parameters Nathan Chen
2026-03-10 7:00 ` Markus Armbruster
2026-03-10 9:01 ` Shameer Kolothum Thodi
2026-03-12 8:20 ` Markus Armbruster
2026-03-12 8:33 ` Shameer Kolothum Thodi
2026-03-12 8:39 ` Cédric Le Goater
2026-03-12 8:44 ` Shameer Kolothum Thodi
2026-03-10 7:42 ` Cédric Le Goater
2026-03-10 8:40 ` Shameer Kolothum Thodi
2026-03-12 8:37 ` Cédric Le Goater
2026-03-12 9:29 ` Shameer Kolothum Thodi
2026-03-10 17:13 ` Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 2/8] hw/arm/smmuv3-accel: Introduce _AUTO support for ATS Nathan Chen
2026-03-10 7:05 ` Markus Armbruster
2026-03-10 17:35 ` Nathan Chen
2026-03-11 15:31 ` Eric Auger
2026-03-11 17:08 ` Nathan Chen
2026-03-11 17:16 ` Eric Auger
2026-03-11 18:09 ` Pavel Hrdina
2026-03-12 8:39 ` Markus Armbruster
2026-03-12 8:51 ` Eric Auger
2026-03-12 9:20 ` Markus Armbruster
2026-03-12 9:25 ` Eric Auger
2026-03-12 16:35 ` Nathan Chen
2026-03-12 8:52 ` Eric Auger
2026-03-11 17:24 ` Eric Auger
2026-03-11 17:46 ` Eric Auger
2026-03-11 17:53 ` Nathan Chen
2026-03-11 18:10 ` Eric Auger
2026-03-11 18:21 ` Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 3/8] vfio/pci: Add ats property and mask ATS cap when not exposed Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 4/8] hw/arm/smmuv3-accel: Introduce _AUTO support for RIL Nathan Chen
2026-03-10 7:06 ` Markus Armbruster
2026-03-09 19:21 ` [RFC PATCH 5/8] qdev: Add a SsidSizeMode property Nathan Chen
2026-03-10 7:14 ` Markus Armbruster
2026-03-09 19:21 ` [RFC PATCH 6/8] hw/arm/smmuv3-accel: Introduce _AUTO support for SSID size Nathan Chen
2026-03-10 7:21 ` Markus Armbruster
2026-03-10 17:44 ` Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 7/8] qdev: Add an OasMode property Nathan Chen
2026-03-11 18:20 ` Eric Auger
2026-03-11 18:24 ` Nathan Chen
2026-03-12 9:29 ` Eric Auger
2026-03-12 16:32 ` Nathan Chen
2026-03-09 19:21 ` [RFC PATCH 8/8] hw/arm/smmuv3-accel: Introduce _AUTO support for OAS Nathan Chen
2026-03-10 7:23 ` Markus Armbruster
2026-03-11 17:43 ` [RFC PATCH 0/8] hw/arm/smmuv3-accel: Support AUTO properties Eric Auger
2026-03-11 17:55 ` Nathan Chen
2026-03-11 18:25 ` Eric Auger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox