diff options
Diffstat (limited to 'arch/x86/kernel/paravirt.c')
-rw-r--r-- | arch/x86/kernel/paravirt.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index c6520a4e85d4..63dd358d8ee1 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <asm/paravirt.h> | 28 | #include <asm/paravirt.h> |
29 | #include <asm/desc.h> | 29 | #include <asm/desc.h> |
30 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
31 | #include <asm/arch_hooks.h> | ||
32 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
33 | #include <asm/time.h> | 32 | #include <asm/time.h> |
34 | #include <asm/pgalloc.h> | 33 | #include <asm/pgalloc.h> |
@@ -44,6 +43,17 @@ void _paravirt_nop(void) | |||
44 | { | 43 | { |
45 | } | 44 | } |
46 | 45 | ||
46 | /* identity function, which can be inlined */ | ||
47 | u32 _paravirt_ident_32(u32 x) | ||
48 | { | ||
49 | return x; | ||
50 | } | ||
51 | |||
52 | u64 _paravirt_ident_64(u64 x) | ||
53 | { | ||
54 | return x; | ||
55 | } | ||
56 | |||
47 | static void __init default_banner(void) | 57 | static void __init default_banner(void) |
48 | { | 58 | { |
49 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", | 59 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", |
@@ -138,9 +148,16 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | |||
138 | if (opfunc == NULL) | 148 | if (opfunc == NULL) |
139 | /* If there's no function, patch it with a ud2a (BUG) */ | 149 | /* If there's no function, patch it with a ud2a (BUG) */ |
140 | ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a)); | 150 | ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a)); |
141 | else if (opfunc == paravirt_nop) | 151 | else if (opfunc == _paravirt_nop) |
142 | /* If the operation is a nop, then nop the callsite */ | 152 | /* If the operation is a nop, then nop the callsite */ |
143 | ret = paravirt_patch_nop(); | 153 | ret = paravirt_patch_nop(); |
154 | |||
155 | /* identity functions just return their single argument */ | ||
156 | else if (opfunc == _paravirt_ident_32) | ||
157 | ret = paravirt_patch_ident_32(insnbuf, len); | ||
158 | else if (opfunc == _paravirt_ident_64) | ||
159 | ret = paravirt_patch_ident_64(insnbuf, len); | ||
160 | |||
144 | else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) || | 161 | else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) || |
145 | type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) || | 162 | type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) || |
146 | type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) || | 163 | type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) || |
@@ -318,10 +335,10 @@ struct pv_time_ops pv_time_ops = { | |||
318 | 335 | ||
319 | struct pv_irq_ops pv_irq_ops = { | 336 | struct pv_irq_ops pv_irq_ops = { |
320 | .init_IRQ = native_init_IRQ, | 337 | .init_IRQ = native_init_IRQ, |
321 | .save_fl = native_save_fl, | 338 | .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), |
322 | .restore_fl = native_restore_fl, | 339 | .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), |
323 | .irq_disable = native_irq_disable, | 340 | .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), |
324 | .irq_enable = native_irq_enable, | 341 | .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), |
325 | .safe_halt = native_safe_halt, | 342 | .safe_halt = native_safe_halt, |
326 | .halt = native_halt, | 343 | .halt = native_halt, |
327 | #ifdef CONFIG_X86_64 | 344 | #ifdef CONFIG_X86_64 |
@@ -399,6 +416,14 @@ struct pv_apic_ops pv_apic_ops = { | |||
399 | #endif | 416 | #endif |
400 | }; | 417 | }; |
401 | 418 | ||
419 | #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) | ||
420 | /* 32-bit pagetable entries */ | ||
421 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32) | ||
422 | #else | ||
423 | /* 64-bit pagetable entries */ | ||
424 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) | ||
425 | #endif | ||
426 | |||
402 | struct pv_mmu_ops pv_mmu_ops = { | 427 | struct pv_mmu_ops pv_mmu_ops = { |
403 | #ifndef CONFIG_X86_64 | 428 | #ifndef CONFIG_X86_64 |
404 | .pagetable_setup_start = native_pagetable_setup_start, | 429 | .pagetable_setup_start = native_pagetable_setup_start, |
@@ -450,22 +475,23 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
450 | .pmd_clear = native_pmd_clear, | 475 | .pmd_clear = native_pmd_clear, |
451 | #endif | 476 | #endif |
452 | .set_pud = native_set_pud, | 477 | .set_pud = native_set_pud, |
453 | .pmd_val = native_pmd_val, | 478 | |
454 | .make_pmd = native_make_pmd, | 479 | .pmd_val = PTE_IDENT, |
480 | .make_pmd = PTE_IDENT, | ||
455 | 481 | ||
456 | #if PAGETABLE_LEVELS == 4 | 482 | #if PAGETABLE_LEVELS == 4 |
457 | .pud_val = native_pud_val, | 483 | .pud_val = PTE_IDENT, |
458 | .make_pud = native_make_pud, | 484 | .make_pud = PTE_IDENT, |
485 | |||
459 | .set_pgd = native_set_pgd, | 486 | .set_pgd = native_set_pgd, |
460 | #endif | 487 | #endif |
461 | #endif /* PAGETABLE_LEVELS >= 3 */ | 488 | #endif /* PAGETABLE_LEVELS >= 3 */ |
462 | 489 | ||
463 | .pte_val = native_pte_val, | 490 | .pte_val = PTE_IDENT, |
464 | .pte_flags = native_pte_flags, | 491 | .pgd_val = PTE_IDENT, |
465 | .pgd_val = native_pgd_val, | ||
466 | 492 | ||
467 | .make_pte = native_make_pte, | 493 | .make_pte = PTE_IDENT, |
468 | .make_pgd = native_make_pgd, | 494 | .make_pgd = PTE_IDENT, |
469 | 495 | ||
470 | .dup_mmap = paravirt_nop, | 496 | .dup_mmap = paravirt_nop, |
471 | .exit_mmap = paravirt_nop, | 497 | .exit_mmap = paravirt_nop, |