diff options
Diffstat (limited to 'arch/i386/kernel/vmi.c')
-rw-r--r-- | arch/i386/kernel/vmi.c | 131 |
1 files changed, 47 insertions, 84 deletions
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 697a70e8c0c..c8726c424b3 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/highmem.h> | ||
29 | #include <asm/vmi.h> | 30 | #include <asm/vmi.h> |
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/fixmap.h> | 32 | #include <asm/fixmap.h> |
@@ -56,7 +57,7 @@ static int disable_noidle; | |||
56 | static int disable_vmi_timer; | 57 | static int disable_vmi_timer; |
57 | 58 | ||
58 | /* Cached VMI operations */ | 59 | /* Cached VMI operations */ |
59 | struct { | 60 | static struct { |
60 | void (*cpuid)(void /* non-c */); | 61 | void (*cpuid)(void /* non-c */); |
61 | void (*_set_ldt)(u32 selector); | 62 | void (*_set_ldt)(u32 selector); |
62 | void (*set_tr)(u32 selector); | 63 | void (*set_tr)(u32 selector); |
@@ -65,16 +66,15 @@ struct { | |||
65 | void (*release_page)(u32, u32); | 66 | void (*release_page)(u32, u32); |
66 | void (*set_pte)(pte_t, pte_t *, unsigned); | 67 | void (*set_pte)(pte_t, pte_t *, unsigned); |
67 | void (*update_pte)(pte_t *, unsigned); | 68 | void (*update_pte)(pte_t *, unsigned); |
68 | void (*set_linear_mapping)(int, u32, u32, u32); | 69 | void (*set_linear_mapping)(int, void *, u32, u32); |
69 | void (*flush_tlb)(int); | 70 | void (*_flush_tlb)(int); |
70 | void (*set_initial_ap_state)(int, int); | 71 | void (*set_initial_ap_state)(int, int); |
71 | void (*halt)(void); | 72 | void (*halt)(void); |
72 | void (*set_lazy_mode)(int mode); | 73 | void (*set_lazy_mode)(int mode); |
73 | } vmi_ops; | 74 | } vmi_ops; |
74 | 75 | ||
75 | /* XXX move this to alternative.h */ | 76 | /* Cached VMI operations */ |
76 | extern struct paravirt_patch __start_parainstructions[], | 77 | struct vmi_timer_ops vmi_timer_ops; |
77 | __stop_parainstructions[]; | ||
78 | 78 | ||
79 | /* | 79 | /* |
80 | * VMI patching routines. | 80 | * VMI patching routines. |
@@ -83,11 +83,6 @@ extern struct paravirt_patch __start_parainstructions[], | |||
83 | #define MNEM_JMP 0xe9 | 83 | #define MNEM_JMP 0xe9 |
84 | #define MNEM_RET 0xc3 | 84 | #define MNEM_RET 0xc3 |
85 | 85 | ||
86 | static char irq_save_disable_callout[] = { | ||
87 | MNEM_CALL, 0, 0, 0, 0, | ||
88 | MNEM_CALL, 0, 0, 0, 0, | ||
89 | MNEM_RET | ||
90 | }; | ||
91 | #define IRQ_PATCH_INT_MASK 0 | 86 | #define IRQ_PATCH_INT_MASK 0 |
92 | #define IRQ_PATCH_DISABLE 5 | 87 | #define IRQ_PATCH_DISABLE 5 |
93 | 88 | ||
@@ -135,33 +130,17 @@ static unsigned patch_internal(int call, unsigned len, void *insns) | |||
135 | static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) | 130 | static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) |
136 | { | 131 | { |
137 | switch (type) { | 132 | switch (type) { |
138 | case PARAVIRT_IRQ_DISABLE: | 133 | case PARAVIRT_PATCH(irq_disable): |
139 | return patch_internal(VMI_CALL_DisableInterrupts, len, insns); | 134 | return patch_internal(VMI_CALL_DisableInterrupts, len, insns); |
140 | case PARAVIRT_IRQ_ENABLE: | 135 | case PARAVIRT_PATCH(irq_enable): |
141 | return patch_internal(VMI_CALL_EnableInterrupts, len, insns); | 136 | return patch_internal(VMI_CALL_EnableInterrupts, len, insns); |
142 | case PARAVIRT_RESTORE_FLAGS: | 137 | case PARAVIRT_PATCH(restore_fl): |
143 | return patch_internal(VMI_CALL_SetInterruptMask, len, insns); | 138 | return patch_internal(VMI_CALL_SetInterruptMask, len, insns); |
144 | case PARAVIRT_SAVE_FLAGS: | 139 | case PARAVIRT_PATCH(save_fl): |
145 | return patch_internal(VMI_CALL_GetInterruptMask, len, insns); | 140 | return patch_internal(VMI_CALL_GetInterruptMask, len, insns); |
146 | case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE: | 141 | case PARAVIRT_PATCH(iret): |
147 | if (len >= 10) { | ||
148 | patch_internal(VMI_CALL_GetInterruptMask, len, insns); | ||
149 | patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5); | ||
150 | return 10; | ||
151 | } else { | ||
152 | /* | ||
153 | * You bastards didn't leave enough room to | ||
154 | * patch save_flags_irq_disable inline. Patch | ||
155 | * to a helper | ||
156 | */ | ||
157 | BUG_ON(len < 5); | ||
158 | *(char *)insns = MNEM_CALL; | ||
159 | patch_offset(insns, irq_save_disable_callout); | ||
160 | return 5; | ||
161 | } | ||
162 | case PARAVIRT_INTERRUPT_RETURN: | ||
163 | return patch_internal(VMI_CALL_IRET, len, insns); | 142 | return patch_internal(VMI_CALL_IRET, len, insns); |
164 | case PARAVIRT_STI_SYSEXIT: | 143 | case PARAVIRT_PATCH(irq_enable_sysexit): |
165 | return patch_internal(VMI_CALL_SYSEXIT, len, insns); | 144 | return patch_internal(VMI_CALL_SYSEXIT, len, insns); |
166 | default: | 145 | default: |
167 | break; | 146 | break; |
@@ -230,24 +209,24 @@ static void vmi_set_tr(void) | |||
230 | static void vmi_load_esp0(struct tss_struct *tss, | 209 | static void vmi_load_esp0(struct tss_struct *tss, |
231 | struct thread_struct *thread) | 210 | struct thread_struct *thread) |
232 | { | 211 | { |
233 | tss->esp0 = thread->esp0; | 212 | tss->x86_tss.esp0 = thread->esp0; |
234 | 213 | ||
235 | /* This can only happen when SEP is enabled, no need to test "SEP"arately */ | 214 | /* This can only happen when SEP is enabled, no need to test "SEP"arately */ |
236 | if (unlikely(tss->ss1 != thread->sysenter_cs)) { | 215 | if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { |
237 | tss->ss1 = thread->sysenter_cs; | 216 | tss->x86_tss.ss1 = thread->sysenter_cs; |
238 | wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); | 217 | wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); |
239 | } | 218 | } |
240 | vmi_ops.set_kernel_stack(__KERNEL_DS, tss->esp0); | 219 | vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.esp0); |
241 | } | 220 | } |
242 | 221 | ||
243 | static void vmi_flush_tlb_user(void) | 222 | static void vmi_flush_tlb_user(void) |
244 | { | 223 | { |
245 | vmi_ops.flush_tlb(VMI_FLUSH_TLB); | 224 | vmi_ops._flush_tlb(VMI_FLUSH_TLB); |
246 | } | 225 | } |
247 | 226 | ||
248 | static void vmi_flush_tlb_kernel(void) | 227 | static void vmi_flush_tlb_kernel(void) |
249 | { | 228 | { |
250 | vmi_ops.flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); | 229 | vmi_ops._flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); |
251 | } | 230 | } |
252 | 231 | ||
253 | /* Stub to do nothing at all; used for delays and unimplemented calls */ | 232 | /* Stub to do nothing at all; used for delays and unimplemented calls */ |
@@ -255,18 +234,6 @@ static void vmi_nop(void) | |||
255 | { | 234 | { |
256 | } | 235 | } |
257 | 236 | ||
258 | /* For NO_IDLE_HZ, we stop the clock when halting the kernel */ | ||
259 | static fastcall void vmi_safe_halt(void) | ||
260 | { | ||
261 | int idle = vmi_stop_hz_timer(); | ||
262 | vmi_ops.halt(); | ||
263 | if (idle) { | ||
264 | local_irq_disable(); | ||
265 | vmi_account_time_restart_hz_timer(); | ||
266 | local_irq_enable(); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | #ifdef CONFIG_DEBUG_PAGE_TYPE | 237 | #ifdef CONFIG_DEBUG_PAGE_TYPE |
271 | 238 | ||
272 | #ifdef CONFIG_X86_PAE | 239 | #ifdef CONFIG_X86_PAE |
@@ -370,8 +337,11 @@ static void vmi_check_page_type(u32 pfn, int type) | |||
370 | #define vmi_check_page_type(p,t) do { } while (0) | 337 | #define vmi_check_page_type(p,t) do { } while (0) |
371 | #endif | 338 | #endif |
372 | 339 | ||
373 | static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) | 340 | #ifdef CONFIG_HIGHPTE |
341 | static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type) | ||
374 | { | 342 | { |
343 | void *va = kmap_atomic(page, type); | ||
344 | |||
375 | /* | 345 | /* |
376 | * Internally, the VMI ROM must map virtual addresses to physical | 346 | * Internally, the VMI ROM must map virtual addresses to physical |
377 | * addresses for processing MMU updates. By the time MMU updates | 347 | * addresses for processing MMU updates. By the time MMU updates |
@@ -385,8 +355,11 @@ static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) | |||
385 | * args: SLOT VA COUNT PFN | 355 | * args: SLOT VA COUNT PFN |
386 | */ | 356 | */ |
387 | BUG_ON(type != KM_PTE0 && type != KM_PTE1); | 357 | BUG_ON(type != KM_PTE0 && type != KM_PTE1); |
388 | vmi_ops.set_linear_mapping((type - KM_PTE0)+1, (u32)va, 1, pfn); | 358 | vmi_ops.set_linear_mapping((type - KM_PTE0)+1, va, 1, page_to_pfn(page)); |
359 | |||
360 | return va; | ||
389 | } | 361 | } |
362 | #endif | ||
390 | 363 | ||
391 | static void vmi_allocate_pt(u32 pfn) | 364 | static void vmi_allocate_pt(u32 pfn) |
392 | { | 365 | { |
@@ -443,13 +416,13 @@ static void vmi_release_pd(u32 pfn) | |||
443 | ((level) | (is_current_as(mm, user) ? \ | 416 | ((level) | (is_current_as(mm, user) ? \ |
444 | (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0)) | 417 | (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0)) |
445 | 418 | ||
446 | static void vmi_update_pte(struct mm_struct *mm, u32 addr, pte_t *ptep) | 419 | static void vmi_update_pte(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
447 | { | 420 | { |
448 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); | 421 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); |
449 | vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); | 422 | vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); |
450 | } | 423 | } |
451 | 424 | ||
452 | static void vmi_update_pte_defer(struct mm_struct *mm, u32 addr, pte_t *ptep) | 425 | static void vmi_update_pte_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
453 | { | 426 | { |
454 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); | 427 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); |
455 | vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0)); | 428 | vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0)); |
@@ -462,7 +435,7 @@ static void vmi_set_pte(pte_t *ptep, pte_t pte) | |||
462 | vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT); | 435 | vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT); |
463 | } | 436 | } |
464 | 437 | ||
465 | static void vmi_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) | 438 | static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) |
466 | { | 439 | { |
467 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); | 440 | vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); |
468 | vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); | 441 | vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); |
@@ -516,7 +489,7 @@ static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | |||
516 | vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); | 489 | vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); |
517 | } | 490 | } |
518 | 491 | ||
519 | void vmi_pmd_clear(pmd_t *pmd) | 492 | static void vmi_pmd_clear(pmd_t *pmd) |
520 | { | 493 | { |
521 | const pte_t pte = { 0 }; | 494 | const pte_t pte = { 0 }; |
522 | vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); | 495 | vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); |
@@ -525,8 +498,6 @@ void vmi_pmd_clear(pmd_t *pmd) | |||
525 | #endif | 498 | #endif |
526 | 499 | ||
527 | #ifdef CONFIG_SMP | 500 | #ifdef CONFIG_SMP |
528 | extern void setup_pda(void); | ||
529 | |||
530 | static void __devinit | 501 | static void __devinit |
531 | vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, | 502 | vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, |
532 | unsigned long start_esp) | 503 | unsigned long start_esp) |
@@ -551,13 +522,11 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, | |||
551 | 522 | ||
552 | ap.ds = __USER_DS; | 523 | ap.ds = __USER_DS; |
553 | ap.es = __USER_DS; | 524 | ap.es = __USER_DS; |
554 | ap.fs = __KERNEL_PDA; | 525 | ap.fs = __KERNEL_PERCPU; |
555 | ap.gs = 0; | 526 | ap.gs = 0; |
556 | 527 | ||
557 | ap.eflags = 0; | 528 | ap.eflags = 0; |
558 | 529 | ||
559 | setup_pda(); | ||
560 | |||
561 | #ifdef CONFIG_X86_PAE | 530 | #ifdef CONFIG_X86_PAE |
562 | /* efer should match BSP efer. */ | 531 | /* efer should match BSP efer. */ |
563 | if (cpu_has_nx) { | 532 | if (cpu_has_nx) { |
@@ -575,9 +544,9 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, | |||
575 | } | 544 | } |
576 | #endif | 545 | #endif |
577 | 546 | ||
578 | static void vmi_set_lazy_mode(int mode) | 547 | static void vmi_set_lazy_mode(enum paravirt_lazy_mode mode) |
579 | { | 548 | { |
580 | static DEFINE_PER_CPU(int, lazy_mode); | 549 | static DEFINE_PER_CPU(enum paravirt_lazy_mode, lazy_mode); |
581 | 550 | ||
582 | if (!vmi_ops.set_lazy_mode) | 551 | if (!vmi_ops.set_lazy_mode) |
583 | return; | 552 | return; |
@@ -685,7 +654,7 @@ void vmi_bringup(void) | |||
685 | { | 654 | { |
686 | /* We must establish the lowmem mapping for MMU ops to work */ | 655 | /* We must establish the lowmem mapping for MMU ops to work */ |
687 | if (vmi_ops.set_linear_mapping) | 656 | if (vmi_ops.set_linear_mapping) |
688 | vmi_ops.set_linear_mapping(0, __PAGE_OFFSET, max_low_pfn, 0); | 657 | vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, max_low_pfn, 0); |
689 | } | 658 | } |
690 | 659 | ||
691 | /* | 660 | /* |
@@ -740,7 +709,6 @@ do { \ | |||
740 | } \ | 709 | } \ |
741 | } while (0) | 710 | } while (0) |
742 | 711 | ||
743 | |||
744 | /* | 712 | /* |
745 | * Activate the VMI interface and switch into paravirtualized mode | 713 | * Activate the VMI interface and switch into paravirtualized mode |
746 | */ | 714 | */ |
@@ -796,12 +764,6 @@ static inline int __init activate_vmi(void) | |||
796 | para_fill(irq_disable, DisableInterrupts); | 764 | para_fill(irq_disable, DisableInterrupts); |
797 | para_fill(irq_enable, EnableInterrupts); | 765 | para_fill(irq_enable, EnableInterrupts); |
798 | 766 | ||
799 | /* irq_save_disable !!! sheer pain */ | ||
800 | patch_offset(&irq_save_disable_callout[IRQ_PATCH_INT_MASK], | ||
801 | (char *)paravirt_ops.save_fl); | ||
802 | patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE], | ||
803 | (char *)paravirt_ops.irq_disable); | ||
804 | |||
805 | para_fill(wbinvd, WBINVD); | 767 | para_fill(wbinvd, WBINVD); |
806 | para_fill(read_tsc, RDTSC); | 768 | para_fill(read_tsc, RDTSC); |
807 | 769 | ||
@@ -831,8 +793,8 @@ static inline int __init activate_vmi(void) | |||
831 | para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); | 793 | para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); |
832 | 794 | ||
833 | /* user and kernel flush are just handled with different flags to FlushTLB */ | 795 | /* user and kernel flush are just handled with different flags to FlushTLB */ |
834 | para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); | 796 | para_wrap(flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB); |
835 | para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, flush_tlb, FlushTLB); | 797 | para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB); |
836 | para_fill(flush_tlb_single, InvalPage); | 798 | para_fill(flush_tlb_single, InvalPage); |
837 | 799 | ||
838 | /* | 800 | /* |
@@ -878,8 +840,13 @@ static inline int __init activate_vmi(void) | |||
878 | paravirt_ops.release_pt = vmi_release_pt; | 840 | paravirt_ops.release_pt = vmi_release_pt; |
879 | paravirt_ops.release_pd = vmi_release_pd; | 841 | paravirt_ops.release_pd = vmi_release_pd; |
880 | } | 842 | } |
881 | para_wrap(map_pt_hook, vmi_map_pt_hook, set_linear_mapping, | 843 | |
882 | SetLinearMapping); | 844 | /* Set linear is needed in all cases */ |
845 | vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping); | ||
846 | #ifdef CONFIG_HIGHPTE | ||
847 | if (vmi_ops.set_linear_mapping) | ||
848 | paravirt_ops.kmap_atomic_pte = vmi_kmap_atomic_pte; | ||
849 | #endif | ||
883 | 850 | ||
884 | /* | 851 | /* |
885 | * These MUST always be patched. Don't support indirect jumps | 852 | * These MUST always be patched. Don't support indirect jumps |
@@ -920,8 +887,8 @@ static inline int __init activate_vmi(void) | |||
920 | paravirt_ops.get_wallclock = vmi_get_wallclock; | 887 | paravirt_ops.get_wallclock = vmi_get_wallclock; |
921 | paravirt_ops.set_wallclock = vmi_set_wallclock; | 888 | paravirt_ops.set_wallclock = vmi_set_wallclock; |
922 | #ifdef CONFIG_X86_LOCAL_APIC | 889 | #ifdef CONFIG_X86_LOCAL_APIC |
923 | paravirt_ops.setup_boot_clock = vmi_timer_setup_boot_alarm; | 890 | paravirt_ops.setup_boot_clock = vmi_time_bsp_init; |
924 | paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm; | 891 | paravirt_ops.setup_secondary_clock = vmi_time_ap_init; |
925 | #endif | 892 | #endif |
926 | paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles; | 893 | paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles; |
927 | paravirt_ops.get_cpu_khz = vmi_cpu_khz; | 894 | paravirt_ops.get_cpu_khz = vmi_cpu_khz; |
@@ -933,11 +900,7 @@ static inline int __init activate_vmi(void) | |||
933 | disable_vmi_timer = 1; | 900 | disable_vmi_timer = 1; |
934 | } | 901 | } |
935 | 902 | ||
936 | /* No idle HZ mode only works if VMI timer and no idle is enabled */ | 903 | para_fill(safe_halt, Halt); |
937 | if (disable_noidle || disable_vmi_timer) | ||
938 | para_fill(safe_halt, Halt); | ||
939 | else | ||
940 | para_wrap(safe_halt, vmi_safe_halt, halt, Halt); | ||
941 | 904 | ||
942 | /* | 905 | /* |
943 | * Alternative instruction rewriting doesn't happen soon enough | 906 | * Alternative instruction rewriting doesn't happen soon enough |
@@ -945,7 +908,7 @@ static inline int __init activate_vmi(void) | |||
945 | * to do this before IRQs get reenabled. Fortunately, it is | 908 | * to do this before IRQs get reenabled. Fortunately, it is |
946 | * idempotent. | 909 | * idempotent. |
947 | */ | 910 | */ |
948 | apply_paravirt(__start_parainstructions, __stop_parainstructions); | 911 | apply_paravirt(__parainstructions, __parainstructions_end); |
949 | 912 | ||
950 | vmi_bringup(); | 913 | vmi_bringup(); |
951 | 914 | ||