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: Fix __update_guest_eip() to clear

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.1-testing] svm: Fix __update_guest_eip() to clear interrupt shadow.
From: "Xen patchbot-3.1-testing" <patchbot-3.1-testing@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 10 Dec 2007 03:10:33 -0800
Delivery-date: Mon, 10 Dec 2007 03:12: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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1196959781 0
# Node ID 1a3035f3d5279ef99517ff904f0d66029acc638f
# Parent  111302f69b35468f1a463b93b591401e9375fb25
svm: Fix __update_guest_eip() to clear interrupt shadow.
Get rid of assertions about return value of get_instruction_length()
-- instead test in __update_guest_eip() and crash the domain.
Cache value of 'current' in svm_do_hlt().

The mismanagement of the interrupt shadow was found by Christoph
Egger of AMD.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
xen-unstable changeset:   16398:bc6aaa44e296c0d905daf57ebe268b32faa58376
xen-unstable date:        Tue Nov 20 15:05:36 2007 +0000
---
 xen/arch/x86/hvm/svm/svm.c            |   46 ++++++++++++++++++++++++----------
 xen/include/asm-x86/hvm/svm/emulate.h |   10 -------
 2 files changed, 33 insertions(+), 23 deletions(-)

diff -r 111302f69b35 -r 1a3035f3d527 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Dec 06 16:36:45 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Dec 06 16:49:41 2007 +0000
@@ -69,6 +69,22 @@ static void *root_vmcb[NR_CPUS] __read_m
 /* hardware assisted paging bits */
 extern int opt_hap_enabled;
 
+static void inline __update_guest_eip(
+    struct vmcb_struct *vmcb, unsigned int inst_len)
+{
+    if ( unlikely((inst_len == 0) || (inst_len > 15)) )
+    {
+        gdprintk(XENLOG_ERR, "Bad instruction length %u\n", inst_len);
+        domain_crash(current->domain);
+        return;
+    }
+
+    vmcb->rip += inst_len;
+    vmcb->rflags &= ~X86_EFLAGS_RF;
+
+    current->arch.hvm_svm.vmcb->interrupt_shadow = 0;
+}
+ 
 static void svm_inject_exception(struct vcpu *v, int trap, 
                                         int ev, int error_code)
 {
@@ -1171,7 +1187,6 @@ static void svm_vmexit_do_cpuid(struct v
                 ((uint64_t)eax << 32) | ebx, ((uint64_t)ecx << 32) | edx);
 
     inst_len = __get_instruction_length(v, INSTR_CPUID, NULL);
-    ASSERT(inst_len > 0);
     __update_guest_eip(vmcb, inst_len);
 }
 
@@ -2000,8 +2015,6 @@ static int svm_cr_access(struct vcpu *v,
         inst_len = __get_instruction_length_from_list(
             v, list_b, ARR_SIZE(list_b), &buffer[index], &match);
     }
-
-    ASSERT(inst_len > 0);
 
     inst_len += index;
 
@@ -2100,8 +2113,6 @@ static int svm_cr_access(struct vcpu *v,
         BUG();
     }
 
-    ASSERT(inst_len);
-
     __update_guest_eip(vmcb, inst_len);
     
     return result;
@@ -2224,7 +2235,11 @@ static void svm_do_msr_access(
 
 static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
 {
-    __update_guest_eip(vmcb, 1);
+    struct vcpu *curr = current;
+    unsigned int inst_len;
+
+    inst_len = __get_instruction_length(curr, INSTR_HLT, NULL);
+    __update_guest_eip(vmcb, inst_len);
 
     /* Check for interrupt not handled or new interrupt. */
     if ( (vmcb->rflags & X86_EFLAGS_IF) &&
@@ -2233,7 +2248,7 @@ static void svm_vmexit_do_hlt(struct vmc
         return;
     }
 
-    HVMTRACE_1D(HLT, current, /*int pending=*/ 0);
+    HVMTRACE_1D(HLT, curr, /*int pending=*/ 0);
     hvm_hlt(vmcb->rflags);
 }
 
@@ -2261,17 +2276,15 @@ void svm_handle_invlpg(const short invlp
      * Unknown how many bytes the invlpg instruction will take.  Use the
      * maximum instruction length here
      */
-    if (inst_copy_from_guest(opcode, svm_rip2pointer(v), length) < length)
+    if ( inst_copy_from_guest(opcode, svm_rip2pointer(v), length) < length )
     {
         gdprintk(XENLOG_ERR, "Error reading memory %d bytes\n", length);
-        domain_crash(v->domain);
-        return;
+        goto crash;
     }
 
     if (invlpga)
     {
         inst_len = __get_instruction_length(v, INSTR_INVLPGA, opcode);
-        ASSERT(inst_len > 0);
         __update_guest_eip(vmcb, inst_len);
 
         /* 
@@ -2285,7 +2298,11 @@ void svm_handle_invlpg(const short invlp
         /* What about multiple prefix codes? */
         prefix = (is_prefix(opcode[0])?opcode[0]:0);
         inst_len = __get_instruction_length(v, INSTR_INVLPG, opcode);
-        ASSERT(inst_len > 0);
+        if ( inst_len <= 0 )
+        {
+            gdprintk(XENLOG_ERR, "Error getting invlpg instr len\n");
+            goto crash;
+        }
 
         inst_len--;
         length -= inst_len;
@@ -2307,6 +2324,10 @@ void svm_handle_invlpg(const short invlp
     paging_invlpg(v, g_vaddr);
     /* signal invplg to ASID handler */
     svm_asid_g_invlpg (v, g_vaddr);
+    return;
+
+ crash:
+    domain_crash(v->domain);
 }
 
 
@@ -2518,7 +2539,6 @@ asmlinkage void svm_vmexit_handler(struc
 
     case VMEXIT_VMMCALL:
         inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
-        ASSERT(inst_len > 0);
         HVMTRACE_1D(VMMCALL, v, regs->eax);
         rc = hvm_do_hypercall(regs);
         if ( rc != HVM_HCALL_preempted )
diff -r 111302f69b35 -r 1a3035f3d527 xen/include/asm-x86/hvm/svm/emulate.h
--- a/xen/include/asm-x86/hvm/svm/emulate.h     Thu Dec 06 16:36:45 2007 +0000
+++ b/xen/include/asm-x86/hvm/svm/emulate.h     Thu Dec 06 16:49:41 2007 +0000
@@ -132,16 +132,6 @@ static inline int skip_prefix_bytes(u8 *
     return index;
 }
 
-
-
-static void inline __update_guest_eip(
-    struct vmcb_struct *vmcb, int inst_len) 
-{
-    ASSERT(inst_len > 0);
-    vmcb->rip += inst_len;
-    vmcb->rflags &= ~X86_EFLAGS_RF;
-}
-
 #endif /* __ASM_X86_HVM_SVM_EMULATE_H__ */
 
 /*

_______________________________________________
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: Fix __update_guest_eip() to clear interrupt shadow., Xen patchbot-3.1-testing <=