diff options
Diffstat (limited to 'arch/x86/lguest/boot.c')
-rw-r--r-- | arch/x86/lguest/boot.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index ca7ec44bafc3..4e0c26559395 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/mce.h> | 67 | #include <asm/mce.h> |
68 | #include <asm/io.h> | 68 | #include <asm/io.h> |
69 | #include <asm/i387.h> | 69 | #include <asm/i387.h> |
70 | #include <asm/stackprotector.h> | ||
70 | #include <asm/reboot.h> /* for struct machine_ops */ | 71 | #include <asm/reboot.h> /* for struct machine_ops */ |
71 | 72 | ||
72 | /*G:010 Welcome to the Guest! | 73 | /*G:010 Welcome to the Guest! |
@@ -166,10 +167,16 @@ static void lazy_hcall3(unsigned long call, | |||
166 | 167 | ||
167 | /* When lazy mode is turned off reset the per-cpu lazy mode variable and then | 168 | /* When lazy mode is turned off reset the per-cpu lazy mode variable and then |
168 | * issue the do-nothing hypercall to flush any stored calls. */ | 169 | * issue the do-nothing hypercall to flush any stored calls. */ |
169 | static void lguest_leave_lazy_mode(void) | 170 | static void lguest_leave_lazy_mmu_mode(void) |
170 | { | 171 | { |
171 | paravirt_leave_lazy(paravirt_get_lazy_mode()); | ||
172 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); | 172 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); |
173 | paravirt_leave_lazy_mmu(); | ||
174 | } | ||
175 | |||
176 | static void lguest_end_context_switch(struct task_struct *next) | ||
177 | { | ||
178 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); | ||
179 | paravirt_end_context_switch(next); | ||
173 | } | 180 | } |
174 | 181 | ||
175 | /*G:033 | 182 | /*G:033 |
@@ -636,7 +643,7 @@ static void __init lguest_init_IRQ(void) | |||
636 | 643 | ||
637 | void lguest_setup_irq(unsigned int irq) | 644 | void lguest_setup_irq(unsigned int irq) |
638 | { | 645 | { |
639 | irq_to_desc_alloc_cpu(irq, 0); | 646 | irq_to_desc_alloc_node(irq, 0); |
640 | set_irq_chip_and_handler_name(irq, &lguest_irq_controller, | 647 | set_irq_chip_and_handler_name(irq, &lguest_irq_controller, |
641 | handle_level_irq, "level"); | 648 | handle_level_irq, "level"); |
642 | } | 649 | } |
@@ -1053,8 +1060,8 @@ __init void lguest_init(void) | |||
1053 | pv_cpu_ops.write_gdt_entry = lguest_write_gdt_entry; | 1060 | pv_cpu_ops.write_gdt_entry = lguest_write_gdt_entry; |
1054 | pv_cpu_ops.write_idt_entry = lguest_write_idt_entry; | 1061 | pv_cpu_ops.write_idt_entry = lguest_write_idt_entry; |
1055 | pv_cpu_ops.wbinvd = lguest_wbinvd; | 1062 | pv_cpu_ops.wbinvd = lguest_wbinvd; |
1056 | pv_cpu_ops.lazy_mode.enter = paravirt_enter_lazy_cpu; | 1063 | pv_cpu_ops.start_context_switch = paravirt_start_context_switch; |
1057 | pv_cpu_ops.lazy_mode.leave = lguest_leave_lazy_mode; | 1064 | pv_cpu_ops.end_context_switch = lguest_end_context_switch; |
1058 | 1065 | ||
1059 | /* pagetable management */ | 1066 | /* pagetable management */ |
1060 | pv_mmu_ops.write_cr3 = lguest_write_cr3; | 1067 | pv_mmu_ops.write_cr3 = lguest_write_cr3; |
@@ -1067,7 +1074,7 @@ __init void lguest_init(void) | |||
1067 | pv_mmu_ops.read_cr2 = lguest_read_cr2; | 1074 | pv_mmu_ops.read_cr2 = lguest_read_cr2; |
1068 | pv_mmu_ops.read_cr3 = lguest_read_cr3; | 1075 | pv_mmu_ops.read_cr3 = lguest_read_cr3; |
1069 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; | 1076 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; |
1070 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode; | 1077 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; |
1071 | pv_mmu_ops.pte_update = lguest_pte_update; | 1078 | pv_mmu_ops.pte_update = lguest_pte_update; |
1072 | pv_mmu_ops.pte_update_defer = lguest_pte_update; | 1079 | pv_mmu_ops.pte_update_defer = lguest_pte_update; |
1073 | 1080 | ||
@@ -1088,13 +1095,21 @@ __init void lguest_init(void) | |||
1088 | * lguest_init() where the rest of the fairly chaotic boot setup | 1095 | * lguest_init() where the rest of the fairly chaotic boot setup |
1089 | * occurs. */ | 1096 | * occurs. */ |
1090 | 1097 | ||
1098 | /* The stack protector is a weird thing where gcc places a canary | ||
1099 | * value on the stack and then checks it on return. This file is | ||
1100 | * compiled with -fno-stack-protector it, so we got this far without | ||
1101 | * problems. The value of the canary is kept at offset 20 from the | ||
1102 | * %gs register, so we need to set that up before calling C functions | ||
1103 | * in other files. */ | ||
1104 | setup_stack_canary_segment(0); | ||
1105 | /* We could just call load_stack_canary_segment(), but we might as | ||
1106 | * call switch_to_new_gdt() which loads the whole table and sets up | ||
1107 | * the per-cpu segment descriptor register %fs as well. */ | ||
1108 | switch_to_new_gdt(0); | ||
1109 | |||
1091 | /* As described in head_32.S, we map the first 128M of memory. */ | 1110 | /* As described in head_32.S, we map the first 128M of memory. */ |
1092 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; | 1111 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; |
1093 | 1112 | ||
1094 | /* Load the %fs segment register (the per-cpu segment register) with | ||
1095 | * the normal data segment to get through booting. */ | ||
1096 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); | ||
1097 | |||
1098 | /* The Host<->Guest Switcher lives at the top of our address space, and | 1113 | /* The Host<->Guest Switcher lives at the top of our address space, and |
1099 | * the Host told us how big it is when we made LGUEST_INIT hypercall: | 1114 | * the Host told us how big it is when we made LGUEST_INIT hypercall: |
1100 | * it put the answer in lguest_data.reserve_mem */ | 1115 | * it put the answer in lguest_data.reserve_mem */ |