aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/lguest.h7
-rw-r--r--drivers/lguest/core.c9
-rw-r--r--drivers/lguest/lg.h2
-rw-r--r--drivers/lguest/page_tables.c21
-rw-r--r--drivers/lguest/x86/core.c5
5 files changed, 21 insertions, 23 deletions
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index 85ecdb80d121..74edebd010ab 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -11,11 +11,8 @@
11 11
12#define GUEST_PL 1 12#define GUEST_PL 1
13 13
14/* Every guest maps the core switcher code. */ 14/* Page for Switcher text itself, then two pages per cpu */
15#define SHARED_SWITCHER_PAGES \ 15#define TOTAL_SWITCHER_PAGES (1 + 2 * nr_cpu_ids)
16 DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE)
17/* Pages for switcher itself, then two pages per cpu */
18#define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * nr_cpu_ids)
19 16
20/* We map at -4M (-2M for PAE) for ease of mapping (one PTE page). */ 17/* We map at -4M (-2M for PAE) for ease of mapping (one PTE page). */
21#ifdef CONFIG_X86_PAE 18#ifdef CONFIG_X86_PAE
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 211d8267992b..4209065b9b1e 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -52,6 +52,13 @@ static __init int map_switcher(void)
52 * easy. 52 * easy.
53 */ 53 */
54 54
55 /* We assume Switcher text fits into a single page. */
56 if (end_switcher_text - start_switcher_text > PAGE_SIZE) {
57 printk(KERN_ERR "lguest: switcher text too large (%zu)\n",
58 end_switcher_text - start_switcher_text);
59 return -EINVAL;
60 }
61
55 /* 62 /*
56 * We allocate an array of struct page pointers. map_vm_area() wants 63 * We allocate an array of struct page pointers. map_vm_area() wants
57 * this, rather than just an array of pages. 64 * this, rather than just an array of pages.
@@ -326,7 +333,7 @@ static int __init init(void)
326 goto out; 333 goto out;
327 334
328 /* Now we set up the pagetable implementation for the Guests. */ 335 /* Now we set up the pagetable implementation for the Guests. */
329 err = init_pagetables(switcher_pages, SHARED_SWITCHER_PAGES); 336 err = init_pagetables(switcher_pages);
330 if (err) 337 if (err)
331 goto unmap; 338 goto unmap;
332 339
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 8bf68c54ff7f..4c3e532d50d6 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -15,7 +15,7 @@
15#include <asm/lguest.h> 15#include <asm/lguest.h>
16 16
17void free_pagetables(void); 17void free_pagetables(void);
18int init_pagetables(struct page **switcher_pages, unsigned int pages); 18int init_pagetables(struct page **switcher_pages);
19 19
20struct pgdir { 20struct pgdir {
21 unsigned long gpgdir; 21 unsigned long gpgdir;
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 21685580eb9f..758466299b0d 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -1079,25 +1079,20 @@ static void free_switcher_pte_pages(void)
1079 1079
1080/*H:520 1080/*H:520
1081 * Setting up the Switcher PTE page for given CPU is fairly easy, given 1081 * Setting up the Switcher PTE page for given CPU is fairly easy, given
1082 * the CPU number and the "struct page"s for the Switcher code itself. 1082 * the CPU number and the "struct page"s for the Switcher and per-cpu pages.
1083 *
1084 * Currently the Switcher is less than a page long, so "pages" is always 1.
1085 */ 1083 */
1086static __init void populate_switcher_pte_page(unsigned int cpu, 1084static __init void populate_switcher_pte_page(unsigned int cpu,
1087 struct page *switcher_pages[], 1085 struct page *switcher_pages[])
1088 unsigned int pages)
1089{ 1086{
1090 unsigned int i;
1091 pte_t *pte = switcher_pte_page(cpu); 1087 pte_t *pte = switcher_pte_page(cpu);
1088 int i;
1092 1089
1093 /* The first entries are easy: they map the Switcher code. */ 1090 /* The first entries maps the Switcher code. */
1094 for (i = 0; i < pages; i++) { 1091 set_pte(&pte[0], mk_pte(switcher_pages[0],
1095 set_pte(&pte[i], mk_pte(switcher_pages[i],
1096 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); 1092 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)));
1097 }
1098 1093
1099 /* The only other thing we map is this CPU's pair of pages. */ 1094 /* The only other thing we map is this CPU's pair of pages. */
1100 i = pages + cpu*2; 1095 i = 1 + cpu*2;
1101 1096
1102 /* First page (Guest registers) is writable from the Guest */ 1097 /* First page (Guest registers) is writable from the Guest */
1103 set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_pages[i]), 1098 set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_pages[i]),
@@ -1128,7 +1123,7 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
1128 * At boot or module load time, init_pagetables() allocates and populates 1123 * At boot or module load time, init_pagetables() allocates and populates
1129 * the Switcher PTE page for each CPU. 1124 * the Switcher PTE page for each CPU.
1130 */ 1125 */
1131__init int init_pagetables(struct page **switcher_pages, unsigned int pages) 1126__init int init_pagetables(struct page **switcher_pages)
1132{ 1127{
1133 unsigned int i; 1128 unsigned int i;
1134 1129
@@ -1138,7 +1133,7 @@ __init int init_pagetables(struct page **switcher_pages, unsigned int pages)
1138 free_switcher_pte_pages(); 1133 free_switcher_pte_pages();
1139 return -ENOMEM; 1134 return -ENOMEM;
1140 } 1135 }
1141 populate_switcher_pte_page(i, switcher_pages, pages); 1136 populate_switcher_pte_page(i, switcher_pages);
1142 } 1137 }
1143 return 0; 1138 return 0;
1144} 1139}
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 20fae765d600..f0a3347b6441 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -62,11 +62,10 @@ static unsigned long switcher_offset(void)
62 return switcher_addr - (unsigned long)start_switcher_text; 62 return switcher_addr - (unsigned long)start_switcher_text;
63} 63}
64 64
65/* This cpu's struct lguest_pages. */ 65/* This cpu's struct lguest_pages (after the Switcher text page) */
66static struct lguest_pages *lguest_pages(unsigned int cpu) 66static struct lguest_pages *lguest_pages(unsigned int cpu)
67{ 67{
68 return &(((struct lguest_pages *) 68 return &(((struct lguest_pages *)(switcher_addr + PAGE_SIZE))[cpu]);
69 (switcher_addr + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
70} 69}
71 70
72static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu); 71static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu);