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

KVM: arm64: nv: Honor MDCR_EL2.TDE routing for debug exceptions



Inject debug exceptions into vEL2 if MDCR_EL2.TDE is set.

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-17-oliver.upton@linux.dev


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 2ca3f03b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
}

extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
extern bool forward_debug_exception(struct kvm_vcpu *vcpu);
extern void kvm_init_nested(struct kvm *kvm);
extern int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu);
extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
+19 −4
Original line number Diff line number Diff line
@@ -2345,14 +2345,14 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
	return true;
}

static bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
static bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg, u64 control_bit)
{
	bool control_bit_set;

	if (!vcpu_has_nv(vcpu))
		return false;

	control_bit_set = __vcpu_sys_reg(vcpu, HCR_EL2) & control_bit;
	control_bit_set = __vcpu_sys_reg(vcpu, reg) & control_bit;
	if (!is_hyp_ctxt(vcpu) && control_bit_set) {
		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
		return true;
@@ -2360,9 +2360,24 @@ static bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
	return false;
}

static bool forward_hcr_traps(struct kvm_vcpu *vcpu, u64 control_bit)
{
	return __forward_traps(vcpu, HCR_EL2, control_bit);
}

bool forward_smc_trap(struct kvm_vcpu *vcpu)
{
	return forward_traps(vcpu, HCR_TSC);
	return forward_hcr_traps(vcpu, HCR_TSC);
}

static bool forward_mdcr_traps(struct kvm_vcpu *vcpu, u64 control_bit)
{
	return __forward_traps(vcpu, MDCR_EL2, control_bit);
}

bool forward_debug_exception(struct kvm_vcpu *vcpu)
{
	return forward_mdcr_traps(vcpu, MDCR_EL2_TDE);
}

static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
@@ -2406,7 +2421,7 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
	 * Forward this trap to the virtual EL2 if the virtual
	 * HCR_EL2.NV bit is set and this is coming from !EL2.
	 */
	if (forward_traps(vcpu, HCR_NV))
	if (forward_hcr_traps(vcpu, HCR_NV))
		return;

	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
+3 −0
Original line number Diff line number Diff line
@@ -183,6 +183,9 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
	struct kvm_run *run = vcpu->run;
	u64 esr = kvm_vcpu_get_esr(vcpu);

	if (!vcpu->guest_debug && forward_debug_exception(vcpu))
		return 1;

	run->exit_reason = KVM_EXIT_DEBUG;
	run->debug.arch.hsr = lower_32_bits(esr);
	run->debug.arch.hsr_high = upper_32_bits(esr);