Commit 5315c716 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: svm: set/clear all DR intercepts in one swoop



Unlike other intercepts, debug register intercepts will be modified
in hot paths if the guest OS is bad or otherwise gets tricked into
doing so.

Avoid calling recalc_intercepts 16 times for debug registers.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent d16c293e
Loading
Loading
Loading
Loading
+20 −21
Original line number Diff line number Diff line
@@ -303,20 +303,35 @@ static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit)
	return vmcb->control.intercept_cr & (1U << bit);
}

static inline void set_dr_intercept(struct vcpu_svm *svm, int bit)
static inline void set_dr_intercepts(struct vcpu_svm *svm)
{
	struct vmcb *vmcb = get_host_vmcb(svm);

	vmcb->control.intercept_dr |= (1U << bit);
	vmcb->control.intercept_dr = (1 << INTERCEPT_DR0_READ)
		| (1 << INTERCEPT_DR1_READ)
		| (1 << INTERCEPT_DR2_READ)
		| (1 << INTERCEPT_DR3_READ)
		| (1 << INTERCEPT_DR4_READ)
		| (1 << INTERCEPT_DR5_READ)
		| (1 << INTERCEPT_DR6_READ)
		| (1 << INTERCEPT_DR7_READ)
		| (1 << INTERCEPT_DR0_WRITE)
		| (1 << INTERCEPT_DR1_WRITE)
		| (1 << INTERCEPT_DR2_WRITE)
		| (1 << INTERCEPT_DR3_WRITE)
		| (1 << INTERCEPT_DR4_WRITE)
		| (1 << INTERCEPT_DR5_WRITE)
		| (1 << INTERCEPT_DR6_WRITE)
		| (1 << INTERCEPT_DR7_WRITE);

	recalc_intercepts(svm);
}

static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit)
static inline void clr_dr_intercepts(struct vcpu_svm *svm)
{
	struct vmcb *vmcb = get_host_vmcb(svm);

	vmcb->control.intercept_dr &= ~(1U << bit);
	vmcb->control.intercept_dr = 0;

	recalc_intercepts(svm);
}
@@ -1080,23 +1095,7 @@ static void init_vmcb(struct vcpu_svm *svm)
	set_cr_intercept(svm, INTERCEPT_CR4_WRITE);
	set_cr_intercept(svm, INTERCEPT_CR8_WRITE);

	set_dr_intercept(svm, INTERCEPT_DR0_READ);
	set_dr_intercept(svm, INTERCEPT_DR1_READ);
	set_dr_intercept(svm, INTERCEPT_DR2_READ);
	set_dr_intercept(svm, INTERCEPT_DR3_READ);
	set_dr_intercept(svm, INTERCEPT_DR4_READ);
	set_dr_intercept(svm, INTERCEPT_DR5_READ);
	set_dr_intercept(svm, INTERCEPT_DR6_READ);
	set_dr_intercept(svm, INTERCEPT_DR7_READ);

	set_dr_intercept(svm, INTERCEPT_DR0_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR1_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR2_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR3_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR4_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR5_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR6_WRITE);
	set_dr_intercept(svm, INTERCEPT_DR7_WRITE);
	set_dr_intercepts(svm);

	set_exception_intercept(svm, PF_VECTOR);
	set_exception_intercept(svm, UD_VECTOR);