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>
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)