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] kexec is not highmem-aware

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [patch] kexec is not highmem-aware
From: "Stephen C. Tweedie" <sct@xxxxxxxxxx>
Date: Mon, 18 Jun 2007 15:29:17 +0100
Cc: Stephen Tweedie <sct@xxxxxxxxxx>, Gerd Hoffmann <kraxel@xxxxxxxxxx>
Delivery-date: Mon, 18 Jun 2007 07:27:27 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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>
Organization: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Hi,

The current 2.6.18-xen tree's kexec seems to be working for me OK on
x86_64 and on small i686 boxes, but it is broken on >1GB 32-bit
configurations, oopsing when the kexec kernel is set up with:

        BUG: unable to handle kernel NULL pointer dereference at virtual 
address 00000000
        ...
        CPU:    0
        EIP:    0061:[<c0415550>]    Not tainted VLI
        EFLAGS: 00010216   (2.6.18-20.el5.kraxel.7xen #1) 
        EIP is at xen_create_contiguous_region+0x9c/0x44b
        eax: 00000000   ebx: 00001000   ecx: 00000400   edx: 00000000
        esi: 0000000b   edi: 00000000   ebp: 00000001   esp: ea292e90
        ds: 007b   es: 007b   ss: 0069
        Process kexec (pid: 2439, ti=ea292000 task=ea577aa0 task.ti=ea292000)
        ...
        Call Trace:
         [<c044ac8f>] get_page_from_freelist+0x1c1/0x325
         [<c044fc72>] page_address+0x7a/0x81
         [<c0438f04>] kimage_alloc_pages+0x64/0xa2
         [<c0438fdf>] kimage_alloc_page+0x9d/0x2a5
         [<c0439226>] kimage_add_entry+0x3f/0xbd
         [<c0439780>] sys_kexec_load+0x2a0/0x3f7
         [<c040534f>] syscall_call+0x7/0xb
         =======================

I'm using the kexec code back-ported to the RHEL-5 kernel atm, but
current xen-unstable.hg appears to have the same problem.

The problem is in kimage_alloc_pages(), which tries to return contiguous
pages by calling 

        xen_create_contiguous_region((unsigned long)page_address(pages),
                                         order, address_bits)

on the pages allocated.  Unfortunately, page_address() returns NULL for
highmem pages.  So as soon as we try this on a page in the highmem heap,
we get the above OOPS.

Fortunately it's easy to fix: we don't need to call
xen_create_contiguous_region() on highmem pages, because the only place
I can see in kexec which uses GFP_HIGHMEM also allocates only single
pages at a time (and those are by definition always contiguous anyway!)

So we really only need to call xen_(create|destroy)_contiguous_region()
if order>0.  That will continue to do the right thing for lowmem high-
order allocations, while allowing single-page GFP_HIGHEM allocations to
work.

The patch below fixes this for me.

--Stephen

Don't try to call xen_create_contiguous_region() on highmem pages.  It
won't work --- page_address() returns NULL on such pages --- but is also
unnecesary because the only place in kexec which uses GFP_HIGHMEM also
allocates only single pages at a time (and those are by definition
always contiguous anyway.)

So we really only need to call xen_(create|destroy)_contiguous_region()
if order>0.  That will continue to do the right thing for lowmem
high-order allocations, while allowing single-page GFP_HIGHEM
allocations to work.

Signed-off-by: Stephen Tweedie <sct@xxxxxxxxxx>


--- linux-2.6.18.noarch/kernel/kexec.c.=K0010=.orig
+++ linux-2.6.18.noarch/kernel/kexec.c
@@ -345,10 +345,13 @@ static struct page *kimage_alloc_pages(g
                else
                        address_bits = long_log2(limit);
 
-               if (xen_create_contiguous_region((unsigned 
long)page_address(pages),
-                                                order, address_bits) < 0) {
-                       __free_pages(pages, order);
-                       return NULL;
+               if (order > 0) {
+                       BUG_ON(gfp_mask & __GFP_HIGHMEM);
+                       if (xen_create_contiguous_region((unsigned 
long)page_address(pages),
+                                                        order, address_bits) < 
0) {
+                               __free_pages(pages, order);
+                               return NULL;
+                       }
                }
 #endif
                pages->mapping = NULL;
@@ -370,7 +373,8 @@ static void kimage_free_pages(struct pag
        for (i = 0; i < count; i++)
                ClearPageReserved(page + i);
 #ifdef CONFIG_XEN
-       xen_destroy_contiguous_region((unsigned long)page_address(page), order);
+       if (order > 0)
+               xen_destroy_contiguous_region((unsigned 
long)page_address(page), order);
 #endif
        __free_pages(page, order);
 }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>