qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, berrange@redhat.com, eduardo@habkost.net,
	armbru@redhat.com, ajones@ventanamicro.com,
	alex.bennee@linaro.org
Subject: [RFC PATCH 35/40] target/arm: Move "has_el2" to class property
Date: Tue,  3 Jan 2023 10:16:41 -0800	[thread overview]
Message-ID: <20230103181646.55711-36-richard.henderson@linaro.org> (raw)
In-Reply-To: <20230103181646.55711-1-richard.henderson@linaro.org>

With the movement of the property, we can remove the field from the
cpu entirely, using only the class.  However, late initialization
of the "max" cpu, due to its interaction with "host", means that we
cannot leave the class property undefined when EL2 is not supported.
Adjust the class field to OnOffAuto and generate an error if enabled
when not supported.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu-qom.h  |  4 +++
 target/arm/cpu.h      |  3 --
 hw/arm/allwinner-h3.c |  9 ++++--
 hw/arm/vexpress.c     | 10 +++---
 hw/arm/virt.c         | 22 ++++++++-----
 hw/arm/xlnx-zynqmp.c  |  3 +-
 hw/cpu/a15mpcore.c    |  9 +++---
 target/arm/cpu.c      | 74 ++++++++++++++++++++++++++++++++++++-------
 8 files changed, 98 insertions(+), 36 deletions(-)

diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
index 2d6fa38a30..fceb557a4d 100644
--- a/target/arm/cpu-qom.h
+++ b/target/arm/cpu-qom.h
@@ -22,6 +22,7 @@
 
 #include "hw/core/cpu.h"
 #include "qom/object.h"
+#include "qapi/qapi-types-common.h"
 
 struct arm_boot_info;
 
@@ -182,6 +183,9 @@ struct ARMCPUClass {
      * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
      */
     uint32_t kvm_target;
+
+    /* CPU has virtualization extension */
+    OnOffAuto has_el2;
 };
 
 static inline int arm_class_feature(ARMCPUClass *acc, int feature)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c0baec37d7..3888cdafdf 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -25,7 +25,6 @@
 #include "hw/registerfields.h"
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
-#include "qapi/qapi-types-common.h"
 
 /* ARM processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO      (0)
@@ -887,8 +886,6 @@ struct ArchCPU {
     /* Current power state, access guarded by BQL */
     ARMPSCIState power_state;
 
