lguest: fix __get_vm_area usage.
Rusty Russell [Tue, 11 Mar 2008 14:35:56 +0000 (09:35 -0500)]
Robert Bragg's 5dc331852848a38ca00a2817e5b98a1d0561b116 tightened
(ie. fixed) the checking in __get_vm_area, and it broke lguest.

lguest should pass the exact "end" it wants, not some random constant
(it was possible previously that it would actually get an address
different from SWITCHER_ADDR).

Also, Fabio Checconi pointed out that we should make sure we're not
hitting the fixmap area.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Robert Bragg <robert@sixbynine.org>

drivers/lguest/core.c

index 7743d73..c632c08 100644 (file)
@@ -69,11 +69,22 @@ static __init int map_switcher(void)
                switcher_page[i] = virt_to_page(addr);
        }
 
+       /* First we check that the Switcher won't overlap the fixmap area at
+        * the top of memory.  It's currently nowhere near, but it could have
+        * very strange effects if it ever happened. */
+       if (SWITCHER_ADDR + (TOTAL_SWITCHER_PAGES+1)*PAGE_SIZE > FIXADDR_START){
+               err = -ENOMEM;
+               printk("lguest: mapping switcher would thwack fixmap\n");
+               goto free_pages;
+       }
+
        /* Now we reserve the "virtual memory area" we want: 0xFFC00000
         * (SWITCHER_ADDR).  We might not get it in theory, but in practice
-        * it's worked so far. */
+        * it's worked so far.  The end address needs +1 because __get_vm_area
+        * allocates an extra guard page, so we need space for that. */
        switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
-                                      VM_ALLOC, SWITCHER_ADDR, VMALLOC_END);
+                                    VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
+                                    + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
        if (!switcher_vma) {
                err = -ENOMEM;
                printk("lguest: could not map switcher pages high\n");