Commit 83da00fbc0c57ce6f84455156a2e3cc057fe7344

Authored by Linus Torvalds

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.

Showing 11 changed files Side-by-side Diff

arch/sparc/include/asm/oplib_64.h
... ... @@ -62,7 +62,8 @@
62 62 /* You must call prom_init() before using any of the library services,
63 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 68 /* Boot argument acquisition, returns the boot command line string. */
68 69 char *prom_getbootargs(void);
arch/sparc/include/asm/setup.h
... ... @@ -48,6 +48,8 @@
48 48 #endif
49 49  
50 50 #ifdef CONFIG_SPARC64
  51 +void __init start_early_boot(void);
  52 +
51 53 /* unaligned_64.c */
52 54 int handle_ldf_stq(u32 insn, struct pt_regs *regs);
53 55 void handle_ld_nf(u32 insn, struct pt_regs *regs);
arch/sparc/kernel/entry.h
... ... @@ -65,13 +65,10 @@
65 65 extern struct pause_patch_entry __pause_3insn_patch,
66 66 __pause_3insn_patch_end;
67 67  
68   -void __init per_cpu_patch(void);
69 68 void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
70 69 struct sun4v_1insn_patch_entry *);
71 70 void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
72 71 struct sun4v_2insn_patch_entry *);
73   -void __init sun4v_patch(void);
74   -void __init boot_cpu_id_too_large(int cpu);
75 72 extern unsigned int dcache_parity_tl1_occurred;
76 73 extern unsigned int icache_parity_tl1_occurred;
77 74  
arch/sparc/kernel/head_64.S
... ... @@ -672,14 +672,12 @@
672 672 sethi %hi(init_thread_union), %g6
673 673 or %g6, %lo(init_thread_union), %g6
674 674 ldx [%g6 + TI_TASK], %g4
675   - mov %sp, %l6
676 675  
677 676 wr %g0, ASI_P, %asi
678 677 mov 1, %g1
679 678 sllx %g1, THREAD_SHIFT, %g1
680 679 sub %g1, (STACKFRAME_SZ + STACK_BIAS), %g1
681 680 add %g6, %g1, %sp
682   - mov 0, %fp
683 681  
684 682 /* Set per-cpu pointer initially to zero, this makes
685 683 * the boot-cpu use the in-kernel-image per-cpu areas
686 684  
687 685  
... ... @@ -706,44 +704,14 @@
706 704 nop
707 705 #endif
708 706  
709   - mov %l6, %o1 ! OpenPROM stack
710 707 call prom_init
711 708 mov %l7, %o0 ! OpenPROM cif handler
712 709  
713   - /* Initialize current_thread_info()->cpu as early as possible.
714   - * In order to do that accurately we have to patch up the get_cpuid()
715   - * assembler sequences. And that, in turn, requires that we know
716   - * if we are on a Starfire box or not. While we're here, patch up
717   - * the sun4v sequences as well.
  710 + /* To create a one-register-window buffer between the kernel's
  711 + * initial stack and the last stack frame we use from the firmware,
  712 + * do the rest of the boot from a C helper function.
718 713 */
719   - call check_if_starfire
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
  714 + call start_early_boot
747 715 nop
748 716 /* Not reached... */
749 717  
arch/sparc/kernel/hvtramp.S
... ... @@ -109,7 +109,6 @@
109 109 sllx %g5, THREAD_SHIFT, %g5
110 110 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
111 111 add %g6, %g5, %sp
112   - mov 0, %fp
113 112  
114 113 call init_irqwork_curcpu
115 114 nop
arch/sparc/kernel/setup_64.c
... ... @@ -30,6 +30,7 @@
30 30 #include <linux/cpu.h>
31 31 #include <linux/initrd.h>
32 32 #include <linux/module.h>
  33 +#include <linux/start_kernel.h>
33 34  
34 35 #include <asm/io.h>
35 36 #include <asm/processor.h>
... ... @@ -162,7 +163,7 @@
162 163  
163 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 168 struct cpuid_patch_entry *p;
168 169 unsigned long ver;
... ... @@ -254,7 +255,7 @@
254 255 }
255 256 }
256 257  
257   -void __init sun4v_patch(void)
  258 +static void __init sun4v_patch(void)
258 259 {
259 260 extern void sun4v_hvapi_init(void);
260 261  
261 262  
262 263  
... ... @@ -323,14 +324,25 @@
323 324 }
324 325 }
325 326  
326   -#ifdef CONFIG_SMP
327   -void __init boot_cpu_id_too_large(int cpu)
  327 +void __init start_early_boot(void)
