From c22e943ea195c121246de4301b65f9564248f40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 9 Dec 2025 09:24:56 +0000 Subject: [PATCH 1/4] Revert "target/arm: Re-use arm_is_psci_call() in HVF" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This breaks a pure HVF (--disable-tcg) build because the fallback stub will always report false. This reverts commit 4695daacc068cd0aa9a91c0063c4f2a9ec9b7ba1. Reviewed-by: Philippe Mathieu-Daudé Tested-by: Christian Stussak Message-ID: <20251209092459.1058313-2-alex.bennee@linaro.org> Signed-off-by: Alex Bennée --- target/arm/hvf/hvf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index de1e8fb8a0..70d34063df 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1935,7 +1935,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp) break; case EC_AA64_HVC: cpu_synchronize_state(cpu); - if (arm_is_psci_call(arm_cpu, EXCP_HVC)) { + if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_HVC) { /* Do NOT advance $pc for HVC */ if (!hvf_handle_psci_call(cpu)) { trace_hvf_unknown_hvc(env->pc, env->xregs[0]); @@ -1949,7 +1949,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp) break; case EC_AA64_SMC: cpu_synchronize_state(cpu); - if (arm_is_psci_call(arm_cpu, EXCP_SMC)) { + if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_SMC) { /* Secure Monitor Call exception, we need to advance $pc */ advance_pc = true; From 2a425aae0b5c9ab162cb9cc9bb8064f5e909bdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 9 Dec 2025 09:24:57 +0000 Subject: [PATCH 2/4] target/arm: ensure PSCI register updates are flushed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3228 Tested-by: Christian Stussak Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251209092459.1058313-3-alex.bennee@linaro.org> Signed-off-by: Alex Bennée --- 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 70d34063df..8e2940217a 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); From d10019372467edac05b783deff7fa9ef830545d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 9 Dec 2025 09:24:58 +0000 Subject: [PATCH 3/4] target/arm: make HV_EXIT_REASON_CANCELED leave hvf_arch_vcpu_exec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this we can spin tightly in the main HVF dispatch loop and never release the lock long enough. As a result the HMP never gets to run and shutting down the system deadlocks. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3228 Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251209092459.1058313-4-alex.bennee@linaro.org> Signed-off-by: Alex Bennée --- target/arm/hvf/hvf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 8e2940217a..8288b60529 100644 --- a/target/arm/hvf/hvf.c +++ b/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(); From dd77ef99aa0280c467fe8442b4238122899ae6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 9 Dec 2025 09:24:59 +0000 Subject: [PATCH 4/4] target/arm: handle unaligned PC during tlb probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PC alignment faults have priority over instruction aborts and we have code to deal with this in the translation front-ends. However during tb_lookup we can see a potentially faulting probe which doesn't get a MemOp set. If the page isn't available this results in EC_INSNABORT (0x20) instead of EC_PCALIGNMENT (0x22). As there is no easy way to set the appropriate MemOp in the instruction fetch probe path lets just detect it in arm_cpu_tlb_fill_align() ahead of the main alignment check. We also teach arm_deliver_fault to deliver the right syndrome for MMU_INST_FETCH alignment issues. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3233 Tested-by: Jessica Clarke Reviewed-by: Richard Henderson Message-ID: <20251209092459.1058313-5-alex.bennee@linaro.org> Signed-off-by: Alex Bennée --- target/arm/tcg/tlb_helper.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index f1983a5732..5c689d3b69 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -250,7 +250,11 @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr, fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc); if (access_type == MMU_INST_FETCH) { - syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc); + if (fi->type == ARMFault_Alignment) { + syn = syn_pcalignment(); + } else { + syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc); + } exc = EXCP_PREFETCH_ABORT; } else { bool gcs = regime_is_gcs(core_to_arm_mmu_idx(env, mmu_idx)); @@ -346,11 +350,18 @@ bool arm_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, vaddr address, } /* - * Per R_XCHFJ, alignment fault not due to memory type has - * highest precedence. Otherwise, walk the page table and - * and collect the page description. + * PC alignment faults should be dealt with at translation time + * but we also need to catch them while being probed. + * + * Then per R_XCHFJ, alignment fault not due to memory type take + * precedence. Otherwise, walk the page table and and collect the + * page description. + * */ - if (address & ((1 << memop_alignment_bits(memop)) - 1)) { + if (access_type == MMU_INST_FETCH && !cpu->env.thumb && + (address & 3)) { + fi->type = ARMFault_Alignment; + } else if (address & ((1 << memop_alignment_bits(memop)) - 1)) { fi->type = ARMFault_Alignment; } else if (!get_phys_addr(&cpu->env, address, access_type, memop, core_to_arm_mmu_idx(&cpu->env, mmu_idx),