[PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
Marc Zyngier
maz at kernel.org
Thu Jan 27 03:08:17 PST 2022
On Thu, 20 Jan 2022 13:58:02 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
>
> Hi Marc,
>
> On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> > +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> > +{
> > + u64 spsr, elr, mode;
> > + bool direct_eret;
> > +
> > + /*
> > + * Going through the whole put/load motions is a waste of time
> > + * if this is a VHE guest hypervisor returning to its own
> > + * userspace, or the hypervisor performing a local exception
> > + * return. No need to save/restore registers, no need to
> > + * switch S2 MMU. Just do the canonical ERET.
> > + */
> > + spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> > + mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> > +
> > + direct_eret = (mode == PSR_MODE_EL0t &&
> > + vcpu_el2_e2h_is_set(vcpu) &&
> > + vcpu_el2_tge_is_set(vcpu));
> > + direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> > +
> > + if (direct_eret) {
> > + *vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
> > + *vcpu_cpsr(vcpu) = spsr;
> > + trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
> > + return;
> > + }
> > +
> > + preempt_disable();
> > + kvm_arch_vcpu_put(vcpu);
> > +
> > + elr = __vcpu_sys_reg(vcpu, ELR_EL2);
> > +
> > + trace_kvm_nested_eret(vcpu, elr, spsr);
> > +
> > + /*
> > + * Note that the current exception level is always the virtual EL2,
> > + * since we set HCR_EL2.NV bit only when entering the virtual EL2.
> > + */
> > + *vcpu_pc(vcpu) = elr;
> > + *vcpu_cpsr(vcpu) = spsr;
> > +
> > + kvm_arch_vcpu_load(vcpu, smp_processor_id());
> > + preempt_enable();
>
> According to ARM DDI 0487G.a, page D13-3289, ERET'ing to EL1 when
> HCR_EL2.TGE is set is an illegal exception return. I don't see this
> case treated here.
Yes, good call.
I've now added handling for both the return to EL1 with TGE set as
well as return to a 32bit mode. The return to EL3 case will directly
be handled by the HW, and the return from AArch32 to AArch64 cannot
happen by construction.
Thanks for spotting it.
M.
--
Without deviation from the norm, progress is not possible.
More information about the linux-arm-kernel
mailing list