-    /* CPU has virtualization extension */
-    bool has_el2;
     /* CPU has security extension */
     bool has_el3;
     /* CPU has PMU (Performance Monitor Unit) */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index 308ed15552..07484b9f97 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -188,12 +188,16 @@ void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk)
 static void allwinner_h3_init(Object *obj)
 {
     AwH3State *s = AW_H3(obj);
+    const char *cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
+    ObjectClass *cpu_class = object_class_by_name(cpu_type);
 
     s->memmap = allwinner_h3_memmap;
 
+    /* ??? This is the default for A7. */
+    class_property_set_bool(cpu_class, "has_el2", true, &error_abort);
+
     for (int i = 0; i < AW_H3_NUM_CPUS; i++) {
-        object_initialize_child(obj, "cpu[*]", &s->cpus[i],
-                                ARM_CPU_TYPE_NAME("cortex-a7"));
+        object_initialize_child(obj, "cpu[*]", &s->cpus[i], cpu_type);
     }
 
     object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
@@ -244,7 +248,6 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
 
         /* All exception levels required */
         qdev_prop_set_bit(DEVICE(&s->cpus[i]), "has_el3", true);
-        qdev_prop_set_bit(DEVICE(&s->cpus[i]), "has_el2", true);
 
         /* Mark realized */
         qdev_realize(DEVICE(&s->cpus[i]), NULL, &error_fatal);
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index e1d1983ae6..211daa8fde 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -208,6 +208,11 @@ static void init_cpus(MachineState *ms, const char *cpu_type,
     SysBusDevice *busdev;
     int n;
     unsigned int smp_cpus = ms->smp.cpus;
+    ObjectClass *cpu_class = object_class_by_name(cpu_type);
+
+    if (!virt) {
+        class_property_set_bool(cpu_class, "has_el2", false, NULL);
+    }
 
     /* Create the actual CPUs */
     for (n = 0; n < smp_cpus; n++) {
@@ -216,11 +221,6 @@ static void init_cpus(MachineState *ms, const char *cpu_type,
         if (!secure) {
             object_property_set_bool(cpuobj, "has_el3", false, NULL);
         }
-        if (!virt) {
-            if (object_property_find(cpuobj, "has_el2")) {
-                object_property_set_bool(cpuobj, "has_el2", false, NULL);
-            }
-        }
 
         if (object_property_find(cpuobj, "reset-cbar")) {
             object_property_set_int(cpuobj, "reset-cbar", periphbase,
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index aed86997c0..dd02e42f97 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2018,6 +2018,7 @@ static void machvirt_init(MachineState *machine)
     MemoryRegion *secure_sysmem = NULL;
     MemoryRegion *tag_sysmem = NULL;
     MemoryRegion *secure_tag_sysmem = NULL;
+    ObjectClass *cpu_class;
     int n, virt_max_cpus;
     bool firmware_loaded;
     bool aarch64 = true;
@@ -2032,6 +2033,16 @@ static void machvirt_init(MachineState *machine)
 
     possible_cpus = mc->possible_cpu_arch_ids(machine);
 
+    assert(possible_cpus->len == max_cpus);
+    for (n = 0; n < max_cpus; n++) {
+        assert(strcmp(machine->cpu_type, possible_cpus->cpus[n].type) == 0);
+    }
+
+    cpu_class = object_class_by_name(machine->cpu_type);
+    if (!vms->virt) {
+        class_property_set_bool(cpu_class, "has_el2", false, &error_abort);
+    }
+
     /*
      * In accelerated mode, the memory map is computed earlier in kvm_type()
      * to create a VM with the right number of IPA bits.
@@ -2046,7 +2057,7 @@ static void machvirt_init(MachineState *machine)
          * we are about to deal with. Once this is done, get rid of
          * the object.
          */
-        cpuobj = object_new(possible_cpus->cpus[0].type);
+        cpuobj = object_new_with_class(cpu_class);
         armcpu = ARM_CPU(cpuobj);
 
         pa_bits = arm_pamax(armcpu);
@@ -2143,8 +2154,7 @@ static void machvirt_init(MachineState *machine)
 
     create_fdt(vms);
 
-    assert(possible_cpus->len == max_cpus);
-    for (n = 0; n < possible_cpus->len; n++) {
+    for (n = 0; n < max_cpus; n++) {
         Object *cpuobj;
         CPUState *cs;
 
@@ -2152,7 +2162,7 @@ static void machvirt_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(possible_cpus->cpus[n].type);
+        cpuobj = object_new_with_class(cpu_class);
         object_property_set_int(cpuobj, "mp-affinity",
                                 possible_cpus->cpus[n].arch_id, NULL);
 
@@ -2168,10 +2178,6 @@ static void machvirt_init(MachineState *machine)
             object_property_set_bool(cpuobj, "has_el3", false, NULL);
         }
 
-        if (!vms->virt && object_property_find(cpuobj, "has_el2")) {
-            object_property_set_bool(cpuobj, "has_el2", false, NULL);
-        }
-
         if (vmc->kvm_no_adjvtime &&
             object_property_find(cpuobj, "kvm-no-adjvtime")) {
             object_property_set_bool(cpuobj, "kvm-no-adjvtime", true, NULL);
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 13ab999eb8..17bad9b4ed 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -385,6 +385,7 @@ static void xlnx_zynqmp_init(Object *obj)
     cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
     cpu_class = object_class_by_name(cpu_type);
     class_property_set_bool(cpu_class, "reset-hivecs", true, &error_abort);
+    class_property_set_bool(cpu_class, "has_el2", s->virt, &error_abort);
 
     for (i = 0; i < num_apus; i++) {
         object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
@@ -529,8 +530,6 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 
         object_property_set_bool(OBJECT(&s->apu_cpu[i]), "has_el3", s->secure,
                                  NULL);
-        object_property_set_bool(OBJECT(&s->apu_cpu[i]), "has_el2", s->virt,
-                                 NULL);
         object_property_set_int(OBJECT(&s->apu_cpu[i]), "reset-cbar",
                                 GIC_BASE_ADDR, &error_abort);
         object_property_set_int(OBJECT(&s->apu_cpu[i]), "core-count",
diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index 774ca9987a..6329d25f68 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -55,7 +55,6 @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
     int i;
     bool has_el3;
     bool has_el2 = false;
-    Object *cpuobj;
 
     gicdev = DEVICE(&s->gic);
     qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
@@ -65,13 +64,15 @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
         /* Make the GIC's TZ support match the CPUs. We assume that
          * either all the CPUs have TZ, or none do.
          */
-        cpuobj = OBJECT(qemu_get_cpu(0));
+        Object *cpuobj = OBJECT(qemu_get_cpu(0));
+        ObjectClass *cpucls = object_get_class(cpuobj);
+
         has_el3 = object_property_find(cpuobj, "has_el3") &&
             object_property_get_bool(cpuobj, "has_el3", &error_abort);
         qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3);
+
         /* Similarly for virtualization support */
-        has_el2 = object_property_find(cpuobj, "has_el2") &&
-            object_property_get_bool(cpuobj, "has_el2", &error_abort);
+        has_el2 = class_property_get_bool(cpucls, "has_el2", NULL);
         qdev_prop_set_bit(gicdev, "has-virtualization-extensions", has_el2);
     }
 
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 032a2cc00a..db996d8c3a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1281,9 +1281,6 @@ static Property arm_cpu_reset_cbar_property =
             DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
 
 #ifndef CONFIG_USER_ONLY
-static Property arm_cpu_has_el2_property =
-            DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
-
 static Property arm_cpu_has_el3_property =
             DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
 #endif
@@ -1391,10 +1388,6 @@ static void arm_cpu_post_init(Object *obj)
                                  qdev_prop_allow_set_link_before_realize,
                                  OBJ_PROP_LINK_STRONG);
     }
-
-    if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
-        qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property);
-    }
 #endif
 
     if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
@@ -1818,10 +1811,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
                                            ID_AA64PFR0, EL3, 0);
     }
 
-    if (!cpu->has_el2) {
-        unset_feature(env, ARM_FEATURE_EL2);
-    }
-
     if (!cpu->has_pmu) {
         unset_feature(env, ARM_FEATURE_PMU);
     }
@@ -2159,6 +2148,34 @@ static bool arm_class_prop_uint64_ofs(ObjectClass *oc, Visitor *v,
 }
 
 #ifndef CONFIG_USER_ONLY
+static bool arm_class_prop_get_auto_ofs(ObjectClass *oc, Visitor *v,
+                                        const char *name, void *opaque,
+                                        Error **errp)
+{
+    ARMCPUClass *acc = ARM_CPU_CLASS(oc);
+    uintptr_t ofs = (uintptr_t)opaque;
+    OnOffAuto *ptr = (void *)acc + ofs;
+    bool val = *ptr == ON_OFF_AUTO_ON;
+
+    return visit_type_bool(v, name, &val, errp);
+}
+
+static bool arm_class_prop_set_auto_ofs(ObjectClass *oc, Visitor *v,
+                                        const char *name, void *opaque,
+                                        Error **errp)
+{
+    ARMCPUClass *acc = ARM_CPU_CLASS(oc);
+    uintptr_t ofs = (uintptr_t)opaque;
+    OnOffAuto *ptr = (void *)acc + ofs;
+    bool val;
+
+    if (visit_type_bool(v, name, &val, errp)) {
+        *ptr = val ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+        return true;
+    }
+    return false;
+}
+
 static bool arm_class_prop_set_sctlrbit(ObjectClass *oc, Visitor *v,
                                         const char *name, void *opaque,
                                         Error **errp)
@@ -2334,6 +2351,19 @@ static void arm_cpu_leaf_class_init(ObjectClass *oc, void *data)
                            arm_class_prop_set_sctlrbit,
                            (void *)((uintptr_t)1 << 13));
     }
