Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+70 -62
+2 -1
arch/sparc/include/asm/oplib_64.h
··· 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);
+2
arch/sparc/include/asm/setup.h
··· 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);
-3
arch/sparc/kernel/entry.h
··· 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
+4 -36
arch/sparc/kernel/head_64.S
··· 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 ··· 704 706 nop 705 707 #endif 706 708 707 - mov %l6, %o1 ! OpenPROM stack 708 709 call prom_init 709 710 mov %l7, %o0 ! OpenPROM cif handler 710 711 711 - /* Initialize current_thread_info()->cpu as early as possible. 712 - * In order to do that accurately we have to patch up the get_cpuid() 713 - * assembler sequences. And that, in turn, requires that we know 714 - * if we are on a Starfire box or not. While we're here, patch up 715 - * the sun4v sequences as well. 712 + /* To create a one-register-window buffer between the kernel's 713 + * initial stack and the last stack frame we use from the firmware, 714 + * do the rest of the boot from a C helper function. 716 715 */ 717 - call check_if_starfire 718 - nop 719 - call per_cpu_patch 720 - nop 721 - call sun4v_patch 722 - nop 723 - 724 - #ifdef CONFIG_SMP 725 - call hard_smp_processor_id 726 - nop 727 - cmp %o0, NR_CPUS 728 - blu,pt %xcc, 1f 729 - nop 730 - call boot_cpu_id_too_large 731 - nop 732 - /* Not reached... */ 733 - 734 - 1: 735 - #else 736 - mov 0, %o0 737 - #endif 738 - sth %o0, [%g6 + TI_CPU] 739 - 740 - call prom_init_report 741 - nop 742 - 743 - /* Off we go.... */ 744 - call start_kernel 716 + call start_early_boot 745 717 nop 746 718 /* Not reached... */ 747 719
-1
arch/sparc/kernel/hvtramp.S
··· 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
+20 -8
arch/sparc/kernel/setup_64.c
··· 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> ··· 163 162 164 163 static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; 165 164 166 - void __init per_cpu_patch(void) 165 + static void __init per_cpu_patch(void) 167 166 { 168 167 struct cpuid_patch_entry *p; 169 168 unsigned long ver; ··· 255 254 } 256 255 } 257 256 258 - void __init sun4v_patch(void) 257 + static void __init sun4v_patch(void) 259 258 { 260 259 extern void sun4v_hvapi_init(void); 261 260 ··· 324 323 } 325 324 } 326 325 327 - #ifdef CONFIG_SMP 328 - void __init boot_cpu_id_too_large(int cpu) 326 + void __init start_early_boot(void) 329 327 { 330 - prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", 331 - cpu, NR_CPUS); 332 - prom_halt(); 328 + int cpu; 329 + 330 + check_if_starfire(); 331 + per_cpu_patch(); 332 + sun4v_patch(); 333 + 334 + cpu = hard_smp_processor_id(); 335 + if (cpu >= NR_CPUS) { 336 + prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", 337 + cpu, NR_CPUS); 338 + prom_halt(); 339 + } 340 + current_thread_info()->cpu = cpu; 341 + 342 + prom_init_report(); 343 + start_kernel(); 333 344 } 334 - #endif 335 345 336 346 /* On Ultra, we support all of the v8 capabilities. */ 337 347 unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
+7 -5
arch/sparc/kernel/trampoline_64.S
··· 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: ··· 397 394 sllx %g5, THREAD_SHIFT, %g5 398 395 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 399 396 add %g6, %g5, %sp 400 - mov 0, %fp 401 397 402 398 rdpr %pstate, %o1 403 399 or %o1, PSTATE_IE, %o1
+30
arch/sparc/mm/gup.c
··· 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 {
+2 -3
arch/sparc/prom/cif.S
··· 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
+3 -3
arch/sparc/prom/init_64.c
··· 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)
-2
arch/sparc/prom/p1275.c
··· 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); ··· 51 52 void prom_cif_init(void *cif_handler, void *cif_stack) 52 53 { 53 54 p1275buf.prom_cif_handler = (void (*)(long *))cif_handler; 54 - p1275buf.prom_cif_stack = (unsigned long)cif_stack; 55 55 }