[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] PAE patches / hypercall interface changes


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Gerd Knorr <kraxel@xxxxxxx>
  • Date: Wed, 8 Jun 2005 17:21:55 +0200
  • Delivery-date: Wed, 08 Jun 2005 15:24:11 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

  Hi,

New PAE patchset (#13) has been uploaded to 
http://dl.bytesex.org/patches/

The hypercall interface has been updated to pass around
64bit-wide page table entries now.

The xen patch is here:

==============================[ cut here ]==============================
--- xen.orig/include/public/xen.h       2005-06-08 11:39:05.000000000 +0200
+++ xen/include/public/xen.h    2005-06-08 12:08:24.000000000 +0200
@@ -270,8 +270,8 @@ typedef u16 domid_t;
  */
 typedef struct
 {
-    memory_t ptr;       /* Machine address of PTE. */
-    memory_t val;       /* New contents of PTE.    */
+    u64 ptr;       /* Machine address of PTE. */
+    u64 val;       /* New contents of PTE.    */
 } mmu_update_t;
 
 /*
--- xen.orig/arch/x86/mm.c      2005-06-08 11:42:11.000000000 +0200
+++ xen/arch/x86/mm.c   2005-06-08 12:12:13.000000000 +0200
@@ -2023,7 +2023,8 @@ int do_mmu_update(
             }
 
             va = map_domain_page_with_cache(mfn, &mapcache);
-            va = (void *)((unsigned long)va + (req.ptr & ~PAGE_MASK));
+            va = (void *)((unsigned long)va +
+                          (unsigned long)(req.ptr & ~PAGE_MASK));
             page = &frame_table[mfn];
 
             switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
@@ -2167,7 +2168,7 @@ int do_mmu_update(
             break;
 
         default:
-            MEM_LOG("Invalid page update command %lx", req.ptr);
+            MEM_LOG("Invalid page update command %x", cmd);
             break;
         }
 
@@ -2254,11 +2255,10 @@ int update_grant_va_mapping(unsigned lon
 }
 
 
-int do_update_va_mapping(unsigned long va,
-                         unsigned long val32,
+int do_update_va_mapping(unsigned long va, u64 val64,
                          unsigned long flags)
 {
-    l1_pgentry_t   val = l1e_from_intpte(val32);
+    l1_pgentry_t   val = l1e_from_intpte(val64);
     struct vcpu   *v   = current;
     struct domain *d   = v->domain;
     unsigned int   cpu = v->processor;
@@ -2352,8 +2352,7 @@ int do_update_va_mapping(unsigned long v
     return rc;
 }
 
-int do_update_va_mapping_otherdomain(unsigned long va,
-                                     unsigned long val32,
+int do_update_va_mapping_otherdomain(unsigned long va, u64 val64,
                                      unsigned long flags,
                                      domid_t domid)
 {
@@ -2371,7 +2370,7 @@ int do_update_va_mapping_otherdomain(uns
         return -ESRCH;
     }
 
-    rc = do_update_va_mapping(va, val32, flags);
+    rc = do_update_va_mapping(va, val64, flags);
 
     return rc;
 }
==============================[ cut here ]==============================

xenlinux 2.6.x needs these changes (also take care that xenlinux
uses the updated xen/include/public/xen.h from the patch above).

==============================[ cut here ]==============================
--- linux-2.6.11.orig/include/asm-xen/asm-i386/hypercall.h      2005-06-08 
12:39:16.000000000 +0200
+++ linux-2.6.11/include/asm-xen/asm-i386/hypercall.h   2005-06-08 
13:01:04.000000000 +0200
@@ -371,13 +371,19 @@ HYPERVISOR_update_va_mapping(
     unsigned long va, pte_t new_val, unsigned long flags)
 {
     int ret;
-    unsigned long ign1, ign2, ign3;
+    unsigned long ign1, ign2, ign3, ign4;
 
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
        : "0" (__HYPERVISOR_update_va_mapping), 
-          "1" (va), "2" ((new_val).pte_low), "3" (flags)
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
+#else
+         "3" (0),
+#endif
+         "4" (flags)
        : "memory" );
 
     if ( unlikely(ret < 0) )
@@ -473,13 +479,20 @@ HYPERVISOR_update_va_mapping_otherdomain
     unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
 {
     int ret;
-    unsigned long ign1, ign2, ign3, ign4;
+    unsigned long ign1, ign2, ign3, ign4, ign5;
 
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
+         "=S" (ign4), "=D" (ign5)
        : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
-          "1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
+#else
+         "3" (0),
+#endif
+         "4" (flags), "5" (domid) :
         "memory" );
     
     return ret;
==============================[ cut here ]==============================

Comments?  Domain0 boots fine.  Other guest OS'es are not
updated yet, tools also not updated yet.


The recent PAE cleanups by Keir which added a new sanity check
prevent the current xenlinux kernel from booting in PAE mode.
I've disabled that for now to make it boot again:

==============================[ cut here ]==============================
--- xen.orig/arch/x86/mm.c      2005-06-08 16:25:03.000000000 +0200
+++ xen/arch/x86/mm.c   2005-06-08 16:25:44.000000000 +0200
@@ -716,8 +716,8 @@ static int create_pae_xen_mappings(l3_pg
     BUG_ON((page->u.inuse.type_info & PGT_count_mask) == 0);
     if ( (page->u.inuse.type_info & PGT_count_mask) != 1 )
     {
-        MEM_LOG("PAE L3 3rd slot is shared");
-        return 0;
+        MEM_LOG("WARNING: PAE L3 3rd slot is shared");
+//        return 0;
     }
 
     /* Xen private mappings. */
==============================[ cut here ]==============================

The xenlinux kernel does that exactly once at boot time, when
initializing swapper_pg_dir.  Happens in arch/xen/i386/mm/init.c:

static void __init pagetable_init (void)
{
        unsigned long vaddr;
        pgd_t *pgd_base = swapper_pg_dir;
        pgd_t *old_pgd = (pgd_t *)xen_start_info.pt_base;
[ ... ]
        memcpy(pgd_base, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
        make_page_readonly(pgd_base);
        xen_pgd_pin(__pa(pgd_base));      <= here it blows up
        load_cr3(pgd_base);
        xen_pgd_unpin(__pa(old_pgd));
        make_page_writable(old_pgd);
[ ... ]
}

What this check is needed for?  Is there some reason why xen
must do that?  Or is this just to catch bugs in the guest OS
kernel?  

  Gerd


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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.