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][SVM] Allow SVM to take advantage of

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM][SVM] Allow SVM to take advantage of flag_dr_dirty.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 28 Aug 2006 12:40:13 +0000
Delivery-date: Mon, 28 Aug 2006 05:40:29 -0700
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 kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID b61b7478b3245daac1d76a2eadb6f33123aec85c
# Parent  fab84f9c0ce6d5d1fb89b31ef071148f781ae5a6
[HVM][SVM] Allow SVM to take advantage of flag_dr_dirty.

Signed-off-by: Travis Betak <travis.betak@xxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c         |  155 ++++++++++++++-----------------------
 xen/arch/x86/hvm/svm/vmcb.c        |    2 
 xen/include/asm-x86/hvm/svm/vmcb.h |   45 ++++++++++
 3 files changed, 105 insertions(+), 97 deletions(-)

diff -r fab84f9c0ce6 -r b61b7478b324 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Aug 28 12:09:36 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Aug 28 12:35:43 2006 +0100
@@ -403,6 +403,50 @@ static inline int long_mode_do_msr_write
     return 1;
 }
 
+
+#define loaddebug(_v,_reg) \
+    __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+#define savedebug(_v,_reg) \
+    __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" 
((_v)->debugreg[_reg]))
+
+
+static inline void svm_save_dr(struct vcpu *v)
+{
+    if (v->arch.hvm_vcpu.flag_dr_dirty)
+    {
+        /* clear the DR dirty flag and re-enable intercepts for DR accesses */ 
+        v->arch.hvm_vcpu.flag_dr_dirty = 0;
+        v->arch.hvm_svm.vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES;
+
+        savedebug(&v->arch.guest_context, 0);    
+        savedebug(&v->arch.guest_context, 1);    
+        savedebug(&v->arch.guest_context, 2);    
+        savedebug(&v->arch.guest_context, 3);    
+    }
+}
+
+
+static inline void __restore_debug_registers(struct vcpu *v)
+{
+    loaddebug(&v->arch.guest_context, 0);
+    loaddebug(&v->arch.guest_context, 1);
+    loaddebug(&v->arch.guest_context, 2);
+    loaddebug(&v->arch.guest_context, 3);
+}
+
+
+static inline void svm_restore_dr(struct vcpu *v)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    if (!vmcb)
+        return;
+
+    if (unlikely(vmcb->dr7 & 0xFF))
+        __restore_debug_registers(v);
+}
+
+
 static int svm_realmode(struct vcpu *v)
 {
     unsigned long cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
@@ -717,6 +761,7 @@ static void svm_ctxt_switch_from(struct 
 static void svm_ctxt_switch_from(struct vcpu *v)
 {
     svm_freeze_time(v);
+    svm_save_dr(v);
 }
 
 static void svm_ctxt_switch_to(struct vcpu *v)
@@ -732,6 +777,7 @@ static void svm_ctxt_switch_to(struct vc
     set_segment_register(es, 0);
     set_segment_register(ss, 0);
 #endif
+    svm_restore_dr(v);
 }
 
 
@@ -1183,55 +1229,16 @@ static inline void set_reg(unsigned int 
 }
                            
 
-static void svm_dr_access (struct vcpu *v, unsigned int reg, unsigned int type,
-                           struct cpu_user_regs *regs)
-{
-    unsigned long *reg_p = 0;
-    unsigned int gpreg = 0;
-    unsigned long eip;
-    int inst_len;
-    int index;
-    struct vmcb_struct *vmcb;
-    u8 buffer[MAX_INST_LEN];
-    u8 prefix = 0;
-
-    vmcb = v->arch.hvm_svm.vmcb;
-    
-    ASSERT(vmcb);
-
-    eip = vmcb->rip;
-    inst_copy_from_guest(buffer, svm_rip2pointer(vmcb), sizeof(buffer));
-    index = skip_prefix_bytes(buffer, sizeof(buffer));
-    
-    ASSERT(buffer[index+0] == 0x0f && (buffer[index+1] & 0xFD) == 0x21);
-
-    if (index > 0 && (buffer[index-1] & 0xF0) == 0x40)
-        prefix = buffer[index-1];
-
-    gpreg = decode_src_reg(prefix, buffer[index + 2]);
-    ASSERT(reg == decode_dest_reg(prefix, buffer[index + 2]));
-
-    HVM_DBG_LOG(DBG_LEVEL_1, "svm_dr_access : eip=%lx, reg=%d, gpreg = %x",
-                eip, reg, gpreg);
-
-    reg_p = get_reg_p(gpreg, regs, vmcb);
-        
-    switch (type) 
-    {
-    case TYPE_MOV_TO_DR: 
-        inst_len = __get_instruction_length(vmcb, INSTR_MOV2DR, buffer);
-        v->arch.guest_context.debugreg[reg] = *reg_p;
-        break;
-    case TYPE_MOV_FROM_DR:
-        inst_len = __get_instruction_length(vmcb, INSTR_MOVDR2, buffer);
-        *reg_p = v->arch.guest_context.debugreg[reg];
-        break;
-    default:
-        __hvm_bug(regs);
-        break;
-    }
-    ASSERT(inst_len > 0);
-    __update_guest_eip(vmcb, inst_len);
+static void svm_dr_access(struct vcpu *v, struct cpu_user_regs *regs)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    v->arch.hvm_vcpu.flag_dr_dirty = 1;
+
+    __restore_debug_registers(v);
+
+    /* allow the guest full access to the debug registers */
+    vmcb->dr_intercepts = 0;
 }
 
 
@@ -2862,53 +2869,9 @@ asmlinkage void svm_vmexit_handler(struc
     case VMEXIT_CR8_WRITE:
         svm_cr_access(v, 8, TYPE_MOV_TO_CR, &regs);
         break;
-
-    case VMEXIT_DR0_READ:
-        svm_dr_access(v, 0, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR1_READ:
-        svm_dr_access(v, 1, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR2_READ:
-        svm_dr_access(v, 2, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR3_READ:
-        svm_dr_access(v, 3, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR6_READ:
-        svm_dr_access(v, 6, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR7_READ:
-        svm_dr_access(v, 7, TYPE_MOV_FROM_DR, &regs);
-        break;
-
-    case VMEXIT_DR0_WRITE:
-        svm_dr_access(v, 0, TYPE_MOV_TO_DR, &regs);
-        break;
-
-    case VMEXIT_DR1_WRITE:
-        svm_dr_access(v, 1, TYPE_MOV_TO_DR, &regs);
-        break;
-
-    case VMEXIT_DR2_WRITE:
-        svm_dr_access(v, 2, TYPE_MOV_TO_DR, &regs);
-        break;
-
-    case VMEXIT_DR3_WRITE:
-        svm_dr_access(v, 3, TYPE_MOV_TO_DR, &regs);
-        break;
-
-    case VMEXIT_DR6_WRITE:
-        svm_dr_access(v, 6, TYPE_MOV_TO_DR, &regs);
-        break;
-
-    case VMEXIT_DR7_WRITE:
-        svm_dr_access(v, 7, TYPE_MOV_TO_DR, &regs);
+       
+    case VMEXIT_DR0_WRITE ... VMEXIT_DR7_WRITE:
+        svm_dr_access(v, &regs);
         break;
 
     case VMEXIT_IOIO:
diff -r fab84f9c0ce6 -r b61b7478b324 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Mon Aug 28 12:09:36 2006 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Mon Aug 28 12:35:43 2006 +0100
@@ -121,7 +121,7 @@ static int construct_vmcb_controls(struc
         GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_RDTSCP;
 
     /* read or write all debug registers 0 - 15 */
-    vmcb->dr_intercepts = 0;
+    vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES;
 
     /* RD/WR all control registers 0 - 15, but not read CR2 */
     vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ | CR_INTERCEPT_CR2_WRITE);
diff -r fab84f9c0ce6 -r b61b7478b324 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h        Mon Aug 28 12:09:36 2006 +0100
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h        Mon Aug 28 12:35:43 2006 +0100
@@ -113,6 +113,51 @@ enum CRInterceptBits
     CR_INTERCEPT_CR14_WRITE = 1 << 30,
     CR_INTERCEPT_CR15_WRITE = 1 << 31,
 };
+
+
+/* debug register intercepts */
+enum DRInterceptBits
+{
+    DR_INTERCEPT_DR0_READ   = 1 << 0,
+    DR_INTERCEPT_DR1_READ   = 1 << 1,
+    DR_INTERCEPT_DR2_READ   = 1 << 2,
+    DR_INTERCEPT_DR3_READ   = 1 << 3,
+    DR_INTERCEPT_DR4_READ   = 1 << 4,
+    DR_INTERCEPT_DR5_READ   = 1 << 5,
+    DR_INTERCEPT_DR6_READ   = 1 << 6,
+    DR_INTERCEPT_DR7_READ   = 1 << 7,
+    DR_INTERCEPT_DR8_READ   = 1 << 8,
+    DR_INTERCEPT_DR9_READ   = 1 << 9,
+    DR_INTERCEPT_DR10_READ  = 1 << 10,
+    DR_INTERCEPT_DR11_READ  = 1 << 11,
+    DR_INTERCEPT_DR12_READ  = 1 << 12,
+    DR_INTERCEPT_DR13_READ  = 1 << 13,
+    DR_INTERCEPT_DR14_READ  = 1 << 14,
+    DR_INTERCEPT_DR15_READ  = 1 << 15,
+    DR_INTERCEPT_DR0_WRITE  = 1 << 16,
+    DR_INTERCEPT_DR1_WRITE  = 1 << 17,
+    DR_INTERCEPT_DR2_WRITE  = 1 << 18,
+    DR_INTERCEPT_DR3_WRITE  = 1 << 19,
+    DR_INTERCEPT_DR4_WRITE  = 1 << 20,
+    DR_INTERCEPT_DR5_WRITE  = 1 << 21,
+    DR_INTERCEPT_DR6_WRITE  = 1 << 22,
+    DR_INTERCEPT_DR7_WRITE  = 1 << 23,
+    DR_INTERCEPT_DR8_WRITE  = 1 << 24,
+    DR_INTERCEPT_DR9_WRITE  = 1 << 25,
+    DR_INTERCEPT_DR10_WRITE = 1 << 26,
+    DR_INTERCEPT_DR11_WRITE = 1 << 27,
+    DR_INTERCEPT_DR12_WRITE = 1 << 28,
+    DR_INTERCEPT_DR13_WRITE = 1 << 29,
+    DR_INTERCEPT_DR14_WRITE = 1 << 30,
+    DR_INTERCEPT_DR15_WRITE = 1 << 31,
+};
+
+/* for lazy save/restore we'd like to intercept all DR writes */
+#define DR_INTERCEPT_ALL_WRITES \
+    (DR_INTERCEPT_DR0_WRITE|DR_INTERCEPT_DR1_WRITE|DR_INTERCEPT_DR2_WRITE \
+    |DR_INTERCEPT_DR3_WRITE|DR_INTERCEPT_DR4_WRITE|DR_INTERCEPT_DR5_WRITE \
+    |DR_INTERCEPT_DR6_WRITE|DR_INTERCEPT_DR7_WRITE) 
+
 
 enum VMEXIT_EXITCODE
 {

_______________________________________________
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][SVM] Allow SVM to take advantage of flag_dr_dirty., Xen patchbot-unstable <=