diff options
-rw-r--r-- | arch/x86/include/asm/lguest.h | 7 | ||||
-rw-r--r-- | drivers/lguest/core.c | 9 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 2 | ||||
-rw-r--r-- | drivers/lguest/page_tables.c | 21 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 5 |
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 | ||
17 | void free_pagetables(void); | 17 | void free_pagetables(void); |
18 | int init_pagetables(struct page **switcher_pages, unsigned int pages); | 18 | int init_pagetables(struct page **switcher_pages); |
19 | 19 | ||
20 | struct pgdir { | 20 | struct 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 | */ |
1086 | static __init void populate_switcher_pte_page(unsigned int cpu, | 1084 | static __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) */ |
66 | static struct lguest_pages *lguest_pages(unsigned int cpu) | 66 | static 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 | ||
72 | static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu); | 71 | static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu); |