diff options
Diffstat (limited to 'arch/x86/lguest/boot.c')
-rw-r--r-- | arch/x86/lguest/boot.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index db832fd65ec..13ee258442a 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -71,7 +71,8 @@ | |||
71 | #include <asm/stackprotector.h> | 71 | #include <asm/stackprotector.h> |
72 | #include <asm/reboot.h> /* for struct machine_ops */ | 72 | #include <asm/reboot.h> /* for struct machine_ops */ |
73 | 73 | ||
74 | /*G:010 Welcome to the Guest! | 74 | /*G:010 |
75 | * Welcome to the Guest! | ||
75 | * | 76 | * |
76 | * The Guest in our tale is a simple creature: identical to the Host but | 77 | * The Guest in our tale is a simple creature: identical to the Host but |
77 | * behaving in simplified but equivalent ways. In particular, the Guest is the | 78 | * behaving in simplified but equivalent ways. In particular, the Guest is the |
@@ -190,15 +191,23 @@ static void lazy_hcall4(unsigned long call, | |||
190 | #endif | 191 | #endif |
191 | 192 | ||
192 | /*G:036 | 193 | /*G:036 |
193 | * When lazy mode is turned off reset the per-cpu lazy mode variable and then | 194 | * When lazy mode is turned off, we issue the do-nothing hypercall to |
194 | * issue the do-nothing hypercall to flush any stored calls. | 195 | * flush any stored calls, and call the generic helper to reset the |
195 | :*/ | 196 | * per-cpu lazy mode variable. |
197 | */ | ||
196 | static void lguest_leave_lazy_mmu_mode(void) | 198 | static void lguest_leave_lazy_mmu_mode(void) |
197 | { | 199 | { |
198 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); | 200 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
199 | paravirt_leave_lazy_mmu(); | 201 | paravirt_leave_lazy_mmu(); |
200 | } | 202 | } |
201 | 203 | ||
204 | /* | ||
205 | * We also catch the end of context switch; we enter lazy mode for much of | ||
206 | * that too, so again we need to flush here. | ||
207 | * | ||
208 | * (Technically, this is lazy CPU mode, and normally we're in lazy MMU | ||
209 | * mode, but unlike Xen, lguest doesn't care about the difference). | ||
210 | */ | ||
202 | static void lguest_end_context_switch(struct task_struct *next) | 211 | static void lguest_end_context_switch(struct task_struct *next) |
203 | { | 212 | { |
204 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); | 213 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
@@ -391,7 +400,7 @@ static void lguest_load_tr_desc(void) | |||
391 | * giant ball of hair. Its entry in the current Intel manual runs to 28 pages. | 400 | * giant ball of hair. Its entry in the current Intel manual runs to 28 pages. |
392 | * | 401 | * |
393 | * This instruction even it has its own Wikipedia entry. The Wikipedia entry | 402 | * This instruction even it has its own Wikipedia entry. The Wikipedia entry |
394 | * has been translated into 5 languages. I am not making this up! | 403 | * has been translated into 6 languages. I am not making this up! |
395 | * | 404 | * |
396 | * We could get funky here and identify ourselves as "GenuineLguest", but | 405 | * We could get funky here and identify ourselves as "GenuineLguest", but |
397 | * instead we just use the real "cpuid" instruction. Then I pretty much turned | 406 | * instead we just use the real "cpuid" instruction. Then I pretty much turned |
@@ -458,7 +467,7 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
458 | /* | 467 | /* |
459 | * PAE systems can mark pages as non-executable. Linux calls this the | 468 | * PAE systems can mark pages as non-executable. Linux calls this the |
460 | * NX bit. Intel calls it XD (eXecute Disable), AMD EVP (Enhanced | 469 | * NX bit. Intel calls it XD (eXecute Disable), AMD EVP (Enhanced |
461 | * Virus Protection). We just switch turn if off here, since we don't | 470 | * Virus Protection). We just switch it off here, since we don't |
462 | * support it. | 471 | * support it. |
463 | */ | 472 | */ |
464 | case 0x80000001: | 473 | case 0x80000001: |
@@ -520,17 +529,16 @@ static unsigned long lguest_read_cr2(void) | |||
520 | 529 | ||
521 | /* See lguest_set_pte() below. */ | 530 | /* See lguest_set_pte() below. */ |
522 | static bool cr3_changed = false; | 531 | static bool cr3_changed = false; |
532 | static unsigned long current_cr3; | ||
523 | 533 | ||
524 | /* | 534 | /* |
525 | * cr3 is the current toplevel pagetable page: the principle is the same as | 535 | * cr3 is the current toplevel pagetable page: the principle is the same as |
526 | * cr0. Keep a local copy, and tell the Host when it changes. The only | 536 | * cr0. Keep a local copy, and tell the Host when it changes. |
527 | * difference is that our local copy is in lguest_data because the Host needs | ||
528 | * to set it upon our initial hypercall. | ||
529 | */ | 537 | */ |
530 | static void lguest_write_cr3(unsigned long cr3) | 538 | static void lguest_write_cr3(unsigned long cr3) |
531 | { | 539 | { |
532 | lguest_data.pgdir = cr3; | ||
533 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); | 540 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); |
541 | current_cr3 = cr3; | ||
534 | 542 | ||
535 | /* These two page tables are simple, linear, and used during boot */ | 543 | /* These two page tables are simple, linear, and used during boot */ |
536 | if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) | 544 | if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) |
@@ -539,7 +547,7 @@ static void lguest_write_cr3(unsigned long cr3) | |||
539 | 547 | ||
540 | static unsigned long lguest_read_cr3(void) | 548 | static unsigned long lguest_read_cr3(void) |
541 | { | 549 | { |
542 | return lguest_data.pgdir; | 550 | return current_cr3; |
543 | } | 551 | } |
544 | 552 | ||
545 | /* cr4 is used to enable and disable PGE, but we don't care. */ | 553 | /* cr4 is used to enable and disable PGE, but we don't care. */ |
@@ -641,7 +649,7 @@ static void lguest_write_cr4(unsigned long val) | |||
641 | 649 | ||
642 | /* | 650 | /* |
643 | * The Guest calls this after it has set a second-level entry (pte), ie. to map | 651 | * The Guest calls this after it has set a second-level entry (pte), ie. to map |
644 | * a page into a process' address space. Wetell the Host the toplevel and | 652 | * a page into a process' address space. We tell the Host the toplevel and |
645 | * address this corresponds to. The Guest uses one pagetable per process, so | 653 | * address this corresponds to. The Guest uses one pagetable per process, so |
646 | * we need to tell the Host which one we're changing (mm->pgd). | 654 | * we need to tell the Host which one we're changing (mm->pgd). |
647 | */ | 655 | */ |
@@ -758,7 +766,7 @@ static void lguest_pmd_clear(pmd_t *pmdp) | |||
758 | static void lguest_flush_tlb_single(unsigned long addr) | 766 | static void lguest_flush_tlb_single(unsigned long addr) |
759 | { | 767 | { |
760 | /* Simply set it to zero: if it was not, it will fault back in. */ | 768 | /* Simply set it to zero: if it was not, it will fault back in. */ |
761 | lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); | 769 | lazy_hcall3(LHCALL_SET_PTE, current_cr3, addr, 0); |
762 | } | 770 | } |
763 | 771 | ||
764 | /* | 772 | /* |
@@ -1140,7 +1148,7 @@ static struct notifier_block paniced = { | |||
1140 | static __init char *lguest_memory_setup(void) | 1148 | static __init char *lguest_memory_setup(void) |
1141 | { | 1149 | { |
1142 | /* | 1150 | /* |
1143 | *The Linux bootloader header contains an "e820" memory map: the | 1151 | * The Linux bootloader header contains an "e820" memory map: the |
1144 | * Launcher populated the first entry with our memory limit. | 1152 | * Launcher populated the first entry with our memory limit. |
1145 | */ | 1153 | */ |
1146 | e820_add_region(boot_params.e820_map[0].addr, | 1154 | e820_add_region(boot_params.e820_map[0].addr, |