+
+    /*
+     * With v8, we cannot yet tell if EL[23] are available, because
+     * we do not yet know if we're using tcg or host acceleration.
+     * We will reject incorrect settings during class_late_init.
+     */
+    if (arm_class_feature(acc, ARM_FEATURE_EL2) ||
+        arm_class_feature(acc, ARM_FEATURE_V8)) {
+        class_property_add(oc, "has_el2", "bool", NULL,
+                           arm_class_prop_get_auto_ofs,
+                           arm_class_prop_set_auto_ofs,
+                           (void *)(uintptr_t)offsetof(ARMCPUClass, has_el2));
+    }
 #endif /* !CONFIG_USER_ONLY */
 }
 
@@ -2353,6 +2383,28 @@ static bool arm_cpu_class_late_init(ObjectClass *oc, Error **errp)
         error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz", acc->gt_cntfrq_hz);
         return false;
     }
+
+    switch (acc->has_el2) {
+    case ON_OFF_AUTO_AUTO:
+        acc->has_el2 = (arm_class_feature(acc, ARM_FEATURE_EL2)
+                        ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF);
+        break;
+    case ON_OFF_AUTO_OFF:
+        unset_class_feature(acc, ARM_FEATURE_EL2);
+        acc->isar.id_pfr1 = FIELD_DP32(acc->isar.id_pfr1, ID_PFR1,
+                                       VIRTUALIZATION, 0);
+        acc->isar.id_aa64pfr0 = FIELD_DP64(acc->isar.id_aa64pfr0,
+                                           ID_AA64PFR0, EL2, 0);
+        break;
+    case ON_OFF_AUTO_ON:
+        if (!arm_class_feature(acc, ARM_FEATURE_EL2)) {
+            error_setg(errp, "CPU does not support EL2");
+            return false;
+        }
+        break;
+    default:
+        g_assert_not_reached();
+    }
 #endif /* !CONFIG_USER_ONLY */
 
     /* Run some consistency checks for TCG. */
-- 
2.34.1



  parent reply	other threads:[~2023-01-03 18:22 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-03 18:16 [RFC PATCH 00/40] Toward class init of cpu features Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 01/40] qdev: Don't always force the global property array non-null Richard Henderson
