diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-04 18:28:59 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-04 18:28:59 -0400 |
| commit | 067e18133f01ee0136bcec2633eb93f7320721a2 (patch) | |
| tree | eb948a629b8b5c59a0fd15e7659e6252349738f2 | |
| parent | 3f5760b90eb3bacfaa4d4c3e584152468ed327ca (diff) | |
| parent | dc731fbbadf5d65c98fcd6c86472aa286c16458a (diff) | |
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Work around compilation warning in arch/x86/kernel/apm_32.c
x86, UV: Complete IRQ interrupt migration in arch_enable_uv_irq()
x86, 32-bit: Fix double accounting in reserve_top_address()
x86: Don't use current_cpu_data in x2apic phys_pkg_id
x86, UV: Fix UV apic mode
x86, UV: Fix macros for accessing large node numbers
x86, UV: Delete mapping of MMR rangs mapped by BIOS
x86, UV: Handle missing blade-local memory correctly
x86: fix assembly constraints in native_save_fl()
x86, msr: execute on the correct CPU subset
x86: Fix assert syntax in vmlinux.lds.S
x86: Make 64-bit efi_ioremap use ioremap on MMIO regions
x86: Add quirk to make Apple MacBook5,2 use reboot=pci
x86: Fix CPA memtype reserving in the set_pages_array*() cases
x86, pat: Fix set_memory_wc related corruption
x86: fix section mismatch for i386 init code
| -rw-r--r-- | arch/x86/include/asm/efi.h | 5 | ||||
| -rw-r--r-- | arch/x86/include/asm/irqflags.h | 8 | ||||
| -rw-r--r-- | arch/x86/include/asm/uv/uv_hub.h | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_phys.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 38 | ||||
| -rw-r--r-- | arch/x86/kernel/apm_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/efi.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/efi_64.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/head_32.S | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/reboot.c | 34 | ||||
| -rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 16 | ||||
| -rw-r--r-- | arch/x86/lib/msr.c | 26 | ||||
| -rw-r--r-- | arch/x86/mm/pageattr.c | 39 | ||||
| -rw-r--r-- | arch/x86/mm/pgtable.c | 1 |
16 files changed, 120 insertions, 79 deletions
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index edc90f23e708..8406ed7f9926 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
| @@ -33,7 +33,7 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); | |||
| 33 | #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ | 33 | #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ |
| 34 | efi_call_virt(f, a1, a2, a3, a4, a5, a6) | 34 | efi_call_virt(f, a1, a2, a3, a4, a5, a6) |
| 35 | 35 | ||
| 36 | #define efi_ioremap(addr, size) ioremap_cache(addr, size) | 36 | #define efi_ioremap(addr, size, type) ioremap_cache(addr, size) |
| 37 | 37 | ||
| 38 | #else /* !CONFIG_X86_32 */ | 38 | #else /* !CONFIG_X86_32 */ |
| 39 | 39 | ||
| @@ -84,7 +84,8 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, | |||
| 84 | efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ | 84 | efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ |
| 85 | (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) | 85 | (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) |
| 86 | 86 | ||
| 87 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size); | 87 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, |
| 88 | u32 type); | ||
| 88 | 89 | ||
| 89 | #endif /* CONFIG_X86_32 */ | 90 | #endif /* CONFIG_X86_32 */ |
| 90 | 91 | ||
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index 2bdab21f0898..c6ccbe7e81ad 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h | |||
| @@ -12,9 +12,15 @@ static inline unsigned long native_save_fl(void) | |||
| 12 | { | 12 | { |
| 13 | unsigned long flags; | 13 | unsigned long flags; |
| 14 | 14 | ||
| 15 | /* | ||
| 16 | * Note: this needs to be "=r" not "=rm", because we have the | ||
| 17 | * stack offset from what gcc expects at the time the "pop" is | ||
| 18 | * executed, and so a memory reference with respect to the stack | ||
| 19 | * would end up using the wrong address. | ||
| 20 | */ | ||
| 15 | asm volatile("# __raw_save_flags\n\t" | 21 | asm volatile("# __raw_save_flags\n\t" |
| 16 | "pushf ; pop %0" | 22 | "pushf ; pop %0" |
| 17 | : "=g" (flags) | 23 | : "=r" (flags) |
| 18 | : /* no input */ | 24 | : /* no input */ |
| 19 | : "memory"); | 25 | : "memory"); |
| 20 | 26 | ||
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 341070f7ad5c..77a68505419a 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
| @@ -175,7 +175,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); | |||
| 175 | #define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT)) | 175 | #define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT)) |
| 176 | 176 | ||
| 177 | #define UV_GLOBAL_MMR64_PNODE_BITS(p) \ | 177 | #define UV_GLOBAL_MMR64_PNODE_BITS(p) \ |
| 178 | ((unsigned long)(UV_PNODE_TO_GNODE(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT) | 178 | (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT) |
| 179 | 179 | ||
| 180 | #define UV_APIC_PNODE_SHIFT 6 | 180 | #define UV_APIC_PNODE_SHIFT 6 |
| 181 | 181 | ||
| @@ -327,6 +327,7 @@ struct uv_blade_info { | |||
| 327 | unsigned short nr_possible_cpus; | 327 | unsigned short nr_possible_cpus; |
| 328 | unsigned short nr_online_cpus; | 328 | unsigned short nr_online_cpus; |
| 329 | unsigned short pnode; | 329 | unsigned short pnode; |
| 330 | short memory_nid; | ||
| 330 | }; | 331 | }; |
| 331 | extern struct uv_blade_info *uv_blade_info; | 332 | extern struct uv_blade_info *uv_blade_info; |
| 332 | extern short *uv_node_to_blade; | 333 | extern short *uv_node_to_blade; |
| @@ -363,6 +364,12 @@ static inline int uv_blade_to_pnode(int bid) | |||
| 363 | return uv_blade_info[bid].pnode; | 364 | return uv_blade_info[bid].pnode; |
| 364 | } | 365 | } |
| 365 | 366 | ||
| 367 | /* Nid of memory node on blade. -1 if no blade-local memory */ | ||
| 368 | static inline int uv_blade_to_memory_nid(int bid) | ||
| 369 | { | ||
| 370 | return uv_blade_info[bid].memory_nid; | ||
| 371 | } | ||
| 372 | |||
| 366 | /* Determine the number of possible cpus on a blade */ | 373 | /* Determine the number of possible cpus on a blade */ |
| 367 | static inline int uv_blade_nr_possible_cpus(int bid) | 374 | static inline int uv_blade_nr_possible_cpus(int bid) |
| 368 | { | 375 | { |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 2284a4812b68..d2ed6c5ddc80 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -3793,6 +3793,9 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
| 3793 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | 3793 | mmr_pnode = uv_blade_to_pnode(mmr_blade); |
| 3794 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | 3794 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); |
| 3795 | 3795 | ||
| 3796 | if (cfg->move_in_progress) | ||
| 3797 | send_cleanup_vector(cfg); | ||
| 3798 | |||
| 3796 | return irq; | 3799 | return irq; |
| 3797 | } | 3800 | } |
| 3798 | 3801 | ||
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 8e4cbb255c38..2ed4e2bb3b32 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
| @@ -170,7 +170,7 @@ static unsigned long set_apic_id(unsigned int id) | |||
| 170 | 170 | ||
| 171 | static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb) | 171 | static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb) |
| 172 | { | 172 | { |
| 173 | return current_cpu_data.initial_apicid >> index_msb; | 173 | return initial_apicid >> index_msb; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static void x2apic_send_IPI_self(int vector) | 176 | static void x2apic_send_IPI_self(int vector) |
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index a284359627e7..0b631c6a2e00 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
| @@ -162,7 +162,7 @@ static unsigned long set_apic_id(unsigned int id) | |||
| 162 | 162 | ||
| 163 | static int x2apic_phys_pkg_id(int initial_apicid, int index_msb) | 163 | static int x2apic_phys_pkg_id(int initial_apicid, int index_msb) |
| 164 | { | 164 | { |
| 165 | return current_cpu_data.initial_apicid >> index_msb; | 165 | return initial_apicid >> index_msb; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static void x2apic_send_IPI_self(int vector) | 168 | static void x2apic_send_IPI_self(int vector) |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 096d19aea2f7..832e908adcb5 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
| @@ -261,7 +261,7 @@ struct apic apic_x2apic_uv_x = { | |||
| 261 | .apic_id_registered = uv_apic_id_registered, | 261 | .apic_id_registered = uv_apic_id_registered, |
| 262 | 262 | ||
| 263 | .irq_delivery_mode = dest_Fixed, | 263 | .irq_delivery_mode = dest_Fixed, |
| 264 | .irq_dest_mode = 1, /* logical */ | 264 | .irq_dest_mode = 0, /* physical */ |
| 265 | 265 | ||
| 266 | .target_cpus = uv_target_cpus, | 266 | .target_cpus = uv_target_cpus, |
| 267 | .disable_esr = 0, | 267 | .disable_esr = 0, |
| @@ -362,12 +362,6 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) | |||
| 362 | BUG(); | 362 | BUG(); |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | static __init void map_low_mmrs(void) | ||
| 366 | { | ||
| 367 | init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); | ||
| 368 | init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); | ||
| 369 | } | ||
| 370 | |||
| 371 | enum map_type {map_wb, map_uc}; | 365 | enum map_type {map_wb, map_uc}; |
| 372 | 366 | ||
| 373 | static __init void map_high(char *id, unsigned long base, int shift, | 367 | static __init void map_high(char *id, unsigned long base, int shift, |
| @@ -395,26 +389,6 @@ static __init void map_gru_high(int max_pnode) | |||
| 395 | map_high("GRU", gru.s.base, shift, max_pnode, map_wb); | 389 | map_high("GRU", gru.s.base, shift, max_pnode, map_wb); |
| 396 | } | 390 | } |
| 397 | 391 | ||
| 398 | static __init void map_config_high(int max_pnode) | ||
| 399 | { | ||
| 400 | union uvh_rh_gam_cfg_overlay_config_mmr_u cfg; | ||
| 401 | int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT; | ||
| 402 | |||
| 403 | cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); | ||
| 404 | if (cfg.s.enable) | ||
| 405 | map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc); | ||
| 406 | } | ||
| 407 | |||
| 408 | static __init void map_mmr_high(int max_pnode) | ||
| 409 | { | ||
| 410 | union uvh_rh_gam_mmr_overlay_config_mmr_u mmr; | ||
| 411 | int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT; | ||
| 412 | |||
| 413 | mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); | ||
| 414 | if (mmr.s.enable) | ||
| 415 | map_high("MMR", mmr.s.base, shift, max_pnode, map_uc); | ||
| 416 | } | ||
| 417 | |||
| 418 | static __init void map_mmioh_high(int max_pnode) | 392 | static __init void map_mmioh_high(int max_pnode) |
| 419 | { | 393 | { |
| 420 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; | 394 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; |
| @@ -566,8 +540,6 @@ void __init uv_system_init(void) | |||
| 566 | unsigned long mmr_base, present, paddr; | 540 | unsigned long mmr_base, present, paddr; |
| 567 | unsigned short pnode_mask; | 541 | unsigned short pnode_mask; |
| 568 | 542 | ||
| 569 | map_low_mmrs(); | ||
| 570 | |||
| 571 | m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); | 543 | m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); |
| 572 | m_val = m_n_config.s.m_skt; | 544 | m_val = m_n_config.s.m_skt; |
| 573 | n_val = m_n_config.s.n_skt; | 545 | n_val = m_n_config.s.n_skt; |
| @@ -591,6 +563,8 @@ void __init uv_system_init(void) | |||
| 591 | bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); | 563 | bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); |
| 592 | uv_blade_info = kmalloc(bytes, GFP_KERNEL); | 564 | uv_blade_info = kmalloc(bytes, GFP_KERNEL); |
| 593 | BUG_ON(!uv_blade_info); | 565 | BUG_ON(!uv_blade_info); |
| 566 | for (blade = 0; blade < uv_num_possible_blades(); blade++) | ||
| 567 | uv_blade_info[blade].memory_nid = -1; | ||
| 594 | 568 | ||
| 595 | get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); | 569 | get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); |
| 596 | 570 | ||
| @@ -629,6 +603,9 @@ void __init uv_system_init(void) | |||
| 629 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 603 | lcpu = uv_blade_info[blade].nr_possible_cpus; |
| 630 | uv_blade_info[blade].nr_possible_cpus++; | 604 | uv_blade_info[blade].nr_possible_cpus++; |
| 631 | 605 | ||
| 606 | /* Any node on the blade, else will contain -1. */ | ||
| 607 | uv_blade_info[blade].memory_nid = nid; | ||
| 608 | |||
| 632 | uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; | 609 | uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; |
| 633 | uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size; | 610 | uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size; |
| 634 | uv_cpu_hub_info(cpu)->m_val = m_val; | 611 | uv_cpu_hub_info(cpu)->m_val = m_val; |
| @@ -662,11 +639,10 @@ void __init uv_system_init(void) | |||
| 662 | pnode = (paddr >> m_val) & pnode_mask; | 639 | pnode = (paddr >> m_val) & pnode_mask; |
| 663 | blade = boot_pnode_to_blade(pnode); | 640 | blade = boot_pnode_to_blade(pnode); |
| 664 | uv_node_to_blade[nid] = blade; | 641 | uv_node_to_blade[nid] = blade; |
| 642 | max_pnode = max(pnode, max_pnode); | ||
| 665 | } | 643 | } |
| 666 | 644 | ||
| 667 | map_gru_high(max_pnode); | 645 | map_gru_high(max_pnode); |
| 668 | map_mmr_high(max_pnode); | ||
| 669 | map_config_high(max_pnode); | ||
| 670 | map_mmioh_high(max_pnode); | 646 | map_mmioh_high(max_pnode); |
| 671 | 647 | ||
| 672 | uv_cpu_init(); | 648 | uv_cpu_init(); |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 79302e9a33a4..442b5508893f 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
| @@ -811,7 +811,7 @@ static int apm_do_idle(void) | |||
| 811 | u8 ret = 0; | 811 | u8 ret = 0; |
| 812 | int idled = 0; | 812 | int idled = 0; |
| 813 | int polling; | 813 | int polling; |
| 814 | int err; | 814 | int err = 0; |
| 815 | 815 | ||
| 816 | polling = !!(current_thread_info()->status & TS_POLLING); | 816 | polling = !!(current_thread_info()->status & TS_POLLING); |
| 817 | if (polling) { | 817 | if (polling) { |
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 96f7ac0bbf01..19ccf6d0dccf 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c | |||
| @@ -512,7 +512,7 @@ void __init efi_enter_virtual_mode(void) | |||
| 512 | && end_pfn <= max_pfn_mapped)) | 512 | && end_pfn <= max_pfn_mapped)) |
| 513 | va = __va(md->phys_addr); | 513 | va = __va(md->phys_addr); |
| 514 | else | 514 | else |
| 515 | va = efi_ioremap(md->phys_addr, size); | 515 | va = efi_ioremap(md->phys_addr, size, md->type); |
| 516 | 516 | ||
| 517 | md->virt_addr = (u64) (unsigned long) va; | 517 | md->virt_addr = (u64) (unsigned long) va; |
| 518 | 518 | ||
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c index 22c3b7828c50..ac0621a7ac3d 100644 --- a/arch/x86/kernel/efi_64.c +++ b/arch/x86/kernel/efi_64.c | |||
| @@ -98,10 +98,14 @@ void __init efi_call_phys_epilog(void) | |||
| 98 | early_runtime_code_mapping_set_exec(0); | 98 | early_runtime_code_mapping_set_exec(0); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size) | 101 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, |
| 102 | u32 type) | ||
| 102 | { | 103 | { |
| 103 | unsigned long last_map_pfn; | 104 | unsigned long last_map_pfn; |
| 104 | 105 | ||
| 106 | if (type == EFI_MEMORY_MAPPED_IO) | ||
| 107 | return ioremap(phys_addr, size); | ||
| 108 | |||
| 105 | last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); | 109 | last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); |
| 106 | if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) | 110 | if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) |
| 107 | return NULL; | 111 | return NULL; |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 8663afb56535..0d98a01cbdb2 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -602,7 +602,11 @@ ignore_int: | |||
| 602 | #endif | 602 | #endif |
| 603 | iret | 603 | iret |
| 604 | 604 | ||
| 605 | .section .cpuinit.data,"wa" | 605 | #ifndef CONFIG_HOTPLUG_CPU |
| 606 | __CPUINITDATA | ||
| 607 | #else | ||
| 608 | __REFDATA | ||
| 609 | #endif | ||
| 606 | .align 4 | 610 | .align 4 |
| 607 | ENTRY(initial_code) | 611 | ENTRY(initial_code) |
| 608 | .long i386_start_kernel | 612 | .long i386_start_kernel |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 508e982dd072..834c9da8bf9d 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
| 4 | #include <linux/pm.h> | 4 | #include <linux/pm.h> |
| 5 | #include <linux/efi.h> | 5 | #include <linux/efi.h> |
| 6 | #include <linux/dmi.h> | ||
| 6 | #include <acpi/reboot.h> | 7 | #include <acpi/reboot.h> |
| 7 | #include <asm/io.h> | 8 | #include <asm/io.h> |
| 8 | #include <asm/apic.h> | 9 | #include <asm/apic.h> |
| @@ -17,7 +18,6 @@ | |||
| 17 | #include <asm/cpu.h> | 18 | #include <asm/cpu.h> |
| 18 | 19 | ||
| 19 | #ifdef CONFIG_X86_32 | 20 | #ifdef CONFIG_X86_32 |
| 20 | # include <linux/dmi.h> | ||
| 21 | # include <linux/ctype.h> | 21 | # include <linux/ctype.h> |
| 22 | # include <linux/mc146818rtc.h> | 22 | # include <linux/mc146818rtc.h> |
| 23 | #else | 23 | #else |
| @@ -404,6 +404,38 @@ EXPORT_SYMBOL(machine_real_restart); | |||
| 404 | 404 | ||
| 405 | #endif /* CONFIG_X86_32 */ | 405 | #endif /* CONFIG_X86_32 */ |
| 406 | 406 | ||
| 407 | /* | ||
| 408 | * Apple MacBook5,2 (2009 MacBook) needs reboot=p | ||
| 409 | */ | ||
| 410 | static int __init set_pci_reboot(const struct dmi_system_id *d) | ||
| 411 | { | ||
| 412 | if (reboot_type != BOOT_CF9) { | ||
| 413 | reboot_type = BOOT_CF9; | ||
| 414 | printk(KERN_INFO "%s series board detected. " | ||
| 415 | "Selecting PCI-method for reboots.\n", d->ident); | ||
| 416 | } | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | |||
| 420 | static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { | ||
| 421 | { /* Handle problems with rebooting on Apple MacBook5,2 */ | ||
| 422 | .callback = set_pci_reboot, | ||
| 423 | .ident = "Apple MacBook", | ||
| 424 | .matches = { | ||
| 425 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
| 426 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"), | ||
| 427 | }, | ||
| 428 | }, | ||
| 429 | { } | ||
| 430 | }; | ||
| 431 | |||
| 432 | static int __init pci_reboot_init(void) | ||
| 433 | { | ||
| 434 | dmi_check_system(pci_reboot_dmi_table); | ||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | core_initcall(pci_reboot_init); | ||
| 438 | |||
| 407 | static inline void kb_wait(void) | 439 | static inline void kb_wait(void) |
| 408 | { | 440 | { |
| 409 | int i; | 441 | int i; |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 59f31d2dd435..78d185d797de 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
| @@ -393,8 +393,8 @@ SECTIONS | |||
| 393 | 393 | ||
| 394 | 394 | ||
| 395 | #ifdef CONFIG_X86_32 | 395 | #ifdef CONFIG_X86_32 |
| 396 | ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), | 396 | . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), |
| 397 | "kernel image bigger than KERNEL_IMAGE_SIZE") | 397 | "kernel image bigger than KERNEL_IMAGE_SIZE"); |
| 398 | #else | 398 | #else |
| 399 | /* | 399 | /* |
| 400 | * Per-cpu symbols which need to be offset from __per_cpu_load | 400 | * Per-cpu symbols which need to be offset from __per_cpu_load |
| @@ -407,12 +407,12 @@ INIT_PER_CPU(irq_stack_union); | |||
| 407 | /* | 407 | /* |
| 408 | * Build-time check on the image size: | 408 | * Build-time check on the image size: |
| 409 | */ | 409 | */ |
| 410 | ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), | 410 | . = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), |
| 411 | "kernel image bigger than KERNEL_IMAGE_SIZE") | 411 | "kernel image bigger than KERNEL_IMAGE_SIZE"); |
| 412 | 412 | ||
| 413 | #ifdef CONFIG_SMP | 413 | #ifdef CONFIG_SMP |
| 414 | ASSERT((per_cpu__irq_stack_union == 0), | 414 | . = ASSERT((per_cpu__irq_stack_union == 0), |
| 415 | "irq_stack_union is not at start of per-cpu area"); | 415 | "irq_stack_union is not at start of per-cpu area"); |
| 416 | #endif | 416 | #endif |
| 417 | 417 | ||
| 418 | #endif /* CONFIG_X86_32 */ | 418 | #endif /* CONFIG_X86_32 */ |
| @@ -420,7 +420,7 @@ ASSERT((per_cpu__irq_stack_union == 0), | |||
| 420 | #ifdef CONFIG_KEXEC | 420 | #ifdef CONFIG_KEXEC |
| 421 | #include <asm/kexec.h> | 421 | #include <asm/kexec.h> |
| 422 | 422 | ||
| 423 | ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, | 423 | . = ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, |
| 424 | "kexec control code size is too big") | 424 | "kexec control code size is too big"); |
| 425 | #endif | 425 | #endif |
| 426 | 426 | ||
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index 1440b9c0547e..caa24aca8115 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c | |||
| @@ -89,16 +89,13 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs) | |||
| 89 | rv.msrs = msrs; | 89 | rv.msrs = msrs; |
| 90 | rv.msr_no = msr_no; | 90 | rv.msr_no = msr_no; |
| 91 | 91 | ||
| 92 | preempt_disable(); | 92 | this_cpu = get_cpu(); |
| 93 | /* | 93 | |
| 94 | * FIXME: handle the CPU we're executing on separately for now until | 94 | if (cpumask_test_cpu(this_cpu, mask)) |
| 95 | * smp_call_function_many has been fixed to not skip it. | 95 | __rdmsr_on_cpu(&rv); |
| 96 | */ | ||
| 97 | this_cpu = raw_smp_processor_id(); | ||
| 98 | smp_call_function_single(this_cpu, __rdmsr_on_cpu, &rv, 1); | ||
| 99 | 96 | ||
| 100 | smp_call_function_many(mask, __rdmsr_on_cpu, &rv, 1); | 97 | smp_call_function_many(mask, __rdmsr_on_cpu, &rv, 1); |
| 101 | preempt_enable(); | 98 | put_cpu(); |
| 102 | } | 99 | } |
| 103 | EXPORT_SYMBOL(rdmsr_on_cpus); | 100 | EXPORT_SYMBOL(rdmsr_on_cpus); |
| 104 | 101 | ||
| @@ -121,16 +118,13 @@ void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs) | |||
| 121 | rv.msrs = msrs; | 118 | rv.msrs = msrs; |
| 122 | rv.msr_no = msr_no; | 119 | rv.msr_no = msr_no; |
| 123 | 120 | ||
| 124 | preempt_disable(); | 121 | this_cpu = get_cpu(); |
| 125 | /* | 122 | |
| 126 | * FIXME: handle the CPU we're executing on separately for now until | 123 | if (cpumask_test_cpu(this_cpu, mask)) |
| 127 | * smp_call_function_many has been fixed to not skip it. | 124 | __wrmsr_on_cpu(&rv); |
| 128 | */ | ||
| 129 | this_cpu = raw_smp_processor_id(); | ||
| 130 | smp_call_function_single(this_cpu, __wrmsr_on_cpu, &rv, 1); | ||
| 131 | 125 | ||
| 132 | smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1); | 126 | smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1); |
| 133 | preempt_enable(); | 127 | put_cpu(); |
| 134 | } | 128 | } |
| 135 | EXPORT_SYMBOL(wrmsr_on_cpus); | 129 | EXPORT_SYMBOL(wrmsr_on_cpus); |
| 136 | 130 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 1b734d7a8966..7e600c1962db 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -591,9 +591,12 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) | |||
| 591 | unsigned int level; | 591 | unsigned int level; |
| 592 | pte_t *kpte, old_pte; | 592 | pte_t *kpte, old_pte; |
| 593 | 593 | ||
| 594 | if (cpa->flags & CPA_PAGES_ARRAY) | 594 | if (cpa->flags & CPA_PAGES_ARRAY) { |
| 595 | address = (unsigned long)page_address(cpa->pages[cpa->curpage]); | 595 | struct page *page = cpa->pages[cpa->curpage]; |
| 596 | else if (cpa->flags & CPA_ARRAY) | 596 | if (unlikely(PageHighMem(page))) |
| 597 | return 0; | ||
| 598 | address = (unsigned long)page_address(page); | ||
| 599 | } else if (cpa->flags & CPA_ARRAY) | ||
| 597 | address = cpa->vaddr[cpa->curpage]; | 600 | address = cpa->vaddr[cpa->curpage]; |
| 598 | else | 601 | else |
| 599 | address = *cpa->vaddr; | 602 | address = *cpa->vaddr; |
| @@ -697,9 +700,12 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
| 697 | * No need to redo, when the primary call touched the direct | 700 | * No need to redo, when the primary call touched the direct |
| 698 | * mapping already: | 701 | * mapping already: |
| 699 | */ | 702 | */ |
| 700 | if (cpa->flags & CPA_PAGES_ARRAY) | 703 | if (cpa->flags & CPA_PAGES_ARRAY) { |
| 701 | vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]); | 704 | struct page *page = cpa->pages[cpa->curpage]; |
| 702 | else if (cpa->flags & CPA_ARRAY) | 705 | if (unlikely(PageHighMem(page))) |
| 706 | return 0; | ||
| 707 | vaddr = (unsigned long)page_address(page); | ||
| 708 | } else if (cpa->flags & CPA_ARRAY) | ||
| 703 | vaddr = cpa->vaddr[cpa->curpage]; | 709 | vaddr = cpa->vaddr[cpa->curpage]; |
| 704 | else | 710 | else |
| 705 | vaddr = *cpa->vaddr; | 711 | vaddr = *cpa->vaddr; |
| @@ -997,12 +1003,15 @@ EXPORT_SYMBOL(set_memory_array_uc); | |||
| 997 | int _set_memory_wc(unsigned long addr, int numpages) | 1003 | int _set_memory_wc(unsigned long addr, int numpages) |
| 998 | { | 1004 | { |
| 999 | int ret; | 1005 | int ret; |
| 1006 | unsigned long addr_copy = addr; | ||
| 1007 | |||
| 1000 | ret = change_page_attr_set(&addr, numpages, | 1008 | ret = change_page_attr_set(&addr, numpages, |
| 1001 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); | 1009 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); |
| 1002 | |||
| 1003 | if (!ret) { | 1010 | if (!ret) { |
| 1004 | ret = change_page_attr_set(&addr, numpages, | 1011 | ret = change_page_attr_set_clr(&addr_copy, numpages, |
| 1005 | __pgprot(_PAGE_CACHE_WC), 0); | 1012 | __pgprot(_PAGE_CACHE_WC), |
| 1013 | __pgprot(_PAGE_CACHE_MASK), | ||
| 1014 | 0, 0, NULL); | ||
| 1006 | } | 1015 | } |
| 1007 | return ret; | 1016 | return ret; |
| 1008 | } | 1017 | } |
| @@ -1119,7 +1128,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) | |||
| 1119 | int free_idx; | 1128 | int free_idx; |
| 1120 | 1129 | ||
| 1121 | for (i = 0; i < addrinarray; i++) { | 1130 | for (i = 0; i < addrinarray; i++) { |
| 1122 | start = (unsigned long)page_address(pages[i]); | 1131 | if (PageHighMem(pages[i])) |
| 1132 | continue; | ||
| 1133 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
| 1123 | end = start + PAGE_SIZE; | 1134 | end = start + PAGE_SIZE; |
| 1124 | if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) | 1135 | if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) |
| 1125 | goto err_out; | 1136 | goto err_out; |
| @@ -1132,7 +1143,9 @@ int set_pages_array_uc(struct page **pages, int addrinarray) | |||
| 1132 | err_out: | 1143 | err_out: |
| 1133 | free_idx = i; | 1144 | free_idx = i; |
| 1134 | for (i = 0; i < free_idx; i++) { | 1145 | for (i = 0; i < free_idx; i++) { |
| 1135 | start = (unsigned long)page_address(pages[i]); | 1146 | if (PageHighMem(pages[i])) |
| 1147 | continue; | ||
| 1148 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
| 1136 | end = start + PAGE_SIZE; | 1149 | end = start + PAGE_SIZE; |
| 1137 | free_memtype(start, end); | 1150 | free_memtype(start, end); |
| 1138 | } | 1151 | } |
| @@ -1161,7 +1174,9 @@ int set_pages_array_wb(struct page **pages, int addrinarray) | |||
| 1161 | return retval; | 1174 | return retval; |
| 1162 | 1175 | ||
| 1163 | for (i = 0; i < addrinarray; i++) { | 1176 | for (i = 0; i < addrinarray; i++) { |
| 1164 | start = (unsigned long)page_address(pages[i]); | 1177 | if (PageHighMem(pages[i])) |
| 1178 | continue; | ||
| 1179 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | ||
| 1165 | end = start + PAGE_SIZE; | 1180 | end = start + PAGE_SIZE; |
| 1166 | free_memtype(start, end); | 1181 | free_memtype(start, end); |
| 1167 | } | 1182 | } |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index af8f9650058c..ed34f5e35999 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
| @@ -329,7 +329,6 @@ void __init reserve_top_address(unsigned long reserve) | |||
| 329 | printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", | 329 | printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", |
| 330 | (int)-reserve); | 330 | (int)-reserve); |
| 331 | __FIXADDR_TOP = -reserve - PAGE_SIZE; | 331 | __FIXADDR_TOP = -reserve - PAGE_SIZE; |
| 332 | __VMALLOC_RESERVE += reserve; | ||
| 333 | #endif | 332 | #endif |
| 334 | } | 333 | } |
| 335 | 334 | ||
