[PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection

Daniel Henrique Barboza posted 1 patch 1 day, 1 hour ago
target/riscv/cpu.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
[PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection
Posted by Daniel Henrique Barboza 1 day, 1 hour ago
Maruks reported in [1] a problem with QMP introspection with
qemu-system-riscv64 that happens after querying a profile CPU.  QEMU
crashes hitting an abort during satp_mode logic that, somehow, is being
triggered via profile code.

For every profile CPU that goes through init we're setting an 'enabled'
flag in the static RISCVProfile object.  This sounded like an okay idea
back when profiles were introduced, but now we've realized that QMP will
querying CPUs without exiting the QEMU process while also going multiple
times through cpu_init() and friends.  The result is that we're in a
situation where we have runtime information being stored in static arrays
that persists between CPU definitions being introspected.

A proper fix is to get rid of profile->enabled and turn profiles into
cpu->cfg flags like we do with every other extension.  Unfortunately
we've been using profile->enabled for lots of things and a redesign
would be in order, one which I'm not comfortable doing right now - we're
too close to the QEMU 11.2 code freeze for such a change.

For now let's silver tape a fix in cpu_init() to reset profile->enabled
for all available profiles.  We'll do a proper redesign in the next
release cycle.

[1] https://lore.kernel.org/qemu-devel/87ld7rmdi6.fsf@pond.sub.org/

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
 target/riscv/cpu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 08a4d14ea1..46b74302db 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1550,6 +1550,25 @@ static void riscv_cpu_init(Object *obj)
     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
     cpu->cfg.max_satp_mode = -1;
 
+    /*
+     * The way we're handling profiles does not cope well with QMP
+     * instropection.  We have a static array that stores RISCVCPUProfiles
+     * objs that hold runtime state for the lifetime of the QEMU process.
+     * Thus setting profile->enabled once, e.g. when instropecting a
+     * profile CPU, will leave the flag set for subsequent intropections.
+     *
+     * For now, clear all 'enabled' flags to avoid misleading QMP w.r.t
+     * profiles being set.
+     *
+     * FIXME: a better long term solution is to remove profile->enabled
+     * and just use regular cpu->cfg flags, avoiding static variables
+     * storing dynamic state.  This will help us not only with QMP but
+     * also single-binary support.
+     */
+    for (int i = 0; riscv_profiles[i] != NULL; i++) {
+        riscv_profiles[i]->enabled = false;
+    }
+
     if (mcc->def->profile) {
         mcc->def->profile->enabled = true;
     }
-- 
2.43.0
Re: [PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection
Posted by Markus Armbruster 13 hours ago
Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> writes:

> Maruks reported in [1] a problem with QMP introspection with
> qemu-system-riscv64 that happens after querying a profile CPU.  QEMU
> crashes hitting an abort during satp_mode logic that, somehow, is being
> triggered via profile code.
>
> For every profile CPU that goes through init we're setting an 'enabled'
> flag in the static RISCVProfile object.  This sounded like an okay idea
> back when profiles were introduced, but now we've realized that QMP will
> querying CPUs without exiting the QEMU process while also going multiple
> times through cpu_init() and friends.  The result is that we're in a
> situation where we have runtime information being stored in static arrays
> that persists between CPU definitions being introspected.
>
> A proper fix is to get rid of profile->enabled and turn profiles into
> cpu->cfg flags like we do with every other extension.  Unfortunately
> we've been using profile->enabled for lots of things and a redesign
> would be in order, one which I'm not comfortable doing right now - we're
> too close to the QEMU 11.2 code freeze for such a change.
>
> For now let's silver tape a fix in cpu_init() to reset profile->enabled
> for all available profiles.  We'll do a proper redesign in the next
> release cycle.
>
> [1] https://lore.kernel.org/qemu-devel/87ld7rmdi6.fsf@pond.sub.org/
>
> Reported-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>

That was quick, thank you!

Tested-by: Markus Armbruster <armbru@redhat.com>
Re: [PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection
Posted by Daniel Henrique Barboza 5 hours ago

On 10/22/2026 3:00 AM, Markus Armbruster wrote:
> Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> writes:
> 
>> Maruks reported in [1] a problem with QMP introspection with

Just now noticed the typo :D


Alistair, can you fix it in-tree or should I re-send?  Thanks,

Daniel

>> qemu-system-riscv64 that happens after querying a profile CPU.  QEMU
>> crashes hitting an abort during satp_mode logic that, somehow, is being
>> triggered via profile code.
>>
>> For every profile CPU that goes through init we're setting an 'enabled'
>> flag in the static RISCVProfile object.  This sounded like an okay idea
>> back when profiles were introduced, but now we've realized that QMP will
>> querying CPUs without exiting the QEMU process while also going multiple
>> times through cpu_init() and friends.  The result is that we're in a
>> situation where we have runtime information being stored in static arrays
>> that persists between CPU definitions being introspected.
>>
>> A proper fix is to get rid of profile->enabled and turn profiles into
>> cpu->cfg flags like we do with every other extension.  Unfortunately
>> we've been using profile->enabled for lots of things and a redesign
>> would be in order, one which I'm not comfortable doing right now - we're
>> too close to the QEMU 11.2 code freeze for such a change.
>>
>> For now let's silver tape a fix in cpu_init() to reset profile->enabled
>> for all available profiles.  We'll do a proper redesign in the next
>> release cycle.
>>
>> [1] https://lore.kernel.org/qemu-devel/87ld7rmdi6.fsf@pond.sub.org/
>>
>> Reported-by: Markus Armbruster <armbru@redhat.com>
>> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> 
> That was quick, thank you!
> 
> Tested-by: Markus Armbruster <armbru@redhat.com>
>
Re: [PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection
Posted by Alistair Francis 16 hours ago
On Wed, 2026-10-21 at 14:31 -0300, Daniel Henrique Barboza wrote:
> Maruks reported in [1] a problem with QMP introspection with
> qemu-system-riscv64 that happens after querying a profile CPU.  QEMU
> crashes hitting an abort during satp_mode logic that, somehow, is
> being
> triggered via profile code.
> 
> For every profile CPU that goes through init we're setting an
> 'enabled'
> flag in the static RISCVProfile object.  This sounded like an okay
> idea
> back when profiles were introduced, but now we've realized that QMP
> will
> querying CPUs without exiting the QEMU process while also going
> multiple
> times through cpu_init() and friends.  The result is that we're in a
> situation where we have runtime information being stored in static
> arrays
> that persists between CPU definitions being introspected.
> 
> A proper fix is to get rid of profile->enabled and turn profiles into
> cpu->cfg flags like we do with every other extension.  Unfortunately
> we've been using profile->enabled for lots of things and a redesign
> would be in order, one which I'm not comfortable doing right now -
> we're
> too close to the QEMU 11.2 code freeze for such a change.
> 
> For now let's silver tape a fix in cpu_init() to reset profile-
> >enabled
> for all available profiles.  We'll do a proper redesign in the next
> release cycle.
> 
> [1] https://lore.kernel.org/qemu-devel/87ld7rmdi6.fsf@pond.sub.org/
> 
> Reported-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Daniel Henrique Barboza
> <daniel.barboza@oss.qualcomm.com>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/cpu.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 08a4d14ea1..46b74302db 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1550,6 +1550,25 @@ static void riscv_cpu_init(Object *obj)
>      cpu->env.vext_ver = VEXT_VERSION_1_00_0;
>      cpu->cfg.max_satp_mode = -1;
>  
> +    /*
> +     * The way we're handling profiles does not cope well with QMP
> +     * instropection.  We have a static array that stores
> RISCVCPUProfiles
> +     * objs that hold runtime state for the lifetime of the QEMU
> process.
> +     * Thus setting profile->enabled once, e.g. when instropecting a
> +     * profile CPU, will leave the flag set for subsequent
> intropections.
> +     *
> +     * For now, clear all 'enabled' flags to avoid misleading QMP
> w.r.t
> +     * profiles being set.
> +     *
> +     * FIXME: a better long term solution is to remove profile-
> >enabled
> +     * and just use regular cpu->cfg flags, avoiding static
> variables
> +     * storing dynamic state.  This will help us not only with QMP
> but
> +     * also single-binary support.
> +     */
> +    for (int i = 0; riscv_profiles[i] != NULL; i++) {
> +        riscv_profiles[i]->enabled = false;
> +    }
> +
>      if (mcc->def->profile) {
>          mcc->def->profile->enabled = true;
>      }
Re: [PATCH] target/riscv/cpu.c: duct tape fix for QMP + RV profiles introspection
Posted by Alistair Francis 16 hours ago
On Wed, 2026-10-21 at 14:31 -0300, Daniel Henrique Barboza wrote:
> Maruks reported in [1] a problem with QMP introspection with
> qemu-system-riscv64 that happens after querying a profile CPU.  QEMU
> crashes hitting an abort during satp_mode logic that, somehow, is
> being
> triggered via profile code.
> 
> For every profile CPU that goes through init we're setting an
> 'enabled'
> flag in the static RISCVProfile object.  This sounded like an okay
> idea
> back when profiles were introduced, but now we've realized that QMP
> will
> querying CPUs without exiting the QEMU process while also going
> multiple
> times through cpu_init() and friends.  The result is that we're in a
> situation where we have runtime information being stored in static
> arrays
> that persists between CPU definitions being introspected.
> 
> A proper fix is to get rid of profile->enabled and turn profiles into
> cpu->cfg flags like we do with every other extension.  Unfortunately
> we've been using profile->enabled for lots of things and a redesign
> would be in order, one which I'm not comfortable doing right now -
> we're
> too close to the QEMU 11.2 code freeze for such a change.
> 
> For now let's silver tape a fix in cpu_init() to reset profile-
> >enabled
> for all available profiles.  We'll do a proper redesign in the next
> release cycle.
> 
> [1] https://lore.kernel.org/qemu-devel/87ld7rmdi6.fsf@pond.sub.org/
> 
> Reported-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Daniel Henrique Barboza
> <daniel.barboza@oss.qualcomm.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 08a4d14ea1..46b74302db 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1550,6 +1550,25 @@ static void riscv_cpu_init(Object *obj)
>      cpu->env.vext_ver = VEXT_VERSION_1_00_0;
>      cpu->cfg.max_satp_mode = -1;
>  
> +    /*
> +     * The way we're handling profiles does not cope well with QMP
> +     * instropection.  We have a static array that stores
> RISCVCPUProfiles
> +     * objs that hold runtime state for the lifetime of the QEMU
> process.
> +     * Thus setting profile->enabled once, e.g. when instropecting a
> +     * profile CPU, will leave the flag set for subsequent
> intropections.
> +     *
> +     * For now, clear all 'enabled' flags to avoid misleading QMP
> w.r.t
> +     * profiles being set.
> +     *
> +     * FIXME: a better long term solution is to remove profile-
> >enabled
> +     * and just use regular cpu->cfg flags, avoiding static
> variables
> +     * storing dynamic state.  This will help us not only with QMP
> but
> +     * also single-binary support.
> +     */
> +    for (int i = 0; riscv_profiles[i] != NULL; i++) {
> +        riscv_profiles[i]->enabled = false;
> +    }
> +
>      if (mcc->def->profile) {
>          mcc->def->profile->enabled = true;
>      }