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-devel

[Xen-devel] [PATCH] vmx-worldswitch-1-to-1.patch

To: Ian Pratt <Ian.Pratt@xxxxxxxxxxxx>, Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] vmx-worldswitch-1-to-1.patch
From: Arun Sharma <arun.sharma@xxxxxxxxx>
Date: Fri, 27 May 2005 12:35:25 -0700
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Fri, 27 May 2005 19:33:00 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
Fix VMX world switch to use 1:1 page tables when the guest has paging
disabled. Also do a printk instead of VMX_DBG_LOG() anytime we crash
a domain.

Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>

--- 1.27/tools/libxc/xc_vmx_build.c     2005-05-24 13:32:29 -07:00
+++ edited/tools/libxc/xc_vmx_build.c   2005-05-27 12:02:08 -07:00
@@ -10,7 +10,7 @@
 #include <zlib.h>
 #include "linux_boot_params.h"
 
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
===== xen/arch/x86/domain.c 1.200 vs edited =====
--- 1.200/xen/arch/x86/domain.c 2005-05-25 03:36:57 -07:00
+++ edited/xen/arch/x86/domain.c        2005-05-27 12:02:09 -07:00
@@ -339,7 +339,6 @@
     }
 
     ed->arch.schedule_tail = arch_vmx_do_launch;
-    clear_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
 
 #if defined (__i386)
     ed->arch.arch_vmx.vmx_platform.real_mode_data = 
===== xen/arch/x86/vmx.c 1.58 vs edited =====
--- 1.58/xen/arch/x86/vmx.c     2005-05-26 19:36:15 -07:00
+++ edited/xen/arch/x86/vmx.c   2005-05-27 12:27:13 -07:00
@@ -122,7 +122,6 @@
 
 static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs) 
 {
-    struct exec_domain *ed = current;
     unsigned long eip;
     l1_pgentry_t gpte;
     unsigned long gpa; /* FIXME: PAE */
@@ -137,15 +136,8 @@
     }
 #endif
 
-    /*
-     * If vpagetable is zero, then we are still emulating 1:1 page tables,
-     * and we should have never gotten here.
-     */
-    if ( !test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state) )
-    {
-        printk("vmx_do_page_fault while running on 1:1 page table\n");
-        return 0;
-    }
+    if (!vmx_paging_enabled(current))
+        handle_mmio(va, va);
 
     gpte = gva_to_gpte(va);
     if (!(l1e_get_flags(gpte) & _PAGE_PRESENT) )
@@ -399,7 +391,7 @@
 
     vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va;
     if (vio == 0) {
-        VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio);
+        printk("bad shared page: %lx", (unsigned long) vio);
         domain_crash_synchronous(); 
     }
     p = &vio->vp_ioreq;
@@ -423,7 +415,10 @@
             laddr = (p->dir == IOREQ_WRITE) ? regs->esi : regs->edi;
         }
         p->pdata_valid = 1;
-        p->u.pdata = (void *) gva_to_gpa(laddr);
+
+        p->u.data = laddr;
+        if (vmx_paging_enabled(d))
+                p->u.pdata = (void *) gva_to_gpa(p->u.data);
         p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
 
         if (test_bit(5, &exit_qualification)) /* "rep" prefix */
@@ -481,7 +476,7 @@
        return 0;
     }
 
-    mfn = phys_to_machine_mapping(l1e_get_pfn(gva_to_gpte(laddr)));
+    mfn = phys_to_machine_mapping(laddr >> PAGE_SHIFT);
     addr = map_domain_mem((mfn << PAGE_SHIFT) | (laddr & ~PAGE_MASK));
 
     if (dir == COPY_IN)
@@ -570,6 +565,12 @@
 
     error |= __vmwrite(CR0_READ_SHADOW, c->cr0);
 
+    if (!vmx_paging_enabled(d)) {
+       VMX_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
+       __vmwrite(GUEST_CR3, pagetable_val(d->domain->arch.phys_table));
+        goto skip_cr3;
+    }
+
     if (c->cr3 == d->arch.arch_vmx.cpu_cr3) {
        /* 
         * This is simple TLB flush, implying the guest has 
@@ -578,7 +579,7 @@
         */
        mfn = phys_to_machine_mapping(c->cr3 >> PAGE_SHIFT);
        if ((mfn << PAGE_SHIFT) != pagetable_val(d->arch.guest_table)) {
-           VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value=%lx", c->cr3);
+           printk("Invalid CR3 value=%lx", c->cr3);
            domain_crash_synchronous();
            return 0;
        }
@@ -590,7 +591,7 @@
         */
        VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %lx", c->cr3);
        if ((c->cr3 >> PAGE_SHIFT) > d->domain->max_pages) {
-           VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value=%lx", c->cr3);
+           printk("Invalid CR3 value=%lx", c->cr3);
            domain_crash_synchronous(); 
            return 0;
        }
@@ -605,6 +606,8 @@
        __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
     }
 
+skip_cr3:
+
     error |= __vmread(CR4_READ_SHADOW, &old_cr4);
     error |= __vmwrite(GUEST_CR4, (c->cr4 | X86_CR4_VMXE));
     error |= __vmwrite(CR4_READ_SHADOW, c->cr4);
@@ -731,18 +734,18 @@
     struct exec_domain *d = current;
     unsigned long old_base_mfn, mfn;
     unsigned long eip;
+    int paging_enabled;
 
     /* 
      * CR0: We don't want to lose PE and PG.
      */
+    paging_enabled = vmx_paging_enabled(d);
     __vmwrite(GUEST_CR0, (value | X86_CR0_PE | X86_CR0_PG));
+    __vmwrite(CR0_READ_SHADOW, value);
 
-    if (value & (X86_CR0_PE | X86_CR0_PG) &&
-        !test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) {
-        /*
-         * Enable paging
-         */
-        set_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state);
+    VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
+    if ((value & X86_CR0_PE) && (value & X86_CR0_PG) 
+        && !paging_enabled) {
         /*
          * The guest CR3 must be pointing to the guest physical.
          */
@@ -750,8 +753,7 @@
                             d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
              !get_page(pfn_to_page(mfn), d->domain) )
         {
-            VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx",
-                        d->arch.arch_vmx.cpu_cr3);
+            printk("Invalid CR3 value = %lx", d->arch.arch_vmx.cpu_cr3);
             domain_crash_synchronous(); /* need to take a clean path */
         }
         old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
