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
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>
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
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
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---
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
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 >
© 2016 - 2026 Red Hat, Inc.