Commit 06d22a9c authored by Oliver Upton's avatar Oliver Upton Committed by Marc Zyngier
Browse files

KVM: arm64: Reload vCPU for accesses to OSLAR_EL1



KVM takes ownership of the debug regs if the guest enables the OS lock,
as it needs to use MDSCR_EL1 to mask debug exceptions. Just reload the
vCPU if the guest toggles the OS lock, relying on kvm_vcpu_load_debug()
to update the debug owner and get the right trap configuration in place.

Tested-by: default avatarJames Clark <james.clark@linaro.org>
Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20241219224116.3941496-13-oliver.upton@linux.dev


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent beb470d9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1346,6 +1346,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu);
void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu);
void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val);

#define kvm_vcpu_os_lock_enabled(vcpu)		\
	(!!(__vcpu_sys_reg(vcpu, OSLSR_EL1) & OSLSR_EL1_OSLK))
+13 −0
Original line number Diff line number Diff line
@@ -288,3 +288,16 @@ void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu)

	vcpu->arch.debug_owner = VCPU_DEBUG_GUEST_OWNED;
}

void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val)
{
	if (val & OSLAR_EL1_OSLK)
		__vcpu_sys_reg(vcpu, OSLSR_EL1) |= OSLSR_EL1_OSLK;
	else
		__vcpu_sys_reg(vcpu, OSLSR_EL1) &= ~OSLSR_EL1_OSLK;

	preempt_disable();
	kvm_arch_vcpu_put(vcpu);
	kvm_arch_vcpu_load(vcpu, smp_processor_id());
	preempt_enable();
}
+1 −8
Original line number Diff line number Diff line
@@ -570,17 +570,10 @@ static bool trap_oslar_el1(struct kvm_vcpu *vcpu,
			   struct sys_reg_params *p,
			   const struct sys_reg_desc *r)
{
	u64 oslsr;

	if (!p->is_write)
		return read_from_write_only(vcpu, p, r);

	/* Forward the OSLK bit to OSLSR */
	oslsr = __vcpu_sys_reg(vcpu, OSLSR_EL1) & ~OSLSR_EL1_OSLK;
	if (p->regval & OSLAR_EL1_OSLK)
		oslsr |= OSLSR_EL1_OSLK;

	__vcpu_sys_reg(vcpu, OSLSR_EL1) = oslsr;
	kvm_debug_handle_oslar(vcpu, p->regval);
	return true;
}