@@ -776,8 +778,7 @@
     } else {
         if ((value & X86_CR0_PE) == 0) {
             __vmread(GUEST_EIP, &eip);
-            VMX_DBG_LOG(DBG_LEVEL_1,
-               "Disabling CR0.PE at %%eip 0x%lx", eip);
+            VMX_DBG_LOG(DBG_LEVEL_1, "Disabling CR0.PE at %%eip 0x%lx\n", eip);
            if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
                set_bit(VMX_CPU_STATE_ASSIST_ENABLED,
                                        &d->arch.arch_vmx.cpu_state);
@@ -838,7 +839,6 @@
     switch(cr) {
     case 0: 
     {
-       __vmwrite(CR0_READ_SHADOW, value);
        return vmx_set_cr0(value);
     }
     case 3: 
@@ -848,7 +848,7 @@
         /*
          * If paging is not enabled yet, simply copy the value to CR3.
          */
-        if (!test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) {
+        if (!vmx_paging_enabled(d)) {
             d->arch.arch_vmx.cpu_cr3 = value;
             break;
         }
@@ -876,8 +876,7 @@
                  !VALID_MFN(mfn = phys_to_machine_mapping(value >> 
PAGE_SHIFT)) ||
                  !get_page(pfn_to_page(mfn), d->domain) )
             {
-                VMX_DBG_LOG(DBG_LEVEL_VMMU, 
-                        "Invalid CR3 value=%lx", value);
+                printk("Invalid CR3 value=%lx", value);
                 domain_crash_synchronous(); /* need to take a clean path */
             }
             old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
@@ -1133,6 +1131,7 @@
         VMX_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
 
     if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
+        printk("Failed vm entry\n");
         domain_crash_synchronous();         
         return;
     }
===== xen/arch/x86/vmx_io.c 1.24 vs edited =====
--- 1.24/xen/arch/x86/vmx_io.c  2005-05-16 01:41:48 -07:00
+++ edited/xen/arch/x86/vmx_io.c        2005-05-27 12:02:09 -07:00
@@ -430,7 +430,7 @@
 void vmx_do_resume(struct exec_domain *d) 
 {
     vmx_stts();
-    if ( test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state) )
+    if ( vmx_paging_enabled(d) )
         __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
     else
         // paging is not enabled in the guest
===== xen/arch/x86/vmx_platform.c 1.19 vs edited =====
--- 1.19/xen/arch/x86/vmx_platform.c    2005-05-26 20:16:05 -07:00
+++ edited/xen/arch/x86/vmx_platform.c  2005-05-27 12:02:09 -07:00
@@ -418,8 +418,12 @@
     }
 
     if ((guest_eip & PAGE_MASK) == ((guest_eip + inst_len) & PAGE_MASK)) {
-        gpte = gva_to_gpte(guest_eip);
-        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        if (vmx_paging_enabled(current)) {
+                gpte = gva_to_gpte(guest_eip);
+                mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        } else {
+                mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
+        }
         ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
         inst_start = (unsigned char *)map_domain_mem(ma);
                 
@@ -509,7 +513,7 @@
     } else
         p->count = 1;
 
-    if (pvalid)
+    if ((pvalid) && vmx_paging_enabled(current))
         p->u.pdata = (void *) gva_to_gpa(p->u.data);
 
 #if 0
===== xen/arch/x86/vmx_vmcs.c 1.25 vs edited =====
--- 1.25/xen/arch/x86/vmx_vmcs.c        2005-05-20 15:28:11 -07:00
+++ edited/xen/arch/x86/vmx_vmcs.c      2005-05-27 12:27:14 -07:00
@@ -291,7 +291,7 @@
 
     /* Initally PG, PE are not set*/
     shadow_cr = host_env->cr0;
-    shadow_cr &= ~(X86_CR0_PE | X86_CR0_PG);
+    shadow_cr &= ~X86_CR0_PG;
     error |= __vmwrite(CR0_READ_SHADOW, shadow_cr);
     /* CR3 is set in vmx_final_setup_guest */
     error |= __vmwrite(GUEST_CR4, host_env->cr4);
===== xen/arch/x86/x86_32/traps.c 1.27 vs edited =====
--- 1.27/xen/arch/x86/x86_32/traps.c    2005-05-21 03:41:05 -07:00
+++ edited/xen/arch/x86/x86_32/traps.c  2005-05-27 12:02:09 -07:00
@@ -20,8 +20,9 @@
     unsigned long ss, ds, es, fs, gs, cs;
     unsigned long eip, esp, eflags;
     const char *context;
-
 #ifdef CONFIG_VMX
+    unsigned long cr0, cr3;
+
     if ( VMX_DOMAIN(current) && (regs->eflags == 0) )
     {
         __vmread(GUEST_EIP, &eip);
@@ -33,6 +34,8 @@
         __vmread(GUEST_FS_SELECTOR, &fs);
         __vmread(GUEST_GS_SELECTOR, &gs);
         __vmread(GUEST_CS_SELECTOR, &cs);
+        __vmread(CR0_READ_SHADOW, &cr0);
+        __vmread(GUEST_CR3, &cr3);
         context = "vmx guest";
     }
     else
@@ -77,6 +80,9 @@
     printk("ds: %04lx   es: %04lx   fs: %04lx   gs: %04lx   "
            "ss: %04lx   cs: %04lx\n",
            ds, es, fs, gs, ss, cs);
+#ifdef CONFIG_VMX
+    printk("cr0: %08lx   cr3: %08lx\n", cr0, cr3);
+#endif
 
     if ( GUEST_MODE(regs) )
         show_guest_stack();
===== xen/include/asm-x86/shadow.h 1.97 vs edited =====
--- 1.97/xen/include/asm-x86/shadow.h   2005-05-25 10:29:18 -07:00
+++ edited/xen/include/asm-x86/shadow.h 2005-05-27 12:02:11 -07:00
@@ -31,6 +31,9 @@
 #include <asm/processor.h>
 #include <asm/domain_page.h>
 #include <public/dom0_ops.h>
+#ifdef CONFIG_VMX
+#include <asm/vmx.h>
+#endif
 
 /* Shadow PT operation mode : shadow-mode variable in arch_domain. */
 
@@ -1672,8 +1675,8 @@
 
 #ifdef CONFIG_VMX
     if ( VMX_DOMAIN(ed) )
-        paging_enabled =
-            test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
+        paging_enabled = vmx_paging_enabled(ed);
+            
     else
 #endif
         // HACK ALERT: there's currently no easy way to figure out if a domU
===== xen/include/asm-x86/vmx.h 1.8 vs edited =====
--- 1.8/xen/include/asm-x86/vmx.h       2005-05-17 15:28:11 -07:00
+++ edited/xen/include/asm-x86/vmx.h    2005-05-27 12:02:11 -07:00
@@ -294,5 +294,14 @@
     if (!(cr0 & X86_CR0_TS))
        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
- 
+
+/* Works only for ed == current */
+static inline int vmx_paging_enabled(struct exec_domain *ed)
+{
+    unsigned long cr0;
+
+    __vmread(CR0_READ_SHADOW, &cr0);
+    return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+}
+
 #endif /* __ASM_X86_VMX_H__ */
===== xen/include/asm-x86/vmx_vmcs.h 1.11 vs edited =====
--- 1.11/xen/include/asm-x86/vmx_vmcs.h 2005-05-26 20:16:05 -07:00
+++ edited/xen/include/asm-x86/vmx_vmcs.h       2005-05-27 12:02:11 -07:00
@@ -29,7 +29,6 @@
 
 void vmx_enter_scheduler(void);
 
-#define VMX_CPU_STATE_PG_ENABLED        0       
 #define        VMX_CPU_STATE_ASSIST_ENABLED    1
 
 struct vmcs_struct {

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] vmx-worldswitch-1-to-1.patch, Arun Sharma <=