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

[Xen-devel] [PATCH] Fix >4G i386 PAE grant table interface



It has been discovered that i386 boxes with more than 4G of RAM would randomly crash. It was traced to the interface of blktap using gnttab_set_map_op.

It would pass in the 64 bit pte entry, but the gnttab_set_map_op would only take a 32 bit (on i386) unsigned long as a parameter. So we lose the top 32bits.

Luckily! The kernel/HV ABI used a uint64_t as the variable to pass the address. So this does *NOT* break the current kernel/HV ABI.

But after the HV grabs the 64 bit address from the guest, it too calls a function that uses a unsigned long (32bits on i386) to pass that address with. So the HV side also chops off the top 64 bits of the variable.


This patch updates both the linux-2.6-sparse tree and the xen HV to use uint64_t instead of unsigned long for those particular functions. This patch has been tested on RHEL5 Beta on a box with 12G i386.

Signed-off-by: Steven Rostedt <srostedt@xxxxxxxxxx>
diff -r 874cc0ff214d linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Wed Nov 01 09:55:43 2006 +0000
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Thu Nov 02 11:36:12 2006 -0500
@@ -118,7 +118,7 @@ int gnttab_resume(void);
 int gnttab_resume(void);
 
 static inline void
-gnttab_set_map_op(struct gnttab_map_grant_ref *map, unsigned long addr,
+gnttab_set_map_op(struct gnttab_map_grant_ref *map, uint64_t addr,
                  uint32_t flags, grant_ref_t ref, domid_t domid)
 {
        if (flags & GNTMAP_contains_pte)
@@ -134,7 +134,7 @@ gnttab_set_map_op(struct gnttab_map_gran
 }
 
 static inline void
-gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, unsigned long addr,
+gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, uint64_t addr,
                    uint32_t flags, grant_handle_t handle)
 {
        if (flags & GNTMAP_contains_pte)
diff -r 874cc0ff214d xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Wed Nov 01 09:55:43 2006 +0000
+++ b/xen/arch/powerpc/mm.c     Thu Nov 02 11:36:12 2006 -0500
@@ -43,14 +43,14 @@ unsigned long total_pages;
 unsigned long total_pages;
 
 int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags)
+    uint64_t addr, unsigned long frame, unsigned int flags)
 {
     panic("%s called\n", __func__);
     return 1;
 }
 
 int destroy_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags)
+    uint64_t addr, unsigned long frame, unsigned int flags)
 {
     panic("%s called\n", __func__);
     return 1;
diff -r 874cc0ff214d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Nov 01 09:55:43 2006 +0000
+++ b/xen/arch/x86/mm.c Thu Nov 02 11:36:12 2006 -0500
@@ -2379,7 +2379,7 @@ int do_mmu_update(
 
 
 static int create_grant_pte_mapping(
-    unsigned long pte_addr, l1_pgentry_t nl1e, struct vcpu *v)
+    uint64_t pte_addr, l1_pgentry_t nl1e, struct vcpu *v)
 {
     int rc = GNTST_okay;
     void *va;
@@ -2403,7 +2403,7 @@ static int create_grant_pte_mapping(
     }
     
     va = map_domain_page(mfn);
-    va = (void *)((unsigned long)va + (pte_addr & ~PAGE_MASK));
+    va = (void *)((unsigned long)va + ((unsigned long)pte_addr & ~PAGE_MASK));
     page = mfn_to_page(mfn);
 
     type = page->u.inuse.type_info & PGT_type_mask;
@@ -2435,7 +2435,7 @@ static int create_grant_pte_mapping(
 }
 
 static int destroy_grant_pte_mapping(
-    unsigned long addr, unsigned long frame, struct domain *d)
+    uint64_t addr, unsigned long frame, struct domain *d)
 {
     int rc = GNTST_okay;
     void *va;
@@ -2454,7 +2454,7 @@ static int destroy_grant_pte_mapping(
     }
     
     va = map_domain_page(mfn);
-    va = (void *)((unsigned long)va + (addr & ~PAGE_MASK));
+    va = (void *)((unsigned long)va + ((unsigned long)addr & ~PAGE_MASK));
     page = mfn_to_page(mfn);
 
     type = page->u.inuse.type_info & PGT_type_mask;
@@ -2475,7 +2475,7 @@ static int destroy_grant_pte_mapping(
     /* Check that the virtual address supplied is actually mapped to frame. */
     if ( unlikely((l1e_get_intpte(ol1e) >> PAGE_SHIFT) != frame) )
     {
-        MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
+        MEM_LOG("PTE entry %lx for address %llx doesn't match frame %lx",
                 (unsigned long)l1e_get_intpte(ol1e), addr, frame);
         put_page_type(page);
         rc = GNTST_general_error;
@@ -2575,7 +2575,7 @@ static int destroy_grant_va_mapping(
 }
 
 int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags)
+    uint64_t addr, unsigned long frame, unsigned int flags)
 {
     l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
 
@@ -2590,7 +2590,7 @@ int create_grant_host_mapping(
 }
 
 int destroy_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags)
+    uint64_t addr, unsigned long frame, unsigned int flags)
 {
     if ( flags & GNTMAP_contains_pte )
         return destroy_grant_pte_mapping(addr, frame, current->domain);
diff -r 874cc0ff214d xen/include/asm-powerpc/grant_table.h
--- a/xen/include/asm-powerpc/grant_table.h     Wed Nov 01 09:55:43 2006 +0000
+++ b/xen/include/asm-powerpc/grant_table.h     Thu Nov 02 11:36:12 2006 -0500
@@ -30,9 +30,9 @@
  * must hold a reference to the page.
  */
 int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags);
+    uint64_t addr, unsigned long frame, unsigned int flags);
 int destroy_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags);
+    uint64_t addr, unsigned long frame, unsigned int flags);
 
 #define gnttab_create_shared_page(d, t, i)                               \
     do {                                                                 \
diff -r 874cc0ff214d xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Wed Nov 01 09:55:43 2006 +0000
+++ b/xen/include/asm-x86/grant_table.h Thu Nov 02 11:36:12 2006 -0500
@@ -14,9 +14,9 @@
  * must hold a reference to the page.
  */
 int create_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags);
+    uint64_t addr, unsigned long frame, unsigned int flags);
 int destroy_grant_host_mapping(
-    unsigned long addr, unsigned long frame, unsigned int flags);
+    uint64_t addr, unsigned long frame, unsigned int flags);
 
 #define gnttab_create_shared_page(d, t, i)                               \
     do {                                                                 \
_______________________________________________
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®.