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-3.1-testing] svm: Greatly reduce total number of CR

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.1-testing] svm: Greatly reduce total number of CR8 intercepts
From: "Xen patchbot-3.1-testing" <patchbot-3.1-testing@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 14 Dec 2007 10:20:21 -0800
Delivery-date: Fri, 14 Dec 2007 10:20:30 -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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197633121 0
# Node ID 56ffd5555ad599c9bdd22eb56fd245c2bb3d6077
# Parent  c90aee0830a71e9295d3a289c7db9cafa4e4fae9
svm: Greatly reduce total number of CR8 intercepts

This patch reduces the number of CR8 intercept to a fraction of the
number of CR8 intercepts without.  First, CR8 read intercepts are
completely disabled since the SVM vTPR is kept kept in sync with the
HVM vLAPIC TPR.  Second, CR8 write intercepts are enabled and disabled
based upon certain conditions.  Most of the time, CR8 write intercepts
are disabled.  They are enabled only when there is a pending interrupt
that can't be delivered because of either the current ISR or TPR (aka
PPR) because this is the only time the TPR matters.

With this patch, the number of CR8 intercepts dropped from around
10,000,000 to around 6,000 during boot of Windows 2003 Server 64-bit
(this is a rough estimate).

Signed-off-by: Travis Betak <travis.betak@xxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
xen-unstable changeset:   15844:924c153e0cf90e7c6f9033842d702d0fbc122d29
xen-unstable date:        Mon Sep 10 16:13:13 2007 +0100
---
 xen/arch/x86/hvm/svm/intr.c |   40 ++++++++++++++++++++++++++++++++++++----
 xen/arch/x86/hvm/svm/svm.c  |   10 ++++++++++
 xen/arch/x86/hvm/svm/vmcb.c |   10 ++++++++--
 3 files changed, 54 insertions(+), 6 deletions(-)

diff -r c90aee0830a7 -r 56ffd5555ad5 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Wed Dec 12 14:42:41 2007 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c       Fri Dec 14 11:52:01 2007 +0000
@@ -31,6 +31,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
+#include <asm/hvm/vlapic.h>
 #include <asm/hvm/svm/svm.h>
 #include <asm/hvm/svm/intr.h>
 #include <xen/event.h>
@@ -59,6 +60,32 @@ static inline int svm_inject_extint(stru
 
     return 0;
 }
+
+static void update_cr8_intercept(
+    struct vcpu *v, int intr_window_enabled)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    struct vlapic *vlapic = vcpu_vlapic(v);
+    int max_irr;
+
+    vmcb->cr_intercepts &= ~CR_INTERCEPT_CR8_WRITE;
+ 
+    /* 
+     * If ExtInts are masked then that dominates the TPR --- the 'interrupt
+     * window' has already been enabled in this case.
+     */
+    if ( intr_window_enabled )
+        return;
+
+    /* Is there an interrupt pending at the LAPIC? Nothing to do if not. */
+    if ( !vlapic_enabled(vlapic) || 
+         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
+        return;
+
+    /* Highest-priority pending interrupt is masked by the TPR? */
+    if ( (vmcb->vintr.fields.tpr & 0xf) >= (max_irr >> 4) )
+        vmcb->cr_intercepts |= CR_INTERCEPT_CR8_WRITE;
+}
     
 asmlinkage void svm_intr_assist(void) 
 {
@@ -66,6 +93,7 @@ asmlinkage void svm_intr_assist(void)
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
+    int intr_window_enabled = 0;
 
     /*
      * Previous Interrupt delivery caused this intercept?
@@ -83,7 +111,7 @@ asmlinkage void svm_intr_assist(void)
         vmcb->exitintinfo.bytes = 0;
         HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
         svm_inject_extint(v, intr_vector);
-        return;
+        goto out;
     }
 
     /*
@@ -92,13 +120,13 @@ asmlinkage void svm_intr_assist(void)
      * external physical interrupt was pending when we executed VMRUN.
      */
     if ( vmcb->vintr.fields.irq )
-        return;
+        goto out;
 
     /* Crank the handle on interrupt state and check for new interrrupts. */
     pt_update_irq(v);
     hvm_set_callback_irq_level();
     if ( !cpu_has_pending_irq(v) )
-        return;
+        goto out;
 
     /*
      * If the guest can't take an interrupt right now, create a 'fake'
@@ -122,7 +150,8 @@ asmlinkage void svm_intr_assist(void)
         vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
         HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
         svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
-        return;
+        intr_window_enabled = 1;
+        goto out;
     }
 
     /* Okay, we can deliver the interrupt: grab it and update PIC state. */
@@ -133,6 +162,9 @@ asmlinkage void svm_intr_assist(void)
     svm_inject_extint(v, intr_vector);
 
     pt_intr_post(v, intr_vector, intr_type);
+
+ out:
+    update_cr8_intercept(v, intr_window_enabled);
 }
 
 /*
diff -r c90aee0830a7 -r 56ffd5555ad5 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Dec 12 14:42:41 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Dec 14 11:52:01 2007 +0000
@@ -2422,6 +2422,16 @@ asmlinkage void svm_vmexit_handler(struc
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int inst_len, rc;
 
+    /*
+     * Before doing anything else, we need to sync up the VLAPIC's TPR with
+     * SVM's vTPR if CR8 writes are currently disabled.  It's OK if the 
+     * guest doesn't touch the CR8 (e.g. 32-bit Windows) because we update
+     * the vTPR on MMIO writes to the TPR
+     */
+    if ( !(vmcb->cr_intercepts & CR_INTERCEPT_CR8_WRITE) )
+        vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
+                       (vmcb->vintr.fields.tpr & 0x0F) << 4);
+
     exit_reason = vmcb->exitcode;
 
     HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
diff -r c90aee0830a7 -r 56ffd5555ad5 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Wed Dec 12 14:42:41 2007 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Fri Dec 14 11:52:01 2007 +0000
@@ -131,8 +131,14 @@ static int construct_vmcb(struct vcpu *v
     /* Intercept all debug-register writes. */
     vmcb->dr_intercepts = ~0u;
 
-    /* Intercept all control-register accesses, except to CR2. */
-    vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ | CR_INTERCEPT_CR2_WRITE);
+    /*
+     * Intercept all control-register accesses except for CR2 reads/writes
+     * and CR8 reads (and actually CR8 writes, but that's a special case
+     * that's handled in svm/intr.c). 
+     */
+    vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ |
+                            CR_INTERCEPT_CR2_WRITE |
+                            CR_INTERCEPT_CR8_READ);
 
     /* I/O and MSR permission bitmaps. */
     arch_svm->msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.1-testing] svm: Greatly reduce total number of CR8 intercepts, Xen patchbot-3.1-testing <=