Skip to content

Commit 2d4712b

Browse files
committed
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)
2 parents 75c5318 + db080f9 commit 2d4712b

File tree

6 files changed

+30
-22
lines changed

6 files changed

+30
-22
lines changed

arch/parisc/include/asm/traps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct pt_regs;
66

77
/* traps.c */
88
void parisc_terminate(char *msg, struct pt_regs *regs,
9-
int code, unsigned long offset);
9+
int code, unsigned long offset) __noreturn __cold;
1010

1111
/* mm/fault.c */
1212
void do_page_fault(struct pt_regs *regs, unsigned long code,

arch/parisc/kernel/cache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
602602
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
603603
}
604604
}
605+
EXPORT_SYMBOL_GPL(flush_cache_page);
605606

606607
#ifdef CONFIG_PARISC_TMPALIAS
607608

arch/parisc/kernel/smp.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ enum ipi_message_type {
7272
IPI_NOP=0,
7373
IPI_RESCHEDULE=1,
7474
IPI_CALL_FUNC,
75-
IPI_CALL_FUNC_SINGLE,
7675
IPI_CPU_START,
7776
IPI_CPU_STOP,
7877
IPI_CPU_TEST
@@ -164,11 +163,6 @@ ipi_interrupt(int irq, void *dev_id)
164163
generic_smp_call_function_interrupt();
165164
break;
166165

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-
172166
case IPI_CPU_START:
173167
smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu);
174168
break;
@@ -260,7 +254,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
260254

261255
void arch_send_call_function_single_ipi(int cpu)
262256
{
263-
send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
257+
send_IPI_single(cpu, IPI_CALL_FUNC);
264258
}
265259

266260
/*

arch/parisc/kernel/traps.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,6 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
291291
do_exit(SIGSEGV);
292292
}
293293

294-
int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
295-
{
296-
return syscall(regs);
297-
}
298-
299294
/* gdb uses break 4,8 */
300295
#define GDB_BREAK_INSN 0x10004
301296
static void handle_gdb_break(struct pt_regs *regs, int wot)
@@ -805,14 +800,14 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
805800
else {
806801

807802
/*
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.
809805
*/
810806

811-
if (fault_space == 0)
807+
if (fault_space == 0 && !in_atomic())
812808
{
813809
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
814810
parisc_terminate("Kernel Fault", regs, code, fault_address);
815-
816811
}
817812
}
818813

arch/parisc/lib/memcpy.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#ifdef __KERNEL__
5757
#include <linux/module.h>
5858
#include <linux/compiler.h>
59-
#include <asm/uaccess.h>
59+
#include <linux/uaccess.h>
6060
#define s_space "%%sr1"
6161
#define d_space "%%sr2"
6262
#else
@@ -524,4 +524,17 @@ EXPORT_SYMBOL(copy_to_user);
524524
EXPORT_SYMBOL(copy_from_user);
525525
EXPORT_SYMBOL(copy_in_user);
526526
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+
527540
#endif

arch/parisc/mm/fault.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,25 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
171171
unsigned long address)
172172
{
173173
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;
176176
unsigned long acc_type;
177177
int fault;
178-
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
178+
unsigned int flags;
179179

180-
if (in_atomic() || !mm)
180+
if (in_atomic())
181181
goto no_context;
182182

183+
tsk = current;
184+
mm = tsk->mm;
185+
if (!mm)
186+
goto no_context;
187+
188+
flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
183189
if (user_mode(regs))
184190
flags |= FAULT_FLAG_USER;
185191

186192
acc_type = parisc_acctyp(code, regs->iir);
187-
188193
if (acc_type & VM_WRITE)
189194
flags |= FAULT_FLAG_WRITE;
190195
retry:

0 commit comments

Comments
 (0)