WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [HVM][VMX] Enable VMX TPR shadow feature.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM][VMX] Enable VMX TPR shadow feature.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 30 Oct 2006 22:10:13 +0000
Delivery-date: Thu, 02 Nov 2006 13:47:42 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 2b99c99f96e67572d33dc1117a6f402ab90d2d3d
# Parent  c33272c2571c7bab7056d8228490700d1df405f9
[HVM][VMX] Enable VMX TPR shadow feature.

x64 Windows uses CR8 to access TPR very frequently. This patch enables
TPR shadow and allows mov-from/to-CR8 to access it directly; tests
indicates it can boost greatly the performance of x64 Windows 2003.

Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 xen/arch/x86/hvm/vlapic.c        |   19 +++++++++++++------
 xen/arch/x86/hvm/vmx/io.c        |   25 +++++++++++++++++++++++++
 xen/arch/x86/hvm/vmx/vmcs.c      |   23 +++++++++++++++--------
 xen/arch/x86/hvm/vmx/vmx.c       |    5 +++++
 xen/include/asm-x86/hvm/vlapic.h |   25 ++++++++++++++++++++++++-
 5 files changed, 82 insertions(+), 15 deletions(-)

diff -r c33272c2571c -r 2b99c99f96e6 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Mon Oct 30 09:45:17 2006 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Mon Oct 30 10:42:27 2006 +0000
@@ -217,8 +217,7 @@ static int vlapic_accept_irq(struct vcpu
         if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
             break;
 
-        if ( vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR) &&
-             trig_mode)
+        if ( vlapic_test_and_set_irr(vector, vlapic) && trig_mode )
         {
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                   "level trig mode repeatedly for vector %d\n", vector);
@@ -482,6 +481,11 @@ static void vlapic_read_aligned(struct v
     *result = 0;
 
     switch ( offset ) {
+    case APIC_PROCPRI:
+        vlapic_update_ppr(vlapic);
+        *result = vlapic_get_reg(vlapic, offset);
+        break;
+
     case APIC_ARBPRI:
         printk("access local APIC ARBPRI register which is for P6\n");
         break;
@@ -616,6 +620,7 @@ static void vlapic_write(struct vcpu *v,
     case APIC_TASKPRI:
         vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
         vlapic_update_ppr(vlapic);
+        vlapic->flush_tpr_threshold = 1;
         break;
 
     case APIC_EOI:
@@ -814,7 +819,7 @@ void vlapic_timer_fn(void *data)
 
     vlapic->timer_last_update = now;
 
-    if ( vlapic_test_and_set_vector(timer_vector, vlapic->regs + APIC_IRR) )
+    if ( vlapic_test_and_set_irr(timer_vector, vlapic) )
         vlapic->intr_pending_count[timer_vector]++;
 
     if ( vlapic_lvtt_period(vlapic) )
@@ -891,7 +896,7 @@ int cpu_get_apic_interrupt(struct vcpu *
                 HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                             "Sending an illegal vector 0x%x.", highest_irr);
 
-                vlapic_set_vector(err_vector, vlapic->regs + APIC_IRR);
+                vlapic_set_irr(err_vector, vlapic);
                 highest_irr = err_vector;
             }
 
@@ -942,7 +947,7 @@ void vlapic_post_injection(struct vcpu *
     case APIC_DM_FIXED:
     case APIC_DM_LOWEST:
         vlapic_set_vector(vector, vlapic->regs + APIC_ISR);
-        vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
+        vlapic_clear_irr(vector, vlapic);
         vlapic_update_ppr(vlapic);
 
         if ( vector == vlapic_lvt_vector(vlapic, APIC_LVTT) )
@@ -950,7 +955,7 @@ void vlapic_post_injection(struct vcpu *
             if ( vlapic->intr_pending_count[vector] > 0 )
             {
                 vlapic->intr_pending_count[vector]--;
-                vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
+                vlapic_set_irr(vector, vlapic);
             }
         }
         break;
@@ -1000,6 +1005,8 @@ static int vlapic_reset(struct vlapic *v
     vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
 
     vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+
+    vlapic->flush_tpr_threshold = 0;
 
     if ( v->vcpu_id == 0 )
         vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
diff -r c33272c2571c -r 2b99c99f96e6 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Mon Oct 30 09:45:17 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/io.c Mon Oct 30 10:42:27 2006 +0000
@@ -68,6 +68,27 @@ static inline int is_interruptibility_st
     return interruptibility;
 }
 
+#ifdef __x86_64__
+static void update_tpr_threshold(struct vlapic *vlapic)
+{
+    int highest_irr, tpr;
+
+    /* Clear the work-to-do flag /then/ do the work. */
+    vlapic->flush_tpr_threshold = 0;
+    mb();
+
+    highest_irr = vlapic_find_highest_irr(vlapic);
+    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
+
+    if ( highest_irr == -1 )
+        __vmwrite(TPR_THRESHOLD, 0);
+    else
+        __vmwrite(TPR_THRESHOLD,
+                  (highest_irr > tpr) ? (tpr >> 4) : (highest_irr >> 4));
+}
+#else
+#define update_tpr_threshold(v) ((void)0)
+#endif
 
 asmlinkage void vmx_intr_assist(void)
 {
@@ -75,6 +96,7 @@ asmlinkage void vmx_intr_assist(void)
     int highest_vector;
     unsigned long eflags;
     struct vcpu *v = current;
+    struct vlapic *vlapic = VLAPIC(v);
     struct hvm_domain *plat=&v->domain->arch.hvm_domain;
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     struct hvm_virpic *pic= &plat->vpic;
@@ -97,6 +119,9 @@ asmlinkage void vmx_intr_assist(void)
         if ( callback_irq != 0 )
             pic_set_xen_irq(pic, callback_irq, local_events_need_delivery());
     }
+
+    if ( vlapic && vlapic_enabled(vlapic) && vlapic->flush_tpr_threshold )
+        update_tpr_threshold(vlapic);
 
     has_ext_irq = cpu_has_pending_irq(v);
 
diff -r c33272c2571c -r 2b99c99f96e6 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Mon Oct 30 09:45:17 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Oct 30 10:42:27 2006 +0000
@@ -346,8 +346,21 @@ static void vmx_do_launch(struct vcpu *v
 
     hvm_stts(v);
 
-    if(hvm_apic_support(v->domain))
-        vlapic_init(v);
+    if( hvm_apic_support(v->domain) && (vlapic_init(v) == 0) )
+    {
+#ifdef __x86_64__ 
+        u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
+        u64  vapic_page_addr = 
+                        page_to_maddr(v->arch.hvm_vcpu.vlapic->regs_page);
+
+        *cpu_exec_control   |= CPU_BASED_TPR_SHADOW;
+        *cpu_exec_control   &= ~CPU_BASED_CR8_STORE_EXITING;
+        *cpu_exec_control   &= ~CPU_BASED_CR8_LOAD_EXITING;
+        error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
+        error |= __vmwrite(VIRTUAL_APIC_PAGE_ADDR, vapic_page_addr);
+        error |= __vmwrite(TPR_THRESHOLD, 0);
+#endif
+    }
 
     vmx_set_host_env(v);
     init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
@@ -514,12 +527,6 @@ static inline int construct_vmcs_host(vo
     error |= __vmwrite(HOST_CR4, crn);
 
     error |= __vmwrite(HOST_RIP, (unsigned long) vmx_asm_vmexit_handler);
-#ifdef __x86_64__
-    /* TBD: support cr8 for 64-bit guest */
-    __vmwrite(VIRTUAL_APIC_PAGE_ADDR, 0);
-    __vmwrite(TPR_THRESHOLD, 0);
-    __vmwrite(SECONDARY_VM_EXEC_CONTROL, 0);
-#endif
 
     return error;
 }
diff -r c33272c2571c -r 2b99c99f96e6 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Oct 30 09:45:17 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Oct 30 10:42:27 2006 +0000
@@ -2409,6 +2409,11 @@ asmlinkage void vmx_vmexit_handler(struc
         vmx_inject_hw_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE);
         break;
 
+    case EXIT_REASON_TPR_BELOW_THRESHOLD:
+        vlapic_update_ppr(VLAPIC(v));
+        VLAPIC(v)->flush_tpr_threshold = 1;
+        break;
+
     default:
         domain_crash_synchronous();     /* should not happen */
     }
diff -r c33272c2571c -r 2b99c99f96e6 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Mon Oct 30 09:45:17 2006 +0000
+++ b/xen/include/asm-x86/hvm/vlapic.h  Mon Oct 30 10:42:27 2006 +0000
@@ -107,6 +107,7 @@ struct vlapic {
     uint32_t           timer_divide_count;
     struct timer       vlapic_timer;
     int                intr_pending_count[MAX_VECTOR];
+    int                flush_tpr_threshold;
     s_time_t           timer_last_update;
     direct_intr_info_t direct_intr;
     uint32_t           err_status;
@@ -117,12 +118,30 @@ struct vlapic {
     void               *regs;
 };
 
+static inline int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
+{
+    vlapic->flush_tpr_threshold = 1;
+    return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
+}
+
+static inline void vlapic_set_irr(int vector, struct vlapic *vlapic)
+{
+    vlapic->flush_tpr_threshold = 1;
+    vlapic_set_vector(vector, vlapic->regs + APIC_IRR);
+}
+
+static inline void vlapic_clear_irr(int vector, struct vlapic *vlapic)
+{
+    vlapic->flush_tpr_threshold = 1;
+    vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
+}
+
 static inline int vlapic_set_irq(struct vlapic *vlapic,
                                  uint8_t vec, uint8_t trig)
 {
     int ret;
 
-    ret = vlapic_test_and_set_vector(vec, vlapic->regs + APIC_IRR);
+    ret = vlapic_test_and_set_irr(vec, vlapic);
     if ( trig )
         vlapic_set_vector(vec, vlapic->regs + APIC_TMR);
 
@@ -144,12 +163,16 @@ static inline void vlapic_set_reg(struct
 
 void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
 
+extern int vlapic_find_highest_irr(struct vlapic *vlapic);
+
 int cpu_has_apic_interrupt(struct vcpu* v);
 int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
 
 extern int vlapic_init(struct vcpu *vc);
 
 extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
+
+extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
 
 int vlapic_accept_pic_intr(struct vcpu *v);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM][VMX] Enable VMX TPR shadow feature., Xen patchbot-unstable <=