328 328 {
329   - prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n",
330   - cpu, NR_CPUS);
331   - prom_halt();
  329 + int cpu;
  330 +
  331 + check_if_starfire();
  332 + per_cpu_patch();
  333 + sun4v_patch();
  334 +
  335 + cpu = hard_smp_processor_id();
  336 + if (cpu >= NR_CPUS) {
  337 + prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n",
  338 + cpu, NR_CPUS);
  339 + prom_halt();
  340 + }
  341 + current_thread_info()->cpu = cpu;
  342 +
  343 + prom_init_report();
  344 + start_kernel();
332 345 }
333   -#endif
334 346  
335 347 /* On Ultra, we support all of the v8 capabilities. */
336 348 unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
arch/sparc/kernel/trampoline_64.S
... ... @@ -109,10 +109,13 @@
109 109 brnz,pn %g1, 1b
110 110 nop
111 111  
112   - sethi %hi(p1275buf), %g2
113   - or %g2, %lo(p1275buf), %g2
114   - ldx [%g2 + 0x10], %l2
115   - add %l2, -(192 + 128), %sp
  112 + /* Get onto temporary stack which will be in the locked
  113 + * kernel image.
  114 + */
  115 + sethi %hi(tramp_stack), %g1
  116 + or %g1, %lo(tramp_stack), %g1
  117 + add %g1, TRAMP_STACK_SIZE, %g1
  118 + sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
116 119 flushw
117 120  
118 121 /* Setup the loop variables:
... ... @@ -394,7 +397,6 @@
394 397 sllx %g5, THREAD_SHIFT, %g5
395 398 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
396 399 add %g6, %g5, %sp
397   - mov 0, %fp
398 400  
399 401 rdpr %pstate, %o1
400 402 or %o1, PSTATE_IE, %o1
... ... @@ -160,6 +160,36 @@
160 160 return 1;
161 161 }
162 162  
  163 +int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
  164 + struct page **pages)
  165 +{
  166 + struct mm_struct *mm = current->mm;
  167 + unsigned long addr, len, end;
  168 + unsigned long next, flags;
  169 + pgd_t *pgdp;
  170 + int nr = 0;
  171 +
  172 + start &= PAGE_MASK;
  173 + addr = start;
  174 + len = (unsigned long) nr_pages << PAGE_SHIFT;
  175 + end = start + len;
  176 +
  177 + local_irq_save(flags);
  178 + pgdp = pgd_offset(mm, addr);
  179 + do {
  180 + pgd_t pgd = *pgdp;
  181 +
  182 + next = pgd_addr_end(addr, end);
  183 + if (pgd_none(pgd))
  184 + break;
  185 + if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
  186 + break;
  187 + } while (pgdp++, addr = next, addr != end);
  188 + local_irq_restore(flags);
  189 +
  190 + return nr;
  191 +}
  192 +
163 193 int get_user_pages_fast(unsigned long start, int nr_pages, int write,
164 194 struct page **pages)
165 195 {
arch/sparc/prom/cif.S
... ... @@ -11,11 +11,10 @@
11 11 .text
12 12 .globl prom_cif_direct
13 13 prom_cif_direct:
  14 + save %sp, -192, %sp
14 15 sethi %hi(p1275buf), %o1
15 16 or %o1, %lo(p1275buf), %o1
16   - ldx [%o1 + 0x0010], %o2 ! prom_cif_stack
17   - save %o2, -192, %sp
18   - ldx [%i1 + 0x0008], %l2 ! prom_cif_handler
  17 + ldx [%o1 + 0x0008], %l2 ! prom_cif_handler
19 18 mov %g4, %l0
20 19 mov %g5, %l1
21 20 mov %g6, %l3
arch/sparc/prom/init_64.c
... ... @@ -26,13 +26,13 @@
26 26 * It gets passed the pointer to the PROM vector.
27 27 */
28 28  
29   -extern void prom_cif_init(void *, void *);
  29 +extern void prom_cif_init(void *);
30 30  
31   -void __init prom_init(void *cif_handler, void *cif_stack)
  31 +void __init prom_init(void *cif_handler)
32 32 {
33 33 phandle node;
34 34  
35   - prom_cif_init(cif_handler, cif_stack);
  35 + prom_cif_init(cif_handler);
36 36  
37 37 prom_chosen_node = prom_finddevice(prom_chosen_path);
38 38 if (!prom_chosen_node || (s32)prom_chosen_node == -1)
arch/sparc/prom/p1275.c
... ... @@ -20,7 +20,6 @@
20 20 struct {
21 21 long prom_callback; /* 0x00 */
22 22 void (*prom_cif_handler)(long *); /* 0x08 */
23   - unsigned long prom_cif_stack; /* 0x10 */
24 23 } p1275buf;
25 24  
26 25 extern void prom_world(int);
... ... @@ -52,6 +51,5 @@
52 51 void prom_cif_init(void *cif_handler, void *cif_stack)
53 52 {
54 53 p1275buf.prom_cif_handler = (void (*)(long *))cif_handler;
55   - p1275buf.prom_cif_stack = (unsigned long)cif_stack;
56 54 }