Commit 2d4712b7a615e5db3eb9a427f1722eec79681b4b

Authored by Linus Torvalds

Merge branch 'parisc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc fixes from Helge Deller:
 "This patchset includes a bugfix to prevent a kernel crash when memory
  in page zero is accessed by the kernel itself, e.g.  via
  probe_kernel_read().

  Furthermore we now export flush_cache_page() which is needed
  (indirectly) by the lustre filesystem.  The other patches remove
  unused functions and optimizes the page fault handler to only evaluate
  variables if needed, which again protects against possible kernel
  crashes"

* 'parisc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: let probe_kernel_read() capture access to page zero
  parisc: optimize variable initialization in do_page_fault
  parisc: fix interruption handler to respect pagefault_disable()
  parisc: mark parisc_terminate() noreturn and cold.
  parisc: remove unused syscall_ipi() function.
  parisc: kill SMP single function call interrupt
  parisc: Export flush_cache_page() (needed by lustre)

Showing 6 changed files Side-by-side Diff

arch/parisc/include/asm/traps.h
... ... @@ -6,7 +6,7 @@
6 6  
7 7 /* traps.c */
8 8 void parisc_terminate(char *msg, struct pt_regs *regs,
9   - int code, unsigned long offset);
  9 + int code, unsigned long offset) __noreturn __cold;
10 10  
11 11 /* mm/fault.c */
12 12 void do_page_fault(struct pt_regs *regs, unsigned long code,
arch/parisc/kernel/cache.c
... ... @@ -602,6 +602,7 @@
602 602 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
603 603 }
604 604 }
  605 +EXPORT_SYMBOL_GPL(flush_cache_page);
605 606  
606 607 #ifdef CONFIG_PARISC_TMPALIAS
607 608  
arch/parisc/kernel/smp.c
... ... @@ -72,7 +72,6 @@
72 72 IPI_NOP=0,
73 73 IPI_RESCHEDULE=1,
74 74 IPI_CALL_FUNC,
75   - IPI_CALL_FUNC_SINGLE,
76 75 IPI_CPU_START,
77 76 IPI_CPU_STOP,
78 77 IPI_CPU_TEST
... ... @@ -164,11 +163,6 @@
164 163 generic_smp_call_function_interrupt();
165 164 break;
166 165  
167   - case IPI_CALL_FUNC_SINGLE:
168   - smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC_SINGLE\n", this_cpu);
169   - generic_smp_call_function_single_interrupt();
170   - break;
171   -
172 166 case IPI_CPU_START:
173 167 smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
174 168 break;
... ... @@ -260,7 +254,7 @@
260 254  
261 255 void arch_send_call_function_single_ipi(int cpu)
262 256 {
263   - send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
  257 + send_IPI_single(cpu, IPI_CALL_FUNC);
264 258 }
265 259  
266 260 /*
arch/parisc/kernel/traps.c
... ... @@ -291,11 +291,6 @@
291 291 do_exit(SIGSEGV);
292 292 }
293 293  
294   -int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
295   -{
296   - return syscall(regs);
297   -}
298   -
299 294 /* gdb uses break 4,8 */
300 295 #define GDB_BREAK_INSN 0x10004
301 296 static void handle_gdb_break(struct pt_regs *regs, int wot)
302 297  
303 298  
... ... @@ -805,14 +800,14 @@
805 800 else {
806 801  
807 802 /*
808   - * The kernel should never fault on its own address space.
  803 + * The kernel should never fault on its own address space,
  804 + * unless pagefault_disable() was called before.
809 805 */
810 806  
811   - if (fault_space == 0)
  807 + if (fault_space == 0 && !in_atomic())
812 808 {
813 809 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
814 810 parisc_terminate("Kernel Fault", regs, code, fault_address);
815   -
816 811 }
817 812 }
818 813  
arch/parisc/lib/memcpy.c
... ... @@ -56,7 +56,7 @@
56 56 #ifdef __KERNEL__
57 57 #include <linux/module.h>
58 58 #include <linux/compiler.h>
59   -#include <asm/uaccess.h>
  59 +#include <linux/uaccess.h>
60 60 #define s_space "%%sr1"
61 61 #define d_space "%%sr2"
62 62 #else
... ... @@ -524,5 +524,18 @@
524 524 EXPORT_SYMBOL(copy_from_user);
525 525 EXPORT_SYMBOL(copy_in_user);
526 526 EXPORT_SYMBOL(memcpy);
  527 +
  528 +long probe_kernel_read(void *dst, const void *src, size_t size)
  529 +{
  530 + unsigned long addr = (unsigned long)src;
  531 +
  532 + if (size < 0 || addr < PAGE_SIZE)
  533 + return -EFAULT;
  534 +
  535 + /* check for I/O space F_EXTEND(0xfff00000) access as well? */
  536 +
  537 + return __probe_kernel_read(dst, src, size);
  538 +}
  539 +
527 540 #endif
arch/parisc/mm/fault.c
... ... @@ -171,20 +171,25 @@
171 171 unsigned long address)
172 172 {
173 173 struct vm_area_struct *vma, *prev_vma;
174   - struct task_struct *tsk = current;
175   - struct mm_struct *mm = tsk->mm;
  174 + struct task_struct *tsk;
  175 + struct mm_struct *mm;
176 176 unsigned long acc_type;
177 177 int fault;
178   - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
  178 + unsigned int flags;
179 179  
180   - if (in_atomic() || !mm)
  180 + if (in_atomic())
181 181 goto no_context;
182 182  
  183 + tsk = current;
  184 + mm = tsk->mm;
  185 + if (!mm)
  186 + goto no_context;
  187 +
  188 + flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
183 189 if (user_mode(regs))
184 190 flags |= FAULT_FLAG_USER;
185 191  
186 192 acc_type = parisc_acctyp(code, regs->iir);
187   -
188 193 if (acc_type & VM_WRITE)
189 194 flags |= FAULT_FLAG_WRITE;
190 195 retry: