lguest: prepare to make SWITCHER_ADDR a variable.
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 22 Apr 2013 04:40:37 +0000 (14:10 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 22 Apr 2013 06:01:33 +0000 (15:31 +0930)
We currently use the whole top PGD entry for the switcher, but that's
hitting the fixmap in some configurations (mainly, large NR_CPUS).
Introduce a variable, currently set to the constant.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
arch/x86/include/asm/lguest.h
drivers/lguest/core.c
drivers/lguest/x86/core.c

index 0d97deb..85ecdb8 100644 (file)
@@ -23,6 +23,8 @@
 #else
 #define SWITCHER_ADDR 0xFFC00000
 #endif
+/* Where we map the Switcher, in both Host and Guest. */
+extern unsigned long switcher_addr;
 
 /* Found in switcher.S */
 extern unsigned long default_idt_entries[];
index a5ebc00..0992523 100644 (file)
@@ -20,7 +20,7 @@
 #include <asm/asm-offsets.h>
 #include "lg.h"
 
-
+unsigned long switcher_addr;
 static struct vm_struct *switcher_vma;
 static struct page **switcher_page;
 
@@ -75,25 +75,27 @@ static __init int map_switcher(void)
                }
        }
 
+       switcher_addr = SWITCHER_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){
+       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.  The end address needs +1 because __get_vm_area
-        * allocates an extra guard page, so we need space for that.
+        * Now we reserve the "virtual memory area" we want.  We might
+        * not get it in theory, but in practice 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, SWITCHER_ADDR
+                                    VM_ALLOC, switcher_addr, switcher_addr
                                     + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
        if (!switcher_vma) {
                err = -ENOMEM;
@@ -103,7 +105,7 @@ static __init int map_switcher(void)
 
        /*
         * This code actually sets up the pages we've allocated to appear at
-        * SWITCHER_ADDR.  map_vm_area() takes the vma we allocated above, the
+        * switcher_addr.  map_vm_area() takes the vma we allocated above, the
         * kind of pages we're mapping (kernel pages), and a pointer to our
         * array of struct pages.  It increments that pointer, but we don't
         * care.
index 4af12e1..20fae76 100644 (file)
@@ -59,14 +59,14 @@ static struct {
 /* Offset from where switcher.S was compiled to where we've copied it */
 static unsigned long switcher_offset(void)
 {
-       return SWITCHER_ADDR - (unsigned long)start_switcher_text;
+       return switcher_addr - (unsigned long)start_switcher_text;
 }
 
 /* This cpu's struct lguest_pages. */
 static struct lguest_pages *lguest_pages(unsigned int cpu)
 {
        return &(((struct lguest_pages *)
-                 (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
+                 (switcher_addr + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
 }
 
 static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu);