Skip to content

Commit

Permalink
Merge branch 'parisc-3.12' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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)
  • Loading branch information
torvalds committed Oct 13, 2013
2 parents 75c5318 + db080f9 commit 2d4712b
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 22 deletions.
2 changes: 1 addition & 1 deletion arch/parisc/include/asm/traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct pt_regs;

/* traps.c */
void parisc_terminate(char *msg, struct pt_regs *regs,
int code, unsigned long offset);
int code, unsigned long offset) __noreturn __cold;

/* mm/fault.c */
void do_page_fault(struct pt_regs *regs, unsigned long code,
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/kernel/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
}
}
EXPORT_SYMBOL_GPL(flush_cache_page);

#ifdef CONFIG_PARISC_TMPALIAS

Expand Down
8 changes: 1 addition & 7 deletions arch/parisc/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ enum ipi_message_type {
IPI_NOP=0,
IPI_RESCHEDULE=1,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
IPI_CPU_START,
IPI_CPU_STOP,
IPI_CPU_TEST
Expand Down Expand Up @@ -164,11 +163,6 @@ ipi_interrupt(int irq, void *dev_id)
generic_smp_call_function_interrupt();
break;

case IPI_CALL_FUNC_SINGLE:
smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC_SINGLE\n", this_cpu);
generic_smp_call_function_single_interrupt();
break;

case IPI_CPU_START:
smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
break;
Expand Down Expand Up @@ -260,7 +254,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)

void arch_send_call_function_single_ipi(int cpu)
{
send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
send_IPI_single(cpu, IPI_CALL_FUNC);
}

/*
Expand Down
11 changes: 3 additions & 8 deletions arch/parisc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,6 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
do_exit(SIGSEGV);
}

int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
{
return syscall(regs);
}

/* gdb uses break 4,8 */
#define GDB_BREAK_INSN 0x10004
static void handle_gdb_break(struct pt_regs *regs, int wot)
Expand Down Expand Up @@ -805,14 +800,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
else {

/*
* The kernel should never fault on its own address space.
* The kernel should never fault on its own address space,
* unless pagefault_disable() was called before.
*/

if (fault_space == 0)
if (fault_space == 0 && !in_atomic())
{
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address);

}
}

Expand Down
15 changes: 14 additions & 1 deletion arch/parisc/lib/memcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#ifdef __KERNEL__
#include <linux/module.h>
#include <linux/compiler.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
#define s_space "%%sr1"
#define d_space "%%sr2"
#else
Expand Down Expand Up @@ -524,4 +524,17 @@ EXPORT_SYMBOL(copy_to_user);
EXPORT_SYMBOL(copy_from_user);
EXPORT_SYMBOL(copy_in_user);
EXPORT_SYMBOL(memcpy);

long probe_kernel_read(void *dst, const void *src, size_t size)
{
unsigned long addr = (unsigned long)src;

if (size < 0 || addr < PAGE_SIZE)
return -EFAULT;

/* check for I/O space F_EXTEND(0xfff00000) access as well? */

return __probe_kernel_read(dst, src, size);
}

#endif
15 changes: 10 additions & 5 deletions arch/parisc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,20 +171,25 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
unsigned long address)
{
struct vm_area_struct *vma, *prev_vma;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
struct task_struct *tsk;
struct mm_struct *mm;
unsigned long acc_type;
int fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
unsigned int flags;

if (in_atomic() || !mm)
if (in_atomic())
goto no_context;

tsk = current;
mm = tsk->mm;
if (!mm)
goto no_context;

flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (user_mode(regs))
flags |= FAULT_FLAG_USER;

acc_type = parisc_acctyp(code, regs->iir);

if (acc_type & VM_WRITE)
flags |= FAULT_FLAG_WRITE;
retry:
Expand Down

0 comments on commit 2d4712b

Please sign in to comment.