ia64/xen-unstable

changeset 16620:966a6d3b7408

SVM: Treat the vlapic's tpr as the master copy and sync the vtpr to it
before every vm entry. This fixes HVM save/restore/migrate, as the
vtpr value was only being synced on guest TPR writes before.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Dec 14 11:50:24 2007 +0000 (2007-12-14)
parents cb0ce96c02de
children a7ede5cb628a
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Dec 14 11:39:02 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Dec 14 11:50:24 2007 +0000
     1.3 @@ -1405,6 +1405,25 @@ void hvm_cpuid(unsigned int input, unsig
     1.4      }
     1.5  }
     1.6  
     1.7 +enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
     1.8 +{
     1.9 +    enum hvm_intblk r;
    1.10 +    ASSERT(v == current);
    1.11 +
    1.12 +    r = hvm_funcs.interrupt_blocked(v, intack);
    1.13 +    if ( r != hvm_intblk_none )
    1.14 +        return r;
    1.15 +
    1.16 +    if ( intack.source == hvm_intsrc_lapic )
    1.17 +    {
    1.18 +        uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
    1.19 +        if ( (tpr >> 4) >= (intack.vector >> 4) )
    1.20 +            return hvm_intblk_tpr;
    1.21 +    }
    1.22 +
    1.23 +    return r;
    1.24 +}
    1.25 +
    1.26  static long hvm_grant_table_op(
    1.27      unsigned int cmd, XEN_GUEST_HANDLE(void) uop, unsigned int count)
    1.28  {
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Dec 14 11:39:02 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Dec 14 11:50:24 2007 +0000
     2.3 @@ -443,10 +443,6 @@ static enum hvm_intblk svm_interrupt_blo
     2.4      if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
     2.5          return hvm_intblk_rflags_ie;
     2.6  
     2.7 -    if ( (intack.source == hvm_intsrc_lapic) &&
     2.8 -         ((vmcb->vintr.fields.tpr & 0xf) >= (intack.vector >> 4)) )
     2.9 -        return hvm_intblk_tpr;
    2.10 -
    2.11      return hvm_intblk_none;
    2.12  }
    2.13  
    2.14 @@ -522,13 +518,6 @@ static void svm_flush_guest_tlbs(void)
    2.15      svm_asid_inc_generation();
    2.16  }
    2.17  
    2.18 -static void svm_update_vtpr(struct vcpu *v, unsigned long value)
    2.19 -{
    2.20 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    2.21 -
    2.22 -    vmcb->vintr.fields.tpr = value & 0x0f;
    2.23 -}
    2.24 -
    2.25  static void svm_sync_vmcb(struct vcpu *v)
    2.26  {
    2.27      struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
    2.28 @@ -788,6 +777,10 @@ static void svm_do_resume(struct vcpu *v
    2.29          svm_asid_init_vcpu(v);
    2.30      }
    2.31  
    2.32 +    /* Reflect the vlapic's TPR in the hardware vtpr */
    2.33 +    v->arch.hvm_svm.vmcb->vintr.fields.tpr = 
    2.34 +        (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
    2.35 +
    2.36      hvm_do_resume(v);
    2.37      reset_stack_and_jump(svm_asm_do_resume);
    2.38  }
    2.39 @@ -885,7 +878,6 @@ static struct hvm_function_table svm_fun
    2.40      .update_guest_cr      = svm_update_guest_cr,
    2.41      .update_guest_efer    = svm_update_guest_efer,
    2.42      .flush_guest_tlbs     = svm_flush_guest_tlbs,
    2.43 -    .update_vtpr          = svm_update_vtpr,
    2.44      .stts                 = svm_stts,
    2.45      .set_tsc_offset       = svm_set_tsc_offset,
    2.46      .inject_exception     = svm_inject_exception,
    2.47 @@ -2212,6 +2204,10 @@ asmlinkage void svm_vmexit_handler(struc
    2.48          domain_crash(v->domain);
    2.49          break;
    2.50      }
    2.51 +
    2.52 +    /* The exit may have updated the TPR: reflect this in the hardware vtpr */
    2.53 +    vmcb->vintr.fields.tpr = 
    2.54 +        (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
    2.55  }
    2.56  
    2.57  asmlinkage void svm_trace_vmentry(void)
     3.1 --- a/xen/arch/x86/hvm/vlapic.c	Fri Dec 14 11:39:02 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/vlapic.c	Fri Dec 14 11:50:24 2007 +0000
     3.3 @@ -580,7 +580,6 @@ static void vlapic_write(struct vcpu *v,
     3.4      {
     3.5      case APIC_TASKPRI:
     3.6          vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
     3.7 -        hvm_update_vtpr(v, (val >> 4) & 0x0f);
     3.8          break;
     3.9  
    3.10      case APIC_EOI:
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 14 11:39:02 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 14 11:50:24 2007 +0000
     4.3 @@ -1011,13 +1011,6 @@ static enum hvm_intblk vmx_interrupt_blo
     4.4      if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
     4.5          return hvm_intblk_rflags_ie;
     4.6  
     4.7 -    if ( intack.source == hvm_intsrc_lapic )
     4.8 -    {
     4.9 -        uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
    4.10 -        if ( (tpr >> 4) >= (intack.vector >> 4) )
    4.11 -            return hvm_intblk_tpr;
    4.12 -    }
    4.13 -
    4.14      return hvm_intblk_none;
    4.15  }
    4.16  
    4.17 @@ -1120,11 +1113,6 @@ static void vmx_inject_exception(
    4.18      }
    4.19  }
    4.20  
    4.21 -static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
    4.22 -{
    4.23 -    /* VMX doesn't have a V_TPR field */
    4.24 -}
    4.25 -
    4.26  static int vmx_event_pending(struct vcpu *v)
    4.27  {
    4.28      ASSERT(v == current);
    4.29 @@ -1148,7 +1136,6 @@ static struct hvm_function_table vmx_fun
    4.30      .update_guest_cr      = vmx_update_guest_cr,
    4.31      .update_guest_efer    = vmx_update_guest_efer,
    4.32      .flush_guest_tlbs     = vmx_flush_guest_tlbs,
    4.33 -    .update_vtpr          = vmx_update_vtpr,
    4.34      .stts                 = vmx_stts,
    4.35      .set_tsc_offset       = vmx_set_tsc_offset,
    4.36      .inject_exception     = vmx_inject_exception,
     5.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Dec 14 11:39:02 2007 +0000
     5.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Dec 14 11:50:24 2007 +0000
     5.3 @@ -106,11 +106,6 @@ struct hvm_function_table {
     5.4      void (*flush_guest_tlbs)(void);
     5.5  
     5.6      /*
     5.7 -     * Reflect the virtual APIC's value in the guest's V_TPR register
     5.8 -     */
     5.9 -    void (*update_vtpr)(struct vcpu *v, unsigned long value);
    5.10 -
    5.11 -    /*
    5.12       * Update specifics of the guest state:
    5.13       * 1) TS bit in guest cr0 
    5.14       * 2) TSC offset in guest
    5.15 @@ -161,12 +156,8 @@ u64 hvm_get_guest_tsc(struct vcpu *v);
    5.16  #define hvm_long_mode_enabled(v) (v,0)
    5.17  #endif
    5.18  
    5.19 -static inline enum hvm_intblk
    5.20 -hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
    5.21 -{
    5.22 -    ASSERT(v == current);
    5.23 -    return hvm_funcs.interrupt_blocked(v, intack);
    5.24 -}
    5.25 +enum hvm_intblk
    5.26 +hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack);
    5.27  
    5.28  static inline int
    5.29  hvm_guest_x86_mode(struct vcpu *v)
    5.30 @@ -184,12 +175,6 @@ hvm_update_host_cr3(struct vcpu *v)
    5.31      hvm_funcs.update_host_cr3(v);
    5.32  }
    5.33  
    5.34 -static inline void
    5.35 -hvm_update_vtpr(struct vcpu *v, unsigned long value)
    5.36 -{
    5.37 -    hvm_funcs.update_vtpr(v, value);
    5.38 -}
    5.39 -
    5.40  static inline void hvm_update_guest_cr(struct vcpu *v, unsigned int cr)
    5.41  {
    5.42      hvm_funcs.update_guest_cr(v, cr);