Message ID | 20231218113305.2511480-8-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: Implement emulation of nested virtualization | expand |
On 12/18/23 22:32, Peter Maydell wrote: > The HCR_EL2.TSC trap for trapping EL1 execution of SMC instructions > has a behaviour change for FEAT_NV when EL3 is not implemented: > > * in older architecture versions TSC was required to have no > effect (i.e. the SMC insn UNDEFs) > * with FEAT_NV, when HCR_EL2.NV == 1 the trap must apply > (i.e. SMC traps to EL2, as it already does in all cases when > EL3 is implemented) > * in newer architecture versions, the behaviour either without > FEAT_NV or with FEAT_NV and HCR_EL2.NV == 0 is relaxed to > an IMPDEF choice between UNDEF and trap-to-EL2 (i.e. it is > permitted to always honour HCR_EL2.TSC) for AArch64 only > > Add the condition to honour the trap bit when HCR_EL2.NV == 1. We > leave the HCR_EL2.NV == 0 case with the existing (UNDEF) behaviour, > as our IMPDEF choice (both because it avoids a behaviour change > for older CPU models and because we'd have to distinguish AArch32 > from AArch64 if we opted to trap to EL2). > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > target/arm/tcg/op_helper.c | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index ea08936a852..ae158200c00 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -930,7 +930,14 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) * * Conduit SMC, valid call Trap to EL2 PSCI Call * Conduit SMC, inval call Trap to EL2 Undef insn - * Conduit not SMC Undef insn Undef insn + * Conduit not SMC Undef or trap[1] Undef insn + * + * [1] In this case: + * - if HCR_EL2.NV == 1 we must trap to EL2 + * - if HCR_EL2.NV == 0 then newer architecture revisions permit + * AArch64 (but not AArch32) to trap to EL2 as an IMPDEF choice + * - otherwise we must UNDEF + * We take the IMPDEF choice to always UNDEF if HCR_EL2.NV == 0. */ /* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state. @@ -944,9 +951,12 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) : smd_flag && !secure; if (!arm_feature(env, ARM_FEATURE_EL3) && + !(arm_hcr_el2_eff(env) & HCR_NV) && cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) { - /* If we have no EL3 then SMC always UNDEFs and can't be - * trapped to EL2. PSCI-via-SMC is a sort of ersatz EL3 + /* + * If we have no EL3 then traditionally SMC always UNDEFs and can't be + * trapped to EL2. For nested virtualization, SMC can be trapped to + * the outer hypervisor. PSCI-via-SMC is a sort of ersatz EL3 * firmware within QEMU, and we want an EL2 guest to be able * to forbid its EL1 from making PSCI calls into QEMU's * "firmware" via HCR.TSC, so for these purposes treat
The HCR_EL2.TSC trap for trapping EL1 execution of SMC instructions has a behaviour change for FEAT_NV when EL3 is not implemented: * in older architecture versions TSC was required to have no effect (i.e. the SMC insn UNDEFs) * with FEAT_NV, when HCR_EL2.NV == 1 the trap must apply (i.e. SMC traps to EL2, as it already does in all cases when EL3 is implemented) * in newer architecture versions, the behaviour either without FEAT_NV or with FEAT_NV and HCR_EL2.NV == 0 is relaxed to an IMPDEF choice between UNDEF and trap-to-EL2 (i.e. it is permitted to always honour HCR_EL2.TSC) for AArch64 only Add the condition to honour the trap bit when HCR_EL2.NV == 1. We leave the HCR_EL2.NV == 0 case with the existing (UNDEF) behaviour, as our IMPDEF choice (both because it avoids a behaviour change for older CPU models and because we'd have to distinguish AArch32 from AArch64 if we opted to trap to EL2). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/tcg/op_helper.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)