[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