On Thu, 21 Mar 2024 at 09:27, Jinjie Ruan <ruanjin...@huawei.com> wrote: > > > > On 2024/3/20 1:28, Peter Maydell wrote: > > 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> > >> --- > >> v8: > >> - Fix the rcu stall after sending a VNMI in qemu VM. > >> v7: > >> - Add Reviewed-by. > >> v6: > >> - env->cp15.hcr_el2 -> arm_hcr_el2_eff(). > >> - env->cp15.hcrx_el2 -> arm_hcrx_el2_eff(). > >> - Not include VF && VFNMI in CPU_INTERRUPT_VNMI. > >> v4: > >> - Accept NMI unconditionally for arm_cpu_has_work() but add comment. > >> - Change from & to && for EXCP_IRQ or EXCP_FIQ. > >> - Refator nmi mask in arm_excp_unmasked(). > >> - Also handle VNMI in arm_cpu_exec_interrupt() and arm_cpu_set_irq(). > >> - Rename virtual to Virtual. > >> v3: > >> - Not include CPU_INTERRUPT_NMI when FEAT_NMI not enabled > >> - Add ARM_CPU_VNMI. > >> - Refator nmi mask in arm_excp_unmasked(). > >> - Test SCTLR_ELx.NMI for ALLINT mask for NMI. > >> --- > >> target/arm/cpu-qom.h | 4 +- > >> target/arm/cpu.c | 85 +++++++++++++++++++++++++++++++++++++++--- > >> target/arm/cpu.h | 4 ++ > >> target/arm/helper.c | 2 + > >> target/arm/internals.h | 9 +++++ > >> 5 files changed, 97 insertions(+), 7 deletions(-) > >> > >> diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h > >> index 8e032691db..e0c9e18036 100644 > >> --- a/target/arm/cpu-qom.h > >> +++ b/target/arm/cpu-qom.h > >> @@ -36,11 +36,13 @@ DECLARE_CLASS_CHECKERS(AArch64CPUClass, AARCH64_CPU, > >> #define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU > >> #define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX) > >> > >> -/* Meanings of the ARMCPU object's four inbound GPIO lines */ > >> +/* Meanings of the ARMCPU object's six inbound GPIO lines */ > >> #define ARM_CPU_IRQ 0 > >> #define ARM_CPU_FIQ 1 > >> #define ARM_CPU_VIRQ 2 > >> #define ARM_CPU_VFIQ 3 > >> +#define ARM_CPU_NMI 4 > >> +#define ARM_CPU_VNMI 5 > >> > >> /* For M profile, some registers are banked secure vs non-secure; > >> * these are represented as a 2-element array where the first element > > > >> @@ -678,13 +687,31 @@ static inline bool arm_excp_unmasked(CPUState *cs, > >> unsigned int excp_idx, > >> return false; > >> } > >> > >> + if (cpu_isar_feature(aa64_nmi, env_archcpu(env)) && > >> + env->cp15.sctlr_el[target_el] & SCTLR_NMI && cur_el == target_el) > >> { > >> + allIntMask = env->pstate & PSTATE_ALLINT || > >> + ((env->cp15.sctlr_el[target_el] & SCTLR_SPINTMASK) && > >> + (env->pstate & PSTATE_SP)); > >> + } > >> + > >> switch (excp_idx) { > >> + case EXCP_NMI: > >> + pstate_unmasked = !allIntMask; > >> + break; > >> + > >> + case EXCP_VNMI: > >> + if ((!(hcr_el2 & HCR_IMO) && !(hcr_el2 & HCR_FMO)) || > >> + (hcr_el2 & HCR_TGE)) { > >> + /* VNMIs(VIRQs or VFIQs) are only taken when hypervized. */ > >> + return false; > >> + } > > > > VINMI and VFNMI aren't the same thing: do we definitely want to > > merge them into one EXCP_VNMI ? It feels like it would be simpler > > to keep them separate. Similarly CPU_INTERRUPT_VNMI, and > > arm_cpu_update_vnmi() probably want VINMI and VFNMI versions. > > It's not like that. The VFNMI cannot be reported from the GIC, there > will be no opportunity to call arm_cpu_update_vfnmi().
The GIC can't trigger it, but the hypervisor can by setting the HCRX_EL2.VFNMI bit. So writes to HCRX_EL2 (and HCR_EL2) would need to call arm_cpu_update_vfnmi(). -- PMM