On Mon, 18 Mar 2024 at 09:37, Jinjie Ruan <ruanjin...@huawei.com> wrote: > > This only implements the external delivery method via the GICv3. > > Signed-off-by: Jinjie Ruan <ruanjin...@huawei.com> > Reviewed-by: Richard Henderson <richard.hender...@linaro.org>
> @@ -692,13 +719,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, > unsigned int excp_idx, > /* VFIQs are only taken when hypervized. */ > return false; > } > - return !(env->daif & PSTATE_F); > + return !(env->daif & PSTATE_F) && (!allIntMask); > case EXCP_VIRQ: > if (!(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) { > /* VIRQs are only taken when hypervized. */ > return false; > } > - return !(env->daif & PSTATE_I); > + return !(env->daif & PSTATE_I) && (!allIntMask); > case EXCP_VSERR: > if (!(hcr_el2 & HCR_AMO) || (hcr_el2 & HCR_TGE)) { > /* VIRQs are only taken when hypervized. */ > @@ -804,6 +831,24 @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int > interrupt_request) > > /* The prioritization of interrupts is IMPLEMENTATION DEFINED. */ > > + if (cpu_isar_feature(aa64_nmi, env_archcpu(env))) { > + if (interrupt_request & CPU_INTERRUPT_NMI) { > + excp_idx = EXCP_NMI; > + target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, > secure); > + if (arm_excp_unmasked(cs, excp_idx, target_el, > + cur_el, secure, hcr_el2)) { > + goto found; > + } > + } > + if (interrupt_request & CPU_INTERRUPT_VNMI) { > + excp_idx = EXCP_VNMI; > + target_el = 1; > + if (arm_excp_unmasked(cs, excp_idx, target_el, > + cur_el, secure, hcr_el2)) { > + goto found; > + } > + } > + } > if (interrupt_request & CPU_INTERRUPT_FIQ) { > excp_idx = EXCP_FIQ; > target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); This part adds handling for taking IRQNMI and VIRQNMI, but not VFIQNMI. So because at the moment we merge VFIQNMI and VFIQ they both come out as interrupt_request having CPU_INTERRUPT_VFIQ set. But we don't handle that in this function or in arm_excp_unmasked(), so we treat it exactly the same as VFIQ, which means that if PSTATE.F is 1 then we will incorrectly fail to take the VFIQNMI. I think the code is going to be a lot more straightforward if we keep all of these things separate. Compare how we handle VSError, which is also (for QEMU) something where only the virtual version exists and which is only triggered via the HCR bits. thanks -- PMM