/* 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);