direct-io.hg
changeset 10485:81bfa15a071e
[HVM][VMX] Added dr restore if breakpoints are enabled in guest dr7.
Signed-off-by: George Dunlap <dunlapg@umich.edu>
Signed-off-by: Nitin Kamble <nitin.a.kamble@intel.com>
Signed-off-by: George Dunlap <dunlapg@umich.edu>
Signed-off-by: Nitin Kamble <nitin.a.kamble@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Tue Jun 27 09:48:23 2006 +0100 (2006-06-27) |
parents | 4105520841b3 |
children | 5610d916ad1b |
files | xen/arch/x86/hvm/vmx/vmx.c |
line diff
1.1 --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 27 09:41:09 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 27 09:48:23 2006 +0100 1.3 @@ -337,6 +337,7 @@ static void vmx_restore_msrs(struct vcpu 1.4 clear_bit(i, &guest_flags); 1.5 } 1.6 } 1.7 + 1.8 #else /* __i386__ */ 1.9 1.10 #define vmx_save_segments(v) ((void)0) 1.11 @@ -356,6 +357,43 @@ static inline int long_mode_do_msr_write 1.12 1.13 #endif /* __i386__ */ 1.14 1.15 +#define loaddebug(_v,_reg) \ 1.16 + __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg])) 1.17 + 1.18 +static inline void __restore_debug_registers(struct vcpu *v) 1.19 +{ 1.20 + loaddebug(&v->arch.guest_context, 0); 1.21 + loaddebug(&v->arch.guest_context, 1); 1.22 + loaddebug(&v->arch.guest_context, 2); 1.23 + loaddebug(&v->arch.guest_context, 3); 1.24 + /* No 4 and 5 */ 1.25 + loaddebug(&v->arch.guest_context, 6); 1.26 + /* DR7 is loaded from the vmcs. */ 1.27 +} 1.28 + 1.29 +/* 1.30 + * DR7 is saved and restored on every vmexit. Other debug registers only 1.31 + * need to be restored if their value is going to affect execution -- i.e., 1.32 + * if one of the breakpoints is enabled. So mask out all bits that don't 1.33 + * enable some breakpoint functionality. 1.34 + * 1.35 + * This is in part necessary because bit 10 of DR7 is hardwired to 1, so a 1.36 + * simple if( guest_dr7 ) will always return true. As long as we're masking, 1.37 + * we might as well do it right. 1.38 + */ 1.39 +#define DR7_ACTIVE_MASK 0xff 1.40 + 1.41 +static inline void vmx_restore_dr(struct vcpu *v) 1.42 +{ 1.43 + unsigned long guest_dr7; 1.44 + 1.45 + __vmread(GUEST_DR7, &guest_dr7); 1.46 + 1.47 + /* Assumes guest does not have DR access at time of context switch. */ 1.48 + if ( unlikely(guest_dr7 & DR7_ACTIVE_MASK) ) 1.49 + __restore_debug_registers(v); 1.50 +} 1.51 + 1.52 static void vmx_freeze_time(struct vcpu *v) 1.53 { 1.54 struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; 1.55 @@ -376,6 +414,7 @@ static void vmx_ctxt_switch_from(struct 1.56 static void vmx_ctxt_switch_to(struct vcpu *v) 1.57 { 1.58 vmx_restore_msrs(v); 1.59 + vmx_restore_dr(v); 1.60 } 1.61 1.62 void stop_vmx(void)