As everything is in place, we can use a new system property to
advertise which stage is supported and remove bad_ste from STE
stage2 config.
The property added arm-smmuv3.stage can have 3 values:
- "1": Stage-1 only is advertised.
- "2": Stage-2 only is advertised.
- "all": Stage-1 + Stage-2 are supported, which is not implemented in
this patch series.
If not passed or an unsupported value is passed, it will default to
stage-1.
Advertise VMID16.
Don't try to decode CD, if stage-2 is configured.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
Changes in v2:
- Squash knob patch with stage-2 enable patch.
- Don't try to decode CD, if stage-2 is configured.
---
hw/arm/smmuv3.c | 34 +++++++++++++++++++++++++---------
include/hw/arm/smmuv3.h | 1 +
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 826aacf8b1..22b5613d4c 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -21,6 +21,7 @@
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
#include "hw/qdev-core.h"
#include "hw/pci/pci.h"
#include "cpu.h"
@@ -248,14 +249,20 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
static void smmuv3_init_regs(SMMUv3State *s)
{
- /**
- * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
- * multi-level stream table
+ /*
+ * Based on sys property, the stages supported in smmu will be advertised.
+ * At the moment "all" is not supported and default to stage-1.
*/
- s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
+ if (s->stage && !strcmp("2", s->stage)) {
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S2P, 1);
+ } else {
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1);
+ }
+
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, VMID16, 1); /* 16-bit VMID */
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
/* terminated transaction will always be aborted/error returned */
@@ -458,10 +465,6 @@ static int decode_ste_s2_cfg(SMMUTransCfg *cfg, STE *ste)
goto bad_ste;
}
- /* This is still here as stage 2 has not been fully enabled yet. */
- qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
- goto bad_ste;
-
return 0;
bad_ste:
@@ -740,7 +743,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
return ret;
}
- if (cfg->aborted || cfg->bypassed) {
+ if (cfg->aborted || cfg->bypassed || (cfg->stage == 2)) {
return 0;
}
@@ -1809,6 +1812,18 @@ static const VMStateDescription vmstate_smmuv3 = {
}
};
+static Property smmuv3_properties[] = {
+ /*
+ * Stages of translation advertised.
+ * "1": Stage 1
+ * "2": Stage 2
+ * "all": Stage 1 + Stage 2
+ * Defaults to stage 1
+ */
+ DEFINE_PROP_STRING("stage", SMMUv3State, stage),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void smmuv3_instance_init(Object *obj)
{
/* Nothing much to do here as of now */
@@ -1825,6 +1840,7 @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
&c->parent_phases);
c->parent_realize = dc->realize;
dc->realize = smmu_realize;
+ device_class_set_props(dc, smmuv3_properties);
}
static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index 6031d7d325..d183a62766 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -62,6 +62,7 @@ struct SMMUv3State {
qemu_irq irq[4];
QemuMutex mutex;
+ char *stage;
};
typedef enum {
--
2.40.0.348.gf938b09366-goog
Hi Mostafa,
On 4/1/23 12:49, Mostafa Saleh wrote:
> As everything is in place, we can use a new system property to
> advertise which stage is supported and remove bad_ste from STE
> stage2 config.
>
> The property added arm-smmuv3.stage can have 3 values:
> - "1": Stage-1 only is advertised.
> - "2": Stage-2 only is advertised.
> - "all": Stage-1 + Stage-2 are supported, which is not implemented in
> this patch series.
>
> If not passed or an unsupported value is passed, it will default to
> stage-1.
>
> Advertise VMID16.
>
> Don't try to decode CD, if stage-2 is configured.
>
> Signed-off-by: Mostafa Saleh <smostafa@google.com>
> ---
> Changes in v2:
> - Squash knob patch with stage-2 enable patch.
> - Don't try to decode CD, if stage-2 is configured.
> ---
> hw/arm/smmuv3.c | 34 +++++++++++++++++++++++++---------
> include/hw/arm/smmuv3.h | 1 +
> 2 files changed, 26 insertions(+), 9 deletions(-)
>
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 826aacf8b1..22b5613d4c 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -21,6 +21,7 @@
> #include "hw/irq.h"
> #include "hw/sysbus.h"
> #include "migration/vmstate.h"
> +#include "hw/qdev-properties.h"
> #include "hw/qdev-core.h"
> #include "hw/pci/pci.h"
> #include "cpu.h"
> @@ -248,14 +249,20 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
>
> static void smmuv3_init_regs(SMMUv3State *s)
> {
> - /**
> - * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
> - * multi-level stream table
> + /*
> + * Based on sys property, the stages supported in smmu will be advertised.
> + * At the moment "all" is not supported and default to stage-1.
> */
> - s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
> + if (s->stage && !strcmp("2", s->stage)) {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S2P, 1);
> + } else {
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1);
> + }
> +
> s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
> s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
> s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
> + s->idr[0] = FIELD_DP32(s->idr[0], IDR0, VMID16, 1); /* 16-bit VMID */
> s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
> s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
> /* terminated transaction will always be aborted/error returned */
> @@ -458,10 +465,6 @@ static int decode_ste_s2_cfg(SMMUTransCfg *cfg, STE *ste)
> goto bad_ste;
> }
>
> - /* This is still here as stage 2 has not been fully enabled yet. */
> - qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
> - goto bad_ste;
> -
> return 0;
>
> bad_ste:
> @@ -740,7 +743,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
> return ret;
> }
>
> - if (cfg->aborted || cfg->bypassed) {
> + if (cfg->aborted || cfg->bypassed || (cfg->stage == 2)) {
> return 0;
> }
>
> @@ -1809,6 +1812,18 @@ static const VMStateDescription vmstate_smmuv3 = {
> }
> };
>
> +static Property smmuv3_properties[] = {
> + /*
> + * Stages of translation advertised.
> + * "1": Stage 1
> + * "2": Stage 2
> + * "all": Stage 1 + Stage 2
I don't think you should talk about 'all' at the moment.
Besides
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Eric
> + * Defaults to stage 1
> + */
> + DEFINE_PROP_STRING("stage", SMMUv3State, stage),
> + DEFINE_PROP_END_OF_LIST()
> +};
> +
> static void smmuv3_instance_init(Object *obj)
> {
> /* Nothing much to do here as of now */
> @@ -1825,6 +1840,7 @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
> &c->parent_phases);
> c->parent_realize = dc->realize;
> dc->realize = smmu_realize;
> + device_class_set_props(dc, smmuv3_properties);
> }
>
> static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 6031d7d325..d183a62766 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -62,6 +62,7 @@ struct SMMUv3State {
>
> qemu_irq irq[4];
> QemuMutex mutex;
> + char *stage;
> };
>
> typedef enum {
© 2016 - 2026 Red Hat, Inc.