parisc: fix interruption handler to respect pagefault_disable()
Helge Deller
maintainerPATCH 1/1 parisc: fix interruption handler to respect pagefault_disable()
Running an "echo t > /proc/sysrq-trigger" crashes the parisc kernel. The problem is, that in print_worker_info() we try to read the workqueue info via the probe_kernel_read() functions which use pagefault_disable() to avoid crashes like this:
probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq));
probe_kernel_read(&wq, &pwq->wq, sizeof(wq));
probe_kernel_read(name, wq->name, sizeof(name) - 1);The problem here is, that the first probe_kernel_read(&pwq) might return zero in pwq and as such the following probe_kernel_reads() try to access contents of the page zero which is read protected and generate a kernel segfault.
With this patch we fix the interruption handler to call parisc_terminate() directly only if pagefault_disable() was not called (in which case preempt_count()==0). Otherwise we hand over to the pagefault handler which will try to look up the faulting address in the fixup tables.
arch/parisc/include/asm/traps.h +1 -1
@@ -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,
arch/parisc/kernel/traps.c +3 -3
@@ -805,14 +805,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); - } }
Quoted 57 lines · Helge Deller
Running an "echo t >
/proc/sysrq-trigger" crashes the parisc kernel. The problem is, that inprint_worker_info()we try to read the workqueue info via theprobe_kernel_read()functions which usepagefault_disable()to avoid crashes like this:probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq)); probe_kernel_read(&wq, &pwq->wq, sizeof(wq)); probe_kernel_read(name, wq->name, sizeof(name) - 1);The problem here is, that the first
probe_kernel_read(&pwq)might return zero in pwq and as such the followingprobe_kernel_reads()try to access contents of the page zero which is read protected and generate a kernel segfault.With this patch we fix the interruption handler to call
parisc_terminate()directly only ifpagefault_disable()was not called (in which case preempt_count()==0). Otherwise we hand over to the pagefault handler which will try to look up the faulting address in the fixup tables.Signed-off-by Helge Deller <[email protected]>Cc <[email protected]> # v3.0+arch/parisc/include/asm/traps.h +1
-1@@ -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,arch/parisc/kernel/traps.c +3
-4@@ -805,14 +805,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); - } } --
Quoted 4 lines
To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
John David Anglin [email protected]