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 branch 'parisc-4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc fixes from Helge Deller:

- Fix printk time stamps on SMP systems which got wrong due to a patch
which was added during the merge window

- Fix two bugs in the stack backtrace code: Races in module unloading
and possible invalid accesses to memory due to wrong instruction
decoding (Mikulas Patocka)

- Fix userspace crash when syscalls access invalid unaligned userspace
addresses. Those syscalls will now return EFAULT as expected.
(tagged for stable kernel series)

* 'parisc-4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Move die_if_kernel() prototype into traps.h header
parisc: Fix pagefault crash in unaligned __get_user() call
parisc: Fix printk time during boot
parisc: Fix backtrace on PA-RISC

+29 -18
+2
arch/parisc/include/asm/traps.h
··· 8 8 void parisc_terminate(char *msg, struct pt_regs *regs, 9 9 int code, unsigned long offset) __noreturn __cold; 10 10 11 + void die_if_kernel(char *str, struct pt_regs *regs, long err); 12 + 11 13 /* mm/fault.c */ 12 14 void do_page_fault(struct pt_regs *regs, unsigned long code, 13 15 unsigned long address);
+3 -2
arch/parisc/kernel/processor.c
··· 324 324 per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision; 325 325 per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model; 326 326 327 - printk(KERN_INFO "FP[%d] enabled: Rev %ld Model %ld\n", 328 - cpunum, coproc_cfg.revision, coproc_cfg.model); 327 + if (cpunum == 0) 328 + printk(KERN_INFO "FP[%d] enabled: Rev %ld Model %ld\n", 329 + cpunum, coproc_cfg.revision, coproc_cfg.model); 329 330 330 331 /* 331 332 ** store status register to stack (hopefully aligned)
-5
arch/parisc/kernel/time.c
··· 309 309 clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz, 310 310 NSEC_PER_MSEC, 0); 311 311 312 - #if defined(CONFIG_HAVE_UNSTABLE_SCHED_CLOCK) && defined(CONFIG_64BIT) 313 - /* At bootup only one 64bit CPU is online and cr16 is "stable" */ 314 - set_sched_clock_stable(); 315 - #endif 316 - 317 312 start_cpu_itimer(); /* get CPU 0 started */ 318 313 319 314 /* register at clocksource framework */
+10 -3
arch/parisc/kernel/unaligned.c
··· 28 28 #include <linux/ratelimit.h> 29 29 #include <asm/uaccess.h> 30 30 #include <asm/hardirq.h> 31 + #include <asm/traps.h> 31 32 32 33 /* #define DEBUG_UNALIGNED 1 */ 33 34 ··· 130 129 #define ERR_PAGEFAULT -2 131 130 132 131 int unaligned_enabled __read_mostly = 1; 133 - 134 - void die_if_kernel (char *str, struct pt_regs *regs, long err); 135 132 136 133 static int emulate_ldh(struct pt_regs *regs, int toreg) 137 134 { ··· 665 666 break; 666 667 } 667 668 668 - if (modify && R1(regs->iir)) 669 + if (ret == 0 && modify && R1(regs->iir)) 669 670 regs->gr[R1(regs->iir)] = newbase; 670 671 671 672 ··· 676 677 677 678 if (ret) 678 679 { 680 + /* 681 + * The unaligned handler failed. 682 + * If we were called by __get_user() or __put_user() jump 683 + * to it's exception fixup handler instead of crashing. 684 + */ 685 + if (!user_mode(regs) && fixup_exception(regs)) 686 + return; 687 + 679 688 printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret); 680 689 die_if_kernel("Unaligned data reference", regs, 28); 681 690
+14 -8
arch/parisc/kernel/unwind.c
··· 75 75 if (addr >= kernel_unwind_table.start && 76 76 addr <= kernel_unwind_table.end) 77 77 e = find_unwind_entry_in_table(&kernel_unwind_table, addr); 78 - else 78 + else { 79 + unsigned long flags; 80 + 81 + spin_lock_irqsave(&unwind_lock, flags); 79 82 list_for_each_entry(table, &unwind_tables, list) { 80 83 if (addr >= table->start && 81 84 addr <= table->end) ··· 89 86 break; 90 87 } 91 88 } 89 + spin_unlock_irqrestore(&unwind_lock, flags); 90 + } 92 91 93 92 return e; 94 93 } ··· 308 303 309 304 insn = *(unsigned int *)npc; 310 305 311 - if ((insn & 0xffffc000) == 0x37de0000 || 312 - (insn & 0xffe00000) == 0x6fc00000) { 306 + if ((insn & 0xffffc001) == 0x37de0000 || 307 + (insn & 0xffe00001) == 0x6fc00000) { 313 308 /* ldo X(sp), sp, or stwm X,D(sp) */ 314 - frame_size += (insn & 0x1 ? -1 << 13 : 0) | 315 - ((insn & 0x3fff) >> 1); 309 + frame_size += (insn & 0x3fff) >> 1; 316 310 dbg("analyzing func @ %lx, insn=%08x @ " 317 311 "%lx, frame_size = %ld\n", info->ip, 318 312 insn, npc, frame_size); 319 - } else if ((insn & 0xffe00008) == 0x73c00008) { 313 + } else if ((insn & 0xffe00009) == 0x73c00008) { 320 314 /* std,ma X,D(sp) */ 321 - frame_size += (insn & 0x1 ? -1 << 13 : 0) | 322 - (((insn >> 4) & 0x3ff) << 3); 315 + frame_size += ((insn >> 4) & 0x3ff) << 3; 323 316 dbg("analyzing func @ %lx, insn=%08x @ " 324 317 "%lx, frame_size = %ld\n", info->ip, 325 318 insn, npc, frame_size); ··· 335 332 "-16(sp) @ %lx\n", info->ip, npc); 336 333 } 337 334 } 335 + 336 + if (frame_size > e->Total_frame_size << 3) 337 + frame_size = e->Total_frame_size << 3; 338 338 339 339 if (!unwind_special(info, e->region_start, frame_size)) { 340 340 info->prev_sp = info->sp - frame_size;