aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-03-03 07:08:29 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2014-03-11 05:46:04 -0400
commit5315c716b69f47e1751d09e16c7bd5b559419531 (patch)
tree568fbaadc920aa3d7060012ac3bccb7813c53690 /arch/x86
parentd16c293e4ecbddedfc1d64095ce56f0569adc12b (diff)
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: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/svm.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1e8616e304a7..86d802be602d 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -303,20 +303,35 @@ static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit)
303 return vmcb->control.intercept_cr & (1U << bit); 303 return vmcb->control.intercept_cr & (1U << bit);
304} 304}
305 305
306static inline void set_dr_intercept(struct vcpu_svm *svm, int bit) 306static inline void set_dr_intercepts(struct vcpu_svm *svm)
307{ 307{
308 struct vmcb *vmcb = get_host_vmcb(svm); 308 struct vmcb *vmcb = get_host_vmcb(svm);
309 309
310 vmcb->control.intercept_dr |= (1U << bit); 310 vmcb->control.intercept_dr = (1 << INTERCEPT_DR0_READ)
311 | (1 << INTERCEPT_DR1_READ)
312 | (1 << INTERCEPT_DR2_READ)
313 | (1 << INTERCEPT_DR3_READ)
314 | (1 << INTERCEPT_DR4_READ)
315 | (1 << INTERCEPT_DR5_READ)
316 | (1 << INTERCEPT_DR6_READ)
317 | (1 << INTERCEPT_DR7_READ)
318 | (1 << INTERCEPT_DR0_WRITE)
319 | (1 << INTERCEPT_DR1_WRITE)
320 | (1 << INTERCEPT_DR2_WRITE)
321 | (1 << INTERCEPT_DR3_WRITE)
322 | (1 << INTERCEPT_DR4_WRITE)
323 | (1 << INTERCEPT_DR5_WRITE)
324 | (1 << INTERCEPT_DR6_WRITE)
325 | (1 << INTERCEPT_DR7_WRITE);
311 326
312 recalc_intercepts(svm); 327 recalc_intercepts(svm);
313} 328}
314 329
315static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit) 330static inline void clr_dr_intercepts(struct vcpu_svm *svm)
316{ 331{
317 struct vmcb *vmcb = get_host_vmcb(svm); 332 struct vmcb *vmcb = get_host_vmcb(svm);
318 333
319 vmcb->control.intercept_dr &= ~(1U << bit); 334 vmcb->control.intercept_dr = 0;
320 335
321 recalc_intercepts(svm); 336 recalc_intercepts(svm);
322} 337}
@@ -1080,23 +1095,7 @@ static void init_vmcb(struct vcpu_svm *svm)
1080 set_cr_intercept(svm, INTERCEPT_CR4_WRITE); 1095 set_cr_intercept(svm, INTERCEPT_CR4_WRITE);
1081 set_cr_intercept(svm, INTERCEPT_CR8_WRITE); 1096 set_cr_intercept(svm, INTERCEPT_CR8_WRITE);
1082 1097
1083 set_dr_intercept(svm, INTERCEPT_DR0_READ); 1098 set_dr_intercepts(svm);
1084 set_dr_intercept(svm, INTERCEPT_DR1_READ);
1085 set_dr_intercept(svm, INTERCEPT_DR2_READ);
1086 set_dr_intercept(svm, INTERCEPT_DR3_READ);
1087 set_dr_intercept(svm, INTERCEPT_DR4_READ);
1088 set_dr_intercept(svm, INTERCEPT_DR5_READ);
1089 set_dr_intercept(svm, INTERCEPT_DR6_READ);
1090 set_dr_intercept(svm, INTERCEPT_DR7_READ);
1091
1092 set_dr_intercept(svm, INTERCEPT_DR0_WRITE);
1093 set_dr_intercept(svm, INTERCEPT_DR1_WRITE);
1094 set_dr_intercept(svm, INTERCEPT_DR2_WRITE);
1095 set_dr_intercept(svm, INTERCEPT_DR3_WRITE);
1096 set_dr_intercept(svm, INTERCEPT_DR4_WRITE);
1097 set_dr_intercept(svm, INTERCEPT_DR5_WRITE);
1098 set_dr_intercept(svm, INTERCEPT_DR6_WRITE);
1099 set_dr_intercept(svm, INTERCEPT_DR7_WRITE);
1100 1099
1101 set_exception_intercept(svm, PF_VECTOR); 1100 set_exception_intercept(svm, PF_VECTOR);
1102 set_exception_intercept(svm, UD_VECTOR); 1101 set_exception_intercept(svm, UD_VECTOR);