diff options
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/kernel/efi.c | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/efi_64.c | 32 | ||||
| -rw-r--r-- | arch/x86/kernel/i8253.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/reboot.c | 46 | ||||
| -rw-r--r-- | arch/x86/mm/ioremap.c | 4 | ||||
| -rw-r--r-- | arch/x86/mm/pageattr.c | 4 | ||||
| -rw-r--r-- | arch/x86/xen/enlighten.c | 4 |
7 files changed, 64 insertions, 40 deletions
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 32dd62b36ff7..cbdf9bacc575 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c | |||
| @@ -384,9 +384,6 @@ static void __init runtime_code_page_mkexec(void) | |||
| 384 | efi_memory_desc_t *md; | 384 | efi_memory_desc_t *md; |
| 385 | void *p; | 385 | void *p; |
| 386 | 386 | ||
| 387 | if (!(__supported_pte_mask & _PAGE_NX)) | ||
| 388 | return; | ||
| 389 | |||
| 390 | /* Make EFI runtime service code area executable */ | 387 | /* Make EFI runtime service code area executable */ |
| 391 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 388 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
| 392 | md = p; | 389 | md = p; |
| @@ -428,9 +425,6 @@ void __init efi_enter_virtual_mode(void) | |||
| 428 | else | 425 | else |
| 429 | va = efi_ioremap(md->phys_addr, size); | 426 | va = efi_ioremap(md->phys_addr, size); |
| 430 | 427 | ||
| 431 | if (md->attribute & EFI_MEMORY_WB) | ||
| 432 | set_memory_uc(md->virt_addr, size); | ||
| 433 | |||
| 434 | md->virt_addr = (u64) (unsigned long) va; | 428 | md->virt_addr = (u64) (unsigned long) va; |
| 435 | 429 | ||
| 436 | if (!va) { | 430 | if (!va) { |
| @@ -439,6 +433,9 @@ void __init efi_enter_virtual_mode(void) | |||
| 439 | continue; | 433 | continue; |
| 440 | } | 434 | } |
| 441 | 435 | ||
| 436 | if (!(md->attribute & EFI_MEMORY_WB)) | ||
| 437 | set_memory_uc(md->virt_addr, size); | ||
| 438 | |||
| 442 | systab = (u64) (unsigned long) efi_phys.systab; | 439 | systab = (u64) (unsigned long) efi_phys.systab; |
| 443 | if (md->phys_addr <= systab && systab < end) { | 440 | if (md->phys_addr <= systab && systab < end) { |
| 444 | systab += md->virt_addr - md->phys_addr; | 441 | systab += md->virt_addr - md->phys_addr; |
| @@ -476,7 +473,8 @@ void __init efi_enter_virtual_mode(void) | |||
| 476 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; | 473 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; |
| 477 | efi.reset_system = virt_efi_reset_system; | 474 | efi.reset_system = virt_efi_reset_system; |
| 478 | efi.set_virtual_address_map = virt_efi_set_virtual_address_map; | 475 | efi.set_virtual_address_map = virt_efi_set_virtual_address_map; |
| 479 | runtime_code_page_mkexec(); | 476 | if (__supported_pte_mask & _PAGE_NX) |
| 477 | runtime_code_page_mkexec(); | ||
| 480 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 478 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
| 481 | memmap.map = NULL; | 479 | memmap.map = NULL; |
| 482 | } | 480 | } |
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c index 09d5c2330934..d143a1e76b30 100644 --- a/arch/x86/kernel/efi_64.c +++ b/arch/x86/kernel/efi_64.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <asm/tlbflush.h> | 35 | #include <asm/tlbflush.h> |
| 36 | #include <asm/proto.h> | 36 | #include <asm/proto.h> |
| 37 | #include <asm/efi.h> | 37 | #include <asm/efi.h> |
| 38 | #include <asm/cacheflush.h> | ||
| 38 | 39 | ||
| 39 | static pgd_t save_pgd __initdata; | 40 | static pgd_t save_pgd __initdata; |
| 40 | static unsigned long efi_flags __initdata; | 41 | static unsigned long efi_flags __initdata; |
| @@ -43,22 +44,15 @@ static void __init early_mapping_set_exec(unsigned long start, | |||
| 43 | unsigned long end, | 44 | unsigned long end, |
| 44 | int executable) | 45 | int executable) |
| 45 | { | 46 | { |
| 46 | pte_t *kpte; | 47 | unsigned long num_pages; |
| 47 | unsigned int level; | 48 | |
| 48 | 49 | start &= PMD_MASK; | |
| 49 | while (start < end) { | 50 | end = (end + PMD_SIZE - 1) & PMD_MASK; |
| 50 | kpte = lookup_address((unsigned long)__va(start), &level); | 51 | num_pages = (end - start) >> PAGE_SHIFT; |
| 51 | BUG_ON(!kpte); | 52 | if (executable) |
| 52 | if (executable) | 53 | set_memory_x((unsigned long)__va(start), num_pages); |
| 53 | set_pte(kpte, pte_mkexec(*kpte)); | 54 | else |
| 54 | else | 55 | set_memory_nx((unsigned long)__va(start), num_pages); |
| 55 | set_pte(kpte, __pte((pte_val(*kpte) | _PAGE_NX) & \ | ||
| 56 | __supported_pte_mask)); | ||
| 57 | if (level == PG_LEVEL_4K) | ||
| 58 | start = (start + PAGE_SIZE) & PAGE_MASK; | ||
| 59 | else | ||
| 60 | start = (start + PMD_SIZE) & PMD_MASK; | ||
| 61 | } | ||
| 62 | } | 56 | } |
| 63 | 57 | ||
| 64 | static void __init early_runtime_code_mapping_set_exec(int executable) | 58 | static void __init early_runtime_code_mapping_set_exec(int executable) |
| @@ -74,7 +68,7 @@ static void __init early_runtime_code_mapping_set_exec(int executable) | |||
| 74 | md = p; | 68 | md = p; |
| 75 | if (md->type == EFI_RUNTIME_SERVICES_CODE) { | 69 | if (md->type == EFI_RUNTIME_SERVICES_CODE) { |
| 76 | unsigned long end; | 70 | unsigned long end; |
| 77 | end = md->phys_addr + (md->num_pages << PAGE_SHIFT); | 71 | end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); |
| 78 | early_mapping_set_exec(md->phys_addr, end, executable); | 72 | early_mapping_set_exec(md->phys_addr, end, executable); |
| 79 | } | 73 | } |
| 80 | } | 74 | } |
| @@ -84,8 +78,8 @@ void __init efi_call_phys_prelog(void) | |||
| 84 | { | 78 | { |
| 85 | unsigned long vaddress; | 79 | unsigned long vaddress; |
| 86 | 80 | ||
| 87 | local_irq_save(efi_flags); | ||
| 88 | early_runtime_code_mapping_set_exec(1); | 81 | early_runtime_code_mapping_set_exec(1); |
| 82 | local_irq_save(efi_flags); | ||
| 89 | vaddress = (unsigned long)__va(0x0UL); | 83 | vaddress = (unsigned long)__va(0x0UL); |
| 90 | save_pgd = *pgd_offset_k(0x0UL); | 84 | save_pgd = *pgd_offset_k(0x0UL); |
| 91 | set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); | 85 | set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); |
| @@ -98,9 +92,9 @@ void __init efi_call_phys_epilog(void) | |||
| 98 | * After the lock is released, the original page table is restored. | 92 | * After the lock is released, the original page table is restored. |
| 99 | */ | 93 | */ |
| 100 | set_pgd(pgd_offset_k(0x0UL), save_pgd); | 94 | set_pgd(pgd_offset_k(0x0UL), save_pgd); |
| 101 | early_runtime_code_mapping_set_exec(0); | ||
| 102 | __flush_tlb_all(); | 95 | __flush_tlb_all(); |
| 103 | local_irq_restore(efi_flags); | 96 | local_irq_restore(efi_flags); |
| 97 | early_runtime_code_mapping_set_exec(0); | ||
| 104 | } | 98 | } |
| 105 | 99 | ||
| 106 | void __init efi_reserve_bootmem(void) | 100 | void __init efi_reserve_bootmem(void) |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index ef62b07b2b48..8540abe86ade 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
| @@ -95,7 +95,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) | |||
| 95 | * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - | 95 | * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - |
| 96 | * !using_apic_timer decisions in do_timer_interrupt_hook() | 96 | * !using_apic_timer decisions in do_timer_interrupt_hook() |
| 97 | */ | 97 | */ |
| 98 | struct clock_event_device pit_clockevent = { | 98 | static struct clock_event_device pit_clockevent = { |
| 99 | .name = "pit", | 99 | .name = "pit", |
| 100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
| 101 | .set_mode = init_pit_timer, | 101 | .set_mode = init_pit_timer, |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 5818dc28167d..7fd6ac43e4a1 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -326,7 +326,7 @@ static inline void kb_wait(void) | |||
| 326 | } | 326 | } |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | void machine_emergency_restart(void) | 329 | static void native_machine_emergency_restart(void) |
| 330 | { | 330 | { |
| 331 | int i; | 331 | int i; |
| 332 | 332 | ||
| @@ -376,7 +376,7 @@ void machine_emergency_restart(void) | |||
| 376 | } | 376 | } |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | void machine_shutdown(void) | 379 | static void native_machine_shutdown(void) |
| 380 | { | 380 | { |
| 381 | /* Stop the cpus and apics */ | 381 | /* Stop the cpus and apics */ |
| 382 | #ifdef CONFIG_SMP | 382 | #ifdef CONFIG_SMP |
| @@ -420,7 +420,7 @@ void machine_shutdown(void) | |||
| 420 | #endif | 420 | #endif |
| 421 | } | 421 | } |
| 422 | 422 | ||
| 423 | void machine_restart(char *__unused) | 423 | static void native_machine_restart(char *__unused) |
| 424 | { | 424 | { |
| 425 | printk("machine restart\n"); | 425 | printk("machine restart\n"); |
| 426 | 426 | ||
| @@ -429,11 +429,11 @@ void machine_restart(char *__unused) | |||
| 429 | machine_emergency_restart(); | 429 | machine_emergency_restart(); |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | void machine_halt(void) | 432 | static void native_machine_halt(void) |
| 433 | { | 433 | { |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | void machine_power_off(void) | 436 | static void native_machine_power_off(void) |
| 437 | { | 437 | { |
| 438 | if (pm_power_off) { | 438 | if (pm_power_off) { |
| 439 | if (!reboot_force) | 439 | if (!reboot_force) |
| @@ -443,9 +443,35 @@ void machine_power_off(void) | |||
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | struct machine_ops machine_ops = { | 445 | struct machine_ops machine_ops = { |
| 446 | .power_off = machine_power_off, | 446 | .power_off = native_machine_power_off, |
| 447 | .shutdown = machine_shutdown, | 447 | .shutdown = native_machine_shutdown, |
| 448 | .emergency_restart = machine_emergency_restart, | 448 | .emergency_restart = native_machine_emergency_restart, |
| 449 | .restart = machine_restart, | 449 | .restart = native_machine_restart, |
| 450 | .halt = machine_halt | 450 | .halt = native_machine_halt |
| 451 | }; | 451 | }; |
| 452 | |||
| 453 | void machine_power_off(void) | ||
| 454 | { | ||
| 455 | machine_ops.power_off(); | ||
| 456 | } | ||
| 457 | |||
| 458 | void machine_shutdown(void) | ||
| 459 | { | ||
| 460 | machine_ops.shutdown(); | ||
| 461 | } | ||
| 462 | |||
| 463 | void machine_emergency_restart(void) | ||
| 464 | { | ||
| 465 | machine_ops.emergency_restart(); | ||
| 466 | } | ||
| 467 | |||
| 468 | void machine_restart(char *cmd) | ||
| 469 | { | ||
| 470 | machine_ops.restart(cmd); | ||
| 471 | } | ||
| 472 | |||
| 473 | void machine_halt(void) | ||
| 474 | { | ||
| 475 | machine_ops.halt(); | ||
| 476 | } | ||
| 477 | |||
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index a4897a85268a..9f42d7e9c158 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
| @@ -265,7 +265,9 @@ static __initdata pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] | |||
| 265 | 265 | ||
| 266 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) | 266 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) |
| 267 | { | 267 | { |
| 268 | pgd_t *pgd = &swapper_pg_dir[pgd_index(addr)]; | 268 | /* Don't assume we're using swapper_pg_dir at this point */ |
| 269 | pgd_t *base = __va(read_cr3()); | ||
| 270 | pgd_t *pgd = &base[pgd_index(addr)]; | ||
| 269 | pud_t *pud = pud_offset(pgd, addr); | 271 | pud_t *pud = pud_offset(pgd, addr); |
| 270 | pmd_t *pmd = pmd_offset(pud, addr); | 272 | pmd_t *pmd = pmd_offset(pud, addr); |
| 271 | 273 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 440210a2277d..bd61ed13f9cf 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -275,8 +275,8 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
| 275 | break; | 275 | break; |
| 276 | #ifdef CONFIG_X86_64 | 276 | #ifdef CONFIG_X86_64 |
| 277 | case PG_LEVEL_1G: | 277 | case PG_LEVEL_1G: |
| 278 | psize = PMD_PAGE_SIZE; | 278 | psize = PUD_PAGE_SIZE; |
| 279 | pmask = PMD_PAGE_MASK; | 279 | pmask = PUD_PAGE_MASK; |
| 280 | break; | 280 | break; |
| 281 | #endif | 281 | #endif |
| 282 | default: | 282 | default: |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index de647bc6e74d..49e5358f481a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -798,6 +798,10 @@ static __init void xen_pagetable_setup_start(pgd_t *base) | |||
| 798 | * added to the table can be prepared properly for Xen. | 798 | * added to the table can be prepared properly for Xen. |
| 799 | */ | 799 | */ |
| 800 | xen_write_cr3(__pa(base)); | 800 | xen_write_cr3(__pa(base)); |
| 801 | |||
| 802 | /* Unpin initial Xen pagetable */ | ||
| 803 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, | ||
| 804 | PFN_DOWN(__pa(xen_start_info->pt_base))); | ||
| 801 | } | 805 | } |
| 802 | 806 | ||
| 803 | static __init void xen_pagetable_setup_done(pgd_t *base) | 807 | static __init void xen_pagetable_setup_done(pgd_t *base) |
