[PATCH 2/2] target/arm: ensure PSCI register updates are flushed

Alex Bennée posted 2 patches 2 months ago
Maintainers: Alexander Graf <agraf@csgraf.de>, Mads Ynddal <mads@ynddal.dk>, Peter Maydell <peter.maydell@linaro.org>
[PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Alex Bennée 2 months ago
When we handle a host call we report state back to the caller via
registers. Set vcpu_dirty to indicate QEMU is currently the reference
and hoist the flush_cpu_state() and make the call unconditional.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 target/arm/hvf/hvf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 70d34063df8..8e2940217a6 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1942,6 +1942,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
                 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
                 env->xregs[0] = -1;
             }
+            cpu->vcpu_dirty = true;
         } else {
             trace_hvf_unknown_hvc(env->pc, env->xregs[0]);
             hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
@@ -1958,6 +1959,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
                 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
                 env->xregs[0] = -1;
             }
+            cpu->vcpu_dirty = true;
         } else {
             trace_hvf_unknown_smc(env->xregs[0]);
             hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
@@ -1980,10 +1982,12 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
         error_report("0x%llx: unhandled exception ec=0x%x", env->pc, ec);
     }
 
+    /* flush any changed cpu state back to HVF */
+    flush_cpu_state(cpu);
+
     if (advance_pc) {
         uint64_t pc;
 
-        flush_cpu_state(cpu);
 
         r = hv_vcpu_get_reg(cpu->accel->fd, HV_REG_PC, &pc);
         assert_hvf_ok(r);
-- 
2.47.3


Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Philippe Mathieu-Daudé 2 months ago
On 5/12/25 16:11, Alex Bennée wrote:
> When we handle a host call we report state back to the caller via
> registers. Set vcpu_dirty to indicate QEMU is currently the reference
> and hoist the flush_cpu_state() and make the call unconditional.
> 
> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>   target/arm/hvf/hvf.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Zenghui Yu 2 months ago
Hi Alex,

On 2025/12/5 23:11, Alex Bennée wrote:
> When we handle a host call we report state back to the caller via
> registers. Set vcpu_dirty to indicate QEMU is currently the reference
> and hoist the flush_cpu_state() and make the call unconditional.
> 
> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

This fixes the guest boot issue.

However I notice that some (all?) HMP commands (e.g., "info registers")
don't return and result in guest hang. Haven't dig further though.

Thanks,
Zenghui

Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Alex Bennée 2 months ago
Zenghui Yu <zenghui.yu@linux.dev> writes:

> Hi Alex,
>
> On 2025/12/5 23:11, Alex Bennée wrote:
>> When we handle a host call we report state back to the caller via
>> registers. Set vcpu_dirty to indicate QEMU is currently the reference
>> and hoist the flush_cpu_state() and make the call unconditional.
>> 
>> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> This fixes the guest boot issue.
>
> However I notice that some (all?) HMP commands (e.g., "info registers")
> don't return and result in guest hang. Haven't dig further though.

Does this fix it:

--8<---------------cut here---------------start------------->8---
target/arm: make HV_EXIT_REASON_CANCELED leave main loop

Without this we can spin tightly in the main HVF dispatch loop and
never release the lock long enough.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

1 file changed, 1 insertion(+)
 target/arm/hvf/hvf.c | 1 +

modified    target/arm/hvf/hvf.c
@@ -2020,6 +2020,7 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
         break;
     case HV_EXIT_REASON_CANCELED:
         /* we got kicked, no exit to process */
+        ret = -1;
         break;
     default:
         g_assert_not_reached();
--8<---------------cut here---------------end--------------->8---

>
> Thanks,
> Zenghui

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro
Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Philippe Mathieu-Daudé 2 months ago
On 8/12/25 18:08, Alex Bennée wrote:

> --8<---------------cut here---------------start------------->8---
> target/arm: make HV_EXIT_REASON_CANCELED leave main loop
> 
> Without this we can spin tightly in the main HVF dispatch loop and
> never release the lock long enough.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

> 
> 1 file changed, 1 insertion(+)
>  target/arm/hvf/hvf.c | 1 +
> 
> modified    target/arm/hvf/hvf.c
> @@ -2020,6 +2020,7 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
>           break;
>       case HV_EXIT_REASON_CANCELED:
>           /* we got kicked, no exit to process */
> +        ret = -1;
>           break;
>       default:
>           g_assert_not_reached();
> --8<---------------cut here---------------end--------------->8---


Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by Zenghui Yu 2 months ago
On 2025/12/9 01:08, Alex Bennée wrote:
> Zenghui Yu <zenghui.yu@linux.dev> writes:
> 
> > Hi Alex,
> >
> > On 2025/12/5 23:11, Alex Bennée wrote:
> > > When we handle a host call we report state back to the caller via
> > > registers. Set vcpu_dirty to indicate QEMU is currently the reference
> > > and hoist the flush_cpu_state() and make the call unconditional.
> > >
> > > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
> > > Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> >
> > This fixes the guest boot issue.
> >
> > However I notice that some (all?) HMP commands (e.g., "info registers")
> > don't return and result in guest hang. Haven't dig further though.
> 
> Does this fix it:
> 
> --8<---------------cut here---------------start------------->8---
> target/arm: make HV_EXIT_REASON_CANCELED leave main loop
> 
> Without this we can spin tightly in the main HVF dispatch loop and
> never release the lock long enough.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> 
> 1 file changed, 1 insertion(+)
>  target/arm/hvf/hvf.c | 1 +
> 
> modified    target/arm/hvf/hvf.c
> @@ -2020,6 +2020,7 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
>          break;
>      case HV_EXIT_REASON_CANCELED:
>          /* we got kicked, no exit to process */
> +        ret = -1;
>          break;
>      default:
>          g_assert_not_reached();
> --8<---------------cut here---------------end--------------->8---

Yes it works. Please feel free to add

Tested-by: Zenghui Yu <zenghui.yu@linux.dev>

on it and patch #2. Thanks for the fixes!

Zenghui

Re: [PATCH 2/2] target/arm: ensure PSCI register updates are flushed
Posted by osy 2 months ago
Tested-by: Joelle van Dyne <j@getutm.app>

(With HV_EXIT_REASON_CANCELED change, otherwise it hangs on shutdown)

On Mon, Dec 8, 2025 at 4:56 PM Zenghui Yu <zenghui.yu@linux.dev> wrote:
>
> On 2025/12/9 01:08, Alex Bennée wrote:
> > Zenghui Yu <zenghui.yu@linux.dev> writes:
> >
> > > Hi Alex,
> > >
> > > On 2025/12/5 23:11, Alex Bennée wrote:
> > > > When we handle a host call we report state back to the caller via
> > > > registers. Set vcpu_dirty to indicate QEMU is currently the reference
> > > > and hoist the flush_cpu_state() and make the call unconditional.
> > > >
> > > > Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3228
> > > > Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> > >
> > > This fixes the guest boot issue.
> > >
> > > However I notice that some (all?) HMP commands (e.g., "info registers")
> > > don't return and result in guest hang. Haven't dig further though.
> >
> > Does this fix it:
> >
> > --8<---------------cut here---------------start------------->8---
> > target/arm: make HV_EXIT_REASON_CANCELED leave main loop
> >
> > Without this we can spin tightly in the main HVF dispatch loop and
> > never release the lock long enough.
> >
> > Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> >
> > 1 file changed, 1 insertion(+)
> >  target/arm/hvf/hvf.c | 1 +
> >
> > modified    target/arm/hvf/hvf.c
> > @@ -2020,6 +2020,7 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
> >          break;
> >      case HV_EXIT_REASON_CANCELED:
> >          /* we got kicked, no exit to process */
> > +        ret = -1;
> >          break;
> >      default:
> >          g_assert_not_reached();
> > --8<---------------cut here---------------end--------------->8---
>
> Yes it works. Please feel free to add
>
> Tested-by: Zenghui Yu <zenghui.yu@linux.dev>
>
> on it and patch #2. Thanks for the fixes!
>
> Zenghui
>