[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] SVM: Treat the vlapic's tpr as the master copy and sync the vtpr to it



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197633024 0
# Node ID 966a6d3b74087474df337e00b31cbecf495b442a
# Parent  cb0ce96c02defc429ca09e1a33f972f2ee09a61b
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@xxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c        |   19 +++++++++++++++++++
 xen/arch/x86/hvm/svm/svm.c    |   20 ++++++++------------
 xen/arch/x86/hvm/vlapic.c     |    1 -
 xen/arch/x86/hvm/vmx/vmx.c    |   13 -------------
 xen/include/asm-x86/hvm/hvm.h |   19 ++-----------------
 5 files changed, 29 insertions(+), 43 deletions(-)

diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Fri Dec 14 11:50:24 2007 +0000
@@ -1403,6 +1403,25 @@ void hvm_cpuid(unsigned int input, unsig
 #endif
         break;
     }
+}
+
+enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
+{
+    enum hvm_intblk r;
+    ASSERT(v == current);
+
+    r = hvm_funcs.interrupt_blocked(v, intack);
+    if ( r != hvm_intblk_none )
+        return r;
+
+    if ( intack.source == hvm_intsrc_lapic )
+    {
+        uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
+        if ( (tpr >> 4) >= (intack.vector >> 4) )
+            return hvm_intblk_tpr;
+    }
+
+    return r;
 }
 
 static long hvm_grant_table_op(
diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Dec 14 11:50:24 2007 +0000
@@ -443,10 +443,6 @@ static enum hvm_intblk svm_interrupt_blo
     if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
         return hvm_intblk_rflags_ie;
 
-    if ( (intack.source == hvm_intsrc_lapic) &&
-         ((vmcb->vintr.fields.tpr & 0xf) >= (intack.vector >> 4)) )
-        return hvm_intblk_tpr;
-
     return hvm_intblk_none;
 }
 
@@ -520,13 +516,6 @@ static void svm_flush_guest_tlbs(void)
      * next VMRUN.  (If ASIDs are disabled, the whole TLB is flushed on
      * VMRUN anyway). */
     svm_asid_inc_generation();
-}
-
-static void svm_update_vtpr(struct vcpu *v, unsigned long value)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    vmcb->vintr.fields.tpr = value & 0x0f;
 }
 
 static void svm_sync_vmcb(struct vcpu *v)
@@ -787,6 +776,10 @@ static void svm_do_resume(struct vcpu *v
         /* Migrating to another ASID domain.  Request a new ASID. */
         svm_asid_init_vcpu(v);
     }
+
+    /* Reflect the vlapic's TPR in the hardware vtpr */
+    v->arch.hvm_svm.vmcb->vintr.fields.tpr = 
+        (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
 
     hvm_do_resume(v);
     reset_stack_and_jump(svm_asm_do_resume);
@@ -885,7 +878,6 @@ static struct hvm_function_table svm_fun
     .update_guest_cr      = svm_update_guest_cr,
     .update_guest_efer    = svm_update_guest_efer,
     .flush_guest_tlbs     = svm_flush_guest_tlbs,
-    .update_vtpr          = svm_update_vtpr,
     .stts                 = svm_stts,
     .set_tsc_offset       = svm_set_tsc_offset,
     .inject_exception     = svm_inject_exception,
@@ -2212,6 +2204,10 @@ asmlinkage void svm_vmexit_handler(struc
         domain_crash(v->domain);
         break;
     }
+
+    /* The exit may have updated the TPR: reflect this in the hardware vtpr */
+    vmcb->vintr.fields.tpr = 
+        (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
 }
 
 asmlinkage void svm_trace_vmentry(void)
diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Fri Dec 14 11:50:24 2007 +0000
@@ -580,7 +580,6 @@ static void vlapic_write(struct vcpu *v,
     {
     case APIC_TASKPRI:
         vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
-        hvm_update_vtpr(v, (val >> 4) & 0x0f);
         break;
 
     case APIC_EOI:
diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Dec 14 11:50:24 2007 +0000
@@ -1011,13 +1011,6 @@ static enum hvm_intblk vmx_interrupt_blo
     if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
         return hvm_intblk_rflags_ie;
 
-    if ( intack.source == hvm_intsrc_lapic )
-    {
-        uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
-        if ( (tpr >> 4) >= (intack.vector >> 4) )
-            return hvm_intblk_tpr;
-    }
-
     return hvm_intblk_none;
 }
 
@@ -1118,11 +1111,6 @@ static void vmx_inject_exception(
         __restore_debug_registers(curr);
         write_debugreg(6, read_debugreg(6) | 0x4000);
     }
-}
-
-static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
-{
-    /* VMX doesn't have a V_TPR field */
 }
 
 static int vmx_event_pending(struct vcpu *v)
@@ -1148,7 +1136,6 @@ static struct hvm_function_table vmx_fun
     .update_guest_cr      = vmx_update_guest_cr,
     .update_guest_efer    = vmx_update_guest_efer,
     .flush_guest_tlbs     = vmx_flush_guest_tlbs,
-    .update_vtpr          = vmx_update_vtpr,
     .stts                 = vmx_stts,
     .set_tsc_offset       = vmx_set_tsc_offset,
     .inject_exception     = vmx_inject_exception,
diff -r cb0ce96c02de -r 966a6d3b7408 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Fri Dec 14 11:50:24 2007 +0000
@@ -106,11 +106,6 @@ struct hvm_function_table {
     void (*flush_guest_tlbs)(void);
 
     /*
-     * Reflect the virtual APIC's value in the guest's V_TPR register
-     */
-    void (*update_vtpr)(struct vcpu *v, unsigned long value);
-
-    /*
      * Update specifics of the guest state:
      * 1) TS bit in guest cr0 
      * 2) TSC offset in guest
@@ -161,12 +156,8 @@ u64 hvm_get_guest_tsc(struct vcpu *v);
 #define hvm_long_mode_enabled(v) (v,0)
 #endif
 
-static inline enum hvm_intblk
-hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
-{
-    ASSERT(v == current);
-    return hvm_funcs.interrupt_blocked(v, intack);
-}
+enum hvm_intblk
+hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack);
 
 static inline int
 hvm_guest_x86_mode(struct vcpu *v)
@@ -182,12 +173,6 @@ hvm_update_host_cr3(struct vcpu *v)
 hvm_update_host_cr3(struct vcpu *v)
 {
     hvm_funcs.update_host_cr3(v);
-}
-
-static inline void
-hvm_update_vtpr(struct vcpu *v, unsigned long value)
-{
-    hvm_funcs.update_vtpr(v, value);
 }
 
 static inline void hvm_update_guest_cr(struct vcpu *v, unsigned int cr)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.