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] [PATCH] [PATCH] More accurate address decoding for VMX s

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [PATCH] [PATCH] More accurate address decoding for VMX string
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Fri, 27 May 2005 08:35:40 +0000
Delivery-date: Fri, 27 May 2005 09:01:42 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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 Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1571, 2005/05/27 09:35:40+01:00, leendert@xxxxxxxxxxxxxx

        [PATCH] [PATCH] More accurate address decoding for VMX string
        
        This patch includes two patches. The major patch is the improved address
        decoding for ins/outs instructions. In the previous version, segment
        overrides were ignored which caused a lot of problems for parts of the
        ROMBIOS code where they are used heavily. Address decoding has been
        made slightly easier now that GUEST_LINEAR_ADDRESS is documented. We
        still need to work around a bug in the current stepping and make sure
        that in protected mode the selector is not null.
        
        The second patch removes the ASSERT(cr3). cr3==0 is a perfectly legal
        value and Xen should not crash when its read.
        
        Signed-Off-By: Leendert van Doorn <leendert@xxxxxxxxxxxxxx>



 vmx.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 76 insertions(+), 24 deletions(-)


diff -Nru a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        2005-05-27 05:02:30 -04:00
+++ b/xen/arch/x86/vmx.c        2005-05-27 05:02:30 -04:00
@@ -318,6 +318,55 @@
     shadow_invlpg(ed, va);
 }
 
+static int check_for_null_selector(unsigned long eip)
+{
+    unsigned char inst[MAX_INST_LEN];
+    unsigned long sel;
+    int i, inst_len;
+    int inst_copy_from_guest(unsigned char *, unsigned long, int);
+
+    __vmread(INSTRUCTION_LEN, &inst_len);
+    memset(inst, 0, MAX_INST_LEN);
+    if (inst_copy_from_guest(inst, eip, inst_len) != inst_len) {
+        printf("check_for_null_selector: get guest instruction failed\n");
+        domain_crash_synchronous();
+    }
+
+    for (i = 0; i < inst_len; i++) {
+        switch (inst[i]) {
+        case 0xf3: /* REPZ */
+        case 0xf2: /* REPNZ */
+        case 0xf0: /* LOCK */
+        case 0x66: /* data32 */
+        case 0x67: /* addr32 */
+            continue;
+        case 0x2e: /* CS */
+            __vmread(GUEST_CS_SELECTOR, &sel);
+            break;
+        case 0x36: /* SS */
+            __vmread(GUEST_SS_SELECTOR, &sel);
+            break;
+        case 0x26: /* ES */
+            __vmread(GUEST_ES_SELECTOR, &sel);
+            break;
+        case 0x64: /* FS */
+            __vmread(GUEST_FS_SELECTOR, &sel);
+            break;
+        case 0x65: /* GS */
+            __vmread(GUEST_GS_SELECTOR, &sel);
+            break;
+        case 0x3e: /* DS */
+            /* FALLTHROUGH */
+        default:
+            /* DS is the default */
+            __vmread(GUEST_DS_SELECTOR, &sel);
+        }
+        return sel == 0 ? 1 : 0;
+    }
+
+    return 0;
+}
+
 static void vmx_io_instruction(struct cpu_user_regs *regs, 
                    unsigned long exit_qualification, unsigned long inst_len) 
 {
@@ -354,40 +403,44 @@
         domain_crash_synchronous(); 
     }
     p = &vio->vp_ioreq;
-    p->dir = test_bit(3, &exit_qualification);  
+    p->dir = test_bit(3, &exit_qualification); /* direction */
 
     p->pdata_valid = 0;
     p->count = 1;
     p->size = (exit_qualification & 7) + 1;
 
-    if (test_bit(4, &exit_qualification)) {
-        p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
-        p->pdata_valid = 1;
+    if (test_bit(4, &exit_qualification)) { /* string instruction */
+       unsigned long laddr;
 
-        if (vm86) {
-            unsigned long seg;
-            if (p->dir == IOREQ_WRITE) {
-                __vmread(GUEST_DS_SELECTOR, &seg);
-                p->u.pdata = (void *)
-                        ((seg << 4) + (regs->esi & 0xFFFF));
-            } else {
-                __vmread(GUEST_ES_SELECTOR, &seg);
-                p->u.pdata = (void *)
-                        ((seg << 4) + (regs->edi & 0xFFFF));
-            }
-        } else {
-               p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ?
-                   regs->esi : regs->edi);
+       __vmread(GUEST_LINEAR_ADDRESS, &laddr);
+        /*
+         * In protected mode, guest linear address is invalid if the
+         * selector is null.
+         */
+        if (!vm86 && check_for_null_selector(eip)) {
+            printf("String I/O with null selector (cs:eip=0x%lx:0x%lx)\n",
+                cs, eip);
+            laddr = (p->dir == IOREQ_WRITE) ? regs->esi : regs->edi;
         }
-        p->u.pdata = (void *) gva_to_gpa(p->u.data);
+        p->pdata_valid = 1;
+        p->u.pdata = (void *) gva_to_gpa(laddr);
+        p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
 
-        if (test_bit(5, &exit_qualification))
+        if (test_bit(5, &exit_qualification)) /* "rep" prefix */
            p->count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
+
+        /*
+         * Split up string I/O operations that cross page boundaries. Don't
+         * advance %eip so that "rep insb" will restart at the next page.
+         */
         if ((p->u.data & PAGE_MASK) != 
-            ((p->u.data + p->count * p->size - 1) & PAGE_MASK)) {
-            printk("stringio crosses page boundary!\n");
+               ((p->u.data + p->count * p->size - 1) & PAGE_MASK)) {
+           VMX_DBG_LOG(DBG_LEVEL_2,
+               "String I/O crosses page boundary (cs:eip=0x%lx:0x%lx)\n",
+               cs, eip);
             if (p->u.data & (p->size - 1)) {
-                printk("Not aligned I/O!\n");
+               printf("Unaligned string I/O operation (cs:eip=0x%lx:0x%lx)\n",
+                       cs, eip);
                 domain_crash_synchronous();     
             }
             p->count = (PAGE_SIZE - (p->u.data & ~PAGE_MASK)) / p->size;
@@ -885,7 +938,6 @@
         __vmx_bug(regs);
 
     value = (unsigned long) d->arch.arch_vmx.cpu_cr3;
-    ASSERT(value);
 
     switch (gp) {
         CASE_SET_REG(EAX, eax);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [PATCH] [PATCH] More accurate address decoding for VMX string, BitKeeper Bot <=