aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest')
-rw-r--r--drivers/lguest/core.c5
-rw-r--r--drivers/lguest/page_tables.c45
2 files changed, 21 insertions, 29 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 1e2cb846b3c9..8744d24ac6e6 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -67,12 +67,11 @@ static __init int map_switcher(void)
67 * so we make sure they're zeroed. 67 * so we make sure they're zeroed.
68 */ 68 */
69 for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) { 69 for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) {
70 unsigned long addr = get_zeroed_page(GFP_KERNEL); 70 switcher_page[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
71 if (!addr) { 71 if (!switcher_page[i]) {
72 err = -ENOMEM; 72 err = -ENOMEM;
73 goto free_some_pages; 73 goto free_some_pages;
74 } 74 }
75 switcher_page[i] = virt_to_page(addr);
76 } 75 }
77 76
78 /* 77 /*
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 8aaad65c3bb5..cf94326f1b59 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -380,7 +380,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
380 * And we copy the flags to the shadow PMD entry. The page 380 * And we copy the flags to the shadow PMD entry. The page
381 * number in the shadow PMD is the page we just allocated. 381 * number in the shadow PMD is the page we just allocated.
382 */ 382 */
383 native_set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); 383 set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd)));
384 } 384 }
385 385
386 /* 386 /*
@@ -447,7 +447,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
447 * we will come back here when a write does actually occur, so 447 * we will come back here when a write does actually occur, so
448 * we can update the Guest's _PAGE_DIRTY flag. 448 * we can update the Guest's _PAGE_DIRTY flag.
449 */ 449 */
450 native_set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); 450 set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0));
451 451
452 /* 452 /*
453 * Finally, we write the Guest PTE entry back: we've set the 453 * Finally, we write the Guest PTE entry back: we've set the
@@ -528,7 +528,7 @@ static void release_pmd(pmd_t *spmd)
528 /* Now we can free the page of PTEs */ 528 /* Now we can free the page of PTEs */
529 free_page((long)ptepage); 529 free_page((long)ptepage);
530 /* And zero out the PMD entry so we never release it twice. */ 530 /* And zero out the PMD entry so we never release it twice. */
531 native_set_pmd(spmd, __pmd(0)); 531 set_pmd(spmd, __pmd(0));
532 } 532 }
533} 533}
534 534
@@ -833,15 +833,15 @@ static void do_set_pte(struct lg_cpu *cpu, int idx,
833 */ 833 */
834 if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) { 834 if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
835 check_gpte(cpu, gpte); 835 check_gpte(cpu, gpte);
836 native_set_pte(spte, 836 set_pte(spte,
837 gpte_to_spte(cpu, gpte, 837 gpte_to_spte(cpu, gpte,
838 pte_flags(gpte) & _PAGE_DIRTY)); 838 pte_flags(gpte) & _PAGE_DIRTY));
839 } else { 839 } else {
840 /* 840 /*
841 * Otherwise kill it and we can demand_page() 841 * Otherwise kill it and we can demand_page()
842 * it in later. 842 * it in later.
843 */ 843 */
844 native_set_pte(spte, __pte(0)); 844 set_pte(spte, __pte(0));
845 } 845 }
846#ifdef CONFIG_X86_PAE 846#ifdef CONFIG_X86_PAE
847 } 847 }
@@ -983,25 +983,22 @@ static unsigned long setup_pagetables(struct lguest *lg,
983 */ 983 */
984 for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD; 984 for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD;
985 i += PTRS_PER_PTE, j++) { 985 i += PTRS_PER_PTE, j++) {
986 /* FIXME: native_set_pmd is overkill here. */ 986 pmd = pfn_pmd(((unsigned long)&linear[i] - mem_base)/PAGE_SIZE,
987 native_set_pmd(&pmd, __pmd(((unsigned long)(linear + i) 987 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER));
988 - mem_base) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER));
989 988
990 if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0) 989 if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0)
991 return -EFAULT; 990 return -EFAULT;
992 } 991 }
993 992
994 /* One PGD entry, pointing to that PMD page. */ 993 /* One PGD entry, pointing to that PMD page. */
995 set_pgd(&pgd, __pgd(((u32)pmds - mem_base) | _PAGE_PRESENT)); 994 pgd = __pgd(((unsigned long)pmds - mem_base) | _PAGE_PRESENT);
996 /* Copy it in as the first PGD entry (ie. addresses 0-1G). */ 995 /* Copy it in as the first PGD entry (ie. addresses 0-1G). */
997 if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0) 996 if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0)
998 return -EFAULT; 997 return -EFAULT;
999 /* 998 /*
1000 * And the third PGD entry (ie. addresses 3G-4G). 999 * And the other PGD entry to make the linear mapping at PAGE_OFFSET
1001 *
1002 * FIXME: This assumes that PAGE_OFFSET for the Guest is 0xC0000000.
1003 */ 1000 */
1004 if (copy_to_user(&pgdir[3], &pgd, sizeof(pgd)) != 0) 1001 if (copy_to_user(&pgdir[KERNEL_PGD_BOUNDARY], &pgd, sizeof(pgd)))
1005 return -EFAULT; 1002 return -EFAULT;
1006#else 1003#else
1007 /* 1004 /*
@@ -1141,15 +1138,13 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
1141{ 1138{
1142 pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); 1139 pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
1143 pte_t regs_pte; 1140 pte_t regs_pte;
1144 unsigned long pfn;
1145 1141
1146#ifdef CONFIG_X86_PAE 1142#ifdef CONFIG_X86_PAE
1147 pmd_t switcher_pmd; 1143 pmd_t switcher_pmd;
1148 pmd_t *pmd_table; 1144 pmd_t *pmd_table;
1149 1145
1150 /* FIXME: native_set_pmd is overkill here. */ 1146 switcher_pmd = pfn_pmd(__pa(switcher_pte_page) >> PAGE_SHIFT,
1151 native_set_pmd(&switcher_pmd, pfn_pmd(__pa(switcher_pte_page) >> 1147 PAGE_KERNEL_EXEC);
1152 PAGE_SHIFT, PAGE_KERNEL_EXEC));
1153 1148
1154 /* Figure out where the pmd page is, by reading the PGD, and converting 1149 /* Figure out where the pmd page is, by reading the PGD, and converting
1155 * it to a virtual address. */ 1150 * it to a virtual address. */
@@ -1157,7 +1152,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
1157 pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX]) 1152 pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX])
1158 << PAGE_SHIFT); 1153 << PAGE_SHIFT);
1159 /* Now write it into the shadow page table. */ 1154 /* Now write it into the shadow page table. */
1160 native_set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd); 1155 set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd);
1161#else 1156#else
1162 pgd_t switcher_pgd; 1157 pgd_t switcher_pgd;
1163 1158
@@ -1179,10 +1174,8 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
1179 * page is already mapped there, we don't have to copy them out 1174 * page is already mapped there, we don't have to copy them out
1180 * again. 1175 * again.
1181 */ 1176 */
1182 pfn = __pa(cpu->regs_page) >> PAGE_SHIFT; 1177 regs_pte = pfn_pte(__pa(cpu->regs_page) >> PAGE_SHIFT, PAGE_KERNEL);
1183 native_set_pte(&regs_pte, pfn_pte(pfn, PAGE_KERNEL)); 1178 set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], regs_pte);
1184 native_set_pte(&switcher_pte_page[pte_index((unsigned long)pages)],
1185 regs_pte);
1186} 1179}
1187/*:*/ 1180/*:*/
1188 1181
@@ -1209,7 +1202,7 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
1209 1202
1210 /* The first entries are easy: they map the Switcher code. */ 1203 /* The first entries are easy: they map the Switcher code. */
1211 for (i = 0; i < pages; i++) { 1204 for (i = 0; i < pages; i++) {
1212 native_set_pte(&pte[i], mk_pte(switcher_page[i], 1205 set_pte(&pte[i], mk_pte(switcher_page[i],
1213 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); 1206 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)));
1214 } 1207 }
1215 1208
@@ -1217,14 +1210,14 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
1217 i = pages + cpu*2; 1210 i = pages + cpu*2;
1218 1211
1219 /* First page (Guest registers) is writable from the Guest */ 1212 /* First page (Guest registers) is writable from the Guest */
1220 native_set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]), 1213 set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]),
1221 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW))); 1214 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW)));
1222 1215
1223 /* 1216 /*
1224 * The second page contains the "struct lguest_ro_state", and is 1217 * The second page contains the "struct lguest_ro_state", and is
1225 * read-only. 1218 * read-only.
1226 */ 1219 */
1227 native_set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]), 1220 set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]),
1228 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); 1221 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)));
1229} 1222}
1230 1223