KVM: svm: set/clear all DR intercepts in one swoop
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 3 Mar 2014 12:08:29 +0000 (13:08 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 11 Mar 2014 09:46:04 +0000 (10:46 +0100)
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: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm.c

index 1e8616e304a7416594c344c7d329ef537c83b2c0..86d802be602d33b583cb047462d2f64111ed0b0f 100644 (file)
@@ -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);