diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-24 15:45:47 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-24 15:45:47 -0400 |
| commit | 83da00fbc0c57ce6f84455156a2e3cc057fe7344 (patch) | |
| tree | fac652b63aac0bfade55cd8113afe668f00c9cd8 | |
| parent | 96971e9aa9578322648b2de593fd4863f3d9fc39 (diff) | |
| parent | 06090e8ed89ea2113a236befb41f71d51f100e60 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull two sparc fixes from David Miller:
1) Fix boots with gcc-4.9 compiled sparc64 kernels.
2) Add missing __get_user_pages_fast() on sparc64 to fix hangs on
futexes used in transparent hugepage areas.
It's really idiotic to have a weak symbolled fallback that just
returns zero, and causes this kind of bug. There should be no
backup implementation and the link should fail if the architecture
fails to provide __get_user_pages_fast() and supports transparent
hugepages.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Implement __get_user_pages_fast().
sparc64: Fix register corruption in top-most kernel stack frame during boot.
| -rw-r--r-- | arch/sparc/include/asm/oplib_64.h | 3 | ||||
| -rw-r--r-- | arch/sparc/include/asm/setup.h | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/entry.h | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/head_64.S | 40 | ||||
| -rw-r--r-- | arch/sparc/kernel/hvtramp.S | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/setup_64.c | 28 | ||||
| -rw-r--r-- | arch/sparc/kernel/trampoline_64.S | 12 | ||||
| -rw-r--r-- | arch/sparc/mm/gup.c | 30 | ||||
| -rw-r--r-- | arch/sparc/prom/cif.S | 5 | ||||
| -rw-r--r-- | arch/sparc/prom/init_64.c | 6 | ||||
| -rw-r--r-- | arch/sparc/prom/p1275.c | 2 |
11 files changed, 70 insertions, 62 deletions
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index f34682430fcf..2e3a4add8591 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
| @@ -62,7 +62,8 @@ struct linux_mem_p1275 { | |||
| 62 | /* You must call prom_init() before using any of the library services, | 62 | /* You must call prom_init() before using any of the library services, |
| 63 | * preferably as early as possible. Pass it the romvec pointer. | 63 | * preferably as early as possible. Pass it the romvec pointer. |
| 64 | */ | 64 | */ |
| 65 | void prom_init(void *cif_handler, void *cif_stack); | 65 | void prom_init(void *cif_handler); |
| 66 | void prom_init_report(void); | ||
| 66 | 67 | ||
| 67 | /* Boot argument acquisition, returns the boot command line string. */ | 68 | /* Boot argument acquisition, returns the boot command line string. */ |
| 68 | char *prom_getbootargs(void); | 69 | char *prom_getbootargs(void); |
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h index f5fffd84d0dd..29d64b1758ed 100644 --- a/arch/sparc/include/asm/setup.h +++ b/arch/sparc/include/asm/setup.h | |||
| @@ -48,6 +48,8 @@ unsigned long safe_compute_effective_address(struct pt_regs *, unsigned int); | |||
| 48 | #endif | 48 | #endif |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_SPARC64 | 50 | #ifdef CONFIG_SPARC64 |
| 51 | void __init start_early_boot(void); | ||
| 52 | |||
| 51 | /* unaligned_64.c */ | 53 | /* unaligned_64.c */ |
| 52 | int handle_ldf_stq(u32 insn, struct pt_regs *regs); | 54 | int handle_ldf_stq(u32 insn, struct pt_regs *regs); |
| 53 | void handle_ld_nf(u32 insn, struct pt_regs *regs); | 55 | void handle_ld_nf(u32 insn, struct pt_regs *regs); |
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index ebaba6167dd4..88d322b67fac 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
| @@ -65,13 +65,10 @@ struct pause_patch_entry { | |||
| 65 | extern struct pause_patch_entry __pause_3insn_patch, | 65 | extern struct pause_patch_entry __pause_3insn_patch, |
| 66 | __pause_3insn_patch_end; | 66 | __pause_3insn_patch_end; |
| 67 | 67 | ||
| 68 | void __init per_cpu_patch(void); | ||
| 69 | void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, | 68 | void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, |
| 70 | struct sun4v_1insn_patch_entry *); | 69 | struct sun4v_1insn_patch_entry *); |
| 71 | void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, | 70 | void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, |
| 72 | struct sun4v_2insn_patch_entry *); | 71 | struct sun4v_2insn_patch_entry *); |
| 73 | void __init sun4v_patch(void); | ||
| 74 | void __init boot_cpu_id_too_large(int cpu); | ||
| 75 | extern unsigned int dcache_parity_tl1_occurred; | 72 | extern unsigned int dcache_parity_tl1_occurred; |
| 76 | extern unsigned int icache_parity_tl1_occurred; | 73 | extern unsigned int icache_parity_tl1_occurred; |
| 77 | 74 | ||
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 4fdeb8040d4d..3d61fcae7ee3 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S | |||
| @@ -672,14 +672,12 @@ tlb_fixup_done: | |||
| 672 | sethi %hi(init_thread_union), %g6 | 672 | sethi %hi(init_thread_union), %g6 |
| 673 | or %g6, %lo(init_thread_union), %g6 | 673 | or %g6, %lo(init_thread_union), %g6 |
| 674 | ldx [%g6 + TI_TASK], %g4 | 674 | ldx [%g6 + TI_TASK], %g4 |
| 675 | mov %sp, %l6 | ||
| 676 | 675 | ||
| 677 | wr %g0, ASI_P, %asi | 676 | wr %g0, ASI_P, %asi |
| 678 | mov 1, %g1 | 677 | mov 1, %g1 |
| 679 | sllx %g1, THREAD_SHIFT, %g1 | 678 | sllx %g1, THREAD_SHIFT, %g1 |
| 680 | sub %g1, (STACKFRAME_SZ + STACK_BIAS), %g1 | 679 | sub %g1, (STACKFRAME_SZ + STACK_BIAS), %g1 |
| 681 | add %g6, %g1, %sp | 680 | add %g6, %g1, %sp |
| 682 | mov 0, %fp | ||
| 683 | 681 | ||
| 684 | /* Set per-cpu pointer initially to zero, this makes | 682 | /* Set per-cpu pointer initially to zero, this makes |
| 685 | * the boot-cpu use the in-kernel-image per-cpu areas | 683 | * the boot-cpu use the in-kernel-image per-cpu areas |
| @@ -706,44 +704,14 @@ tlb_fixup_done: | |||
| 706 | nop | 704 | nop |
| 707 | #endif | 705 | #endif |
| 708 | 706 | ||
| 709 | mov %l6, %o1 ! OpenPROM stack | ||
| 710 | call prom_init | 707 | call prom_init |
| 711 | mov %l7, %o0 ! OpenPROM cif handler | 708 | mov %l7, %o0 ! OpenPROM cif handler |
| 712 | 709 | ||
| 713 | /* Initialize current_thread_info()->cpu as early as possible. | 710 | /* To create a one-register-window buffer between the kernel's |
| 714 | * In order to do that accurately we have to patch up the get_cpuid() | 711 | * initial stack and the last stack frame we use from the firmware, |
| 715 | * assembler sequences. And that, in turn, requires that we know | 712 | * do the rest of the boot from a C helper function. |
| 716 | * if we are on a Starfire box or not. While we're here, patch up | ||
| 717 | * the sun4v sequences as well. | ||
| 718 | */ | 713 | */ |
| 719 | call check_if_starfire | 714 | call start_early_boot |
| 720 | nop | ||
| 721 | call per_cpu_patch | ||
| 722 | nop | ||
| 723 | call sun4v_patch | ||
| 724 | nop | ||
| 725 | |||
| 726 | #ifdef CONFIG_SMP | ||
| 727 | call hard_smp_processor_id | ||
| 728 | nop | ||
| 729 | cmp %o0, NR_CPUS | ||
| 730 | blu,pt %xcc, 1f | ||
| 731 | nop | ||
| 732 | call boot_cpu_id_too_large | ||
| 733 | nop | ||
| 734 | /* Not reached... */ | ||
| 735 | |||
| 736 | 1: | ||
| 737 | #else | ||
| 738 | mov 0, %o0 | ||
| 739 | #endif | ||
| 740 | sth %o0, [%g6 + TI_CPU] | ||
| 741 | |||
| 742 | call prom_init_report | ||
| 743 | nop | ||
| 744 | |||
| 745 | /* Off we go.... */ | ||
| 746 | call start_kernel | ||
| 747 | nop | 715 | nop |
| 748 | /* Not reached... */ | 716 | /* Not reached... */ |
| 749 | 717 | ||
diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S index b7ddcdd1dea9..cdbfec299f2f 100644 --- a/arch/sparc/kernel/hvtramp.S +++ b/arch/sparc/kernel/hvtramp.S | |||
| @@ -109,7 +109,6 @@ hv_cpu_startup: | |||
| 109 | sllx %g5, THREAD_SHIFT, %g5 | 109 | sllx %g5, THREAD_SHIFT, %g5 |
| 110 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 | 110 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 |
| 111 | add %g6, %g5, %sp | 111 | add %g6, %g5, %sp |
| 112 | mov 0, %fp | ||
| 113 | 112 | ||
| 114 | call init_irqwork_curcpu | 113 | call init_irqwork_curcpu |
| 115 | nop | 114 | nop |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index e629b8377587..c38d19fc27ba 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/cpu.h> | 30 | #include <linux/cpu.h> |
| 31 | #include <linux/initrd.h> | 31 | #include <linux/initrd.h> |
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/start_kernel.h> | ||
| 33 | 34 | ||
| 34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 35 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
| @@ -162,7 +163,7 @@ char reboot_command[COMMAND_LINE_SIZE]; | |||
| 162 | 163 | ||
| 163 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; | 164 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; |
| 164 | 165 | ||
| 165 | void __init per_cpu_patch(void) | 166 | static void __init per_cpu_patch(void) |
| 166 | { | 167 | { |
| 167 | struct cpuid_patch_entry *p; | 168 | struct cpuid_patch_entry *p; |
| 168 | unsigned long ver; | 169 | unsigned long ver; |
| @@ -254,7 +255,7 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start, | |||
| 254 | } | 255 | } |
| 255 | } | 256 | } |
| 256 | 257 | ||
| 257 | void __init sun4v_patch(void) | 258 | static void __init sun4v_patch(void) |
| 258 | { | 259 | { |
| 259 | extern void sun4v_hvapi_init(void); | 260 | extern void sun4v_hvapi_init(void); |
| 260 | 261 | ||
| @@ -323,14 +324,25 @@ static void __init pause_patch(void) | |||
| 323 | } | 324 | } |
| 324 | } | 325 | } |
| 325 | 326 | ||
| 326 | #ifdef CONFIG_SMP | 327 | |