2023-01-05 21:56   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 02/40] qom: Introduce class_late_init Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 03/40] qom: Create class properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 04/40] target/arm: Remove aarch64_cpu_finalizefn Richard Henderson
2023-01-05 21:51   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 05/40] target/arm: Create arm_cpu_register_parent Richard Henderson
2023-01-05 21:57   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 06/40] target/arm: Remove AArch64CPUClass Richard Henderson
2023-01-05 21:50   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 07/40] target/arm: Create TYPE_ARM_V7M_CPU Richard Henderson
2023-01-05 21:58   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 08/40] target/arm: Pass ARMCPUClass to ARMCPUInfo.class_init Richard Henderson
2023-01-05 22:00   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 09/40] target/arm: Utilize arm-cpu instance_post_init hook Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 10/40] target/arm: Copy dtb_compatible from ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 11/40] target/arm: Copy features " Richard Henderson
2023-01-05 22:04   ` Philippe Mathieu-Daudé
2023-01-06  2:19     ` Richard Henderson
2023-01-06  7:14       ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 12/40] target/arm: Copy isar and friends " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 13/40] hw/arm/bcm2836: Set mp-affinity property in realize Richard Henderson
2023-01-05 21:48   ` Philippe Mathieu-Daudé
2023-01-06  7:51     ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 14/40] target/arm: Rename arm_cpu_mp_affinity Richard Henderson
2023-01-05 21:55   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 15/40] target/arm: Create arm_cpu_mp_affinity Richard Henderson
2023-01-05 21:53   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 16/40] target/arm: Represent the entire MPIDR_EL1 Richard Henderson
2023-01-06 19:16   ` Peter Maydell
2023-01-06 19:33     ` Richard Henderson
2023-01-06 22:14       ` Peter Maydell
2023-01-06 22:36         ` Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 17/40] target/arm: Copy cp_regs from ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 18/40] target/arm: Create cpreg definition functions with GHashTable arg Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 19/40] target/arm: Move most cpu initialization to the class Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 20/40] target/arm: Merge kvm64.c with kvm.c Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 21/40] target/arm: Remove aarch64 check from aarch64_host_object_init Richard Henderson
2023-01-05 22:08   ` Philippe Mathieu-Daudé
2023-01-06  2:21     ` Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 22/40] target/arm: Hoist feature and dtb_compatible from KVM, HVF Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 23/40] target/arm: Probe KVM host into ARMCPUClass Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 24/40] target/arm/hvf: Probe " Richard Henderson
2023-01-05 22:10   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 25/40] target/arm/hvf: Use offsetof in hvf_arm_get_host_cpu_features Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 26/40] target/arm: Rename 'cpu' to 'acc' in class init functions Richard Henderson
2023-01-03 19:24   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 27/40] target/arm: Split out strongarm_class_init Richard Henderson
2023-01-05 22:12   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 28/40] target/arm: Split out xscale*_class_init Richard Henderson
2023-01-05 22:13   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 29/40] target/arm: Remove m-profile has_vfp and has_dsp properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 30/40] target/arm: Move feature bit propagation to class init Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 31/40] target/arm: Get and set class properties in the monitor Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 32/40] target/arm: Move "midr" to class property Richard Henderson
2023-01-05 22:18   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 33/40] target/arm: Move "cntfrq" " Richard Henderson
2023-01-05 22:21   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 34/40] target/arm: Move "reset-hivecs" " Richard Henderson
2023-01-03 18:16 ` Richard Henderson [this message]
2023-01-03 18:16 ` [RFC PATCH 36/40] target/arm: Move "has_el3" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 37/40] target/arm: Move "cfgend" " Richard Henderson
2023-01-05 22:23   ` Philippe Mathieu-Daudé
2023-01-03 18:16 ` [RFC PATCH 38/40] target/arm: Move "vfp" and "neon" to class properties Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 39/40] target/arm: Move "has-mpu" and "pmsav7-dregion" " Richard Henderson
2023-01-03 18:16 ` [RFC PATCH 40/40] target/arm: Move "pmu" to class property Richard Henderson
2023-01-04  0:01 ` [RFC PATCH 00/40] Toward class init of cpu features Richard Henderson
2023-01-06 19:12 ` Peter Maydell
2023-01-06 19:29   ` Richard Henderson
2023-01-06 21:59     ` Peter Maydell
2023-01-06 22:28       ` Richard Henderson
2023-01-07 13:14         ` Peter Maydell
2023-01-06 23:43       ` Alex Bennée
2023-01-06 23:57         ` Richard Henderson
2023-01-07 10:19           ` Alex Bennée
2023-01-07 17:53             ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230103181646.55711-36-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=ajones@ventanamicro.com \
    --cc=alex.bennee@linaro.org \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).