summaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/fault.c
diff options
context:
space:
mode:
authorStuart Menefy <stuart.menefy@st.com>2006-11-21 13:34:04 +0900
committerPaul Mundt <lethal@linux-sh.org>2006-12-06 10:45:38 +0900
commitb5a1bcbee434b843c8850a968d9a6c7541f1be9d (patch)
tree2745f5efa2b4d6dfe18f4f186738612f0e77f79c /arch/sh/mm/fault.c
parentf0bc814cfbc212683c882e58b3d1afec6b3e3aa3 (diff)
sh: Set up correct siginfo structures for page faults.
Remove the previous saving of fault codes into the thread_struct as they are never used, and appeared to be inherited from x86. Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/fault.c')
-rw-r--r--arch/sh/mm/fault.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 68663b8f99a..43bed2cb00e 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -26,13 +26,16 @@ extern void die(const char *,struct pt_regs *,long);
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
- unsigned long address)
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+ unsigned long writeaccess,
+ unsigned long address)
{
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long page;
+ int si_code;
+ siginfo_t info;
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
@@ -41,6 +44,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
tsk = current;
mm = tsk->mm;
+ si_code = SEGV_MAPERR;
/*
* If we're in an interrupt or have no user
@@ -65,6 +69,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
* we can handle it..
*/
good_area:
+ si_code = SEGV_ACCERR;
if (writeaccess) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -105,9 +110,11 @@ bad_area:
up_read(&mm->mmap_sem);
if (user_mode(regs)) {
- tsk->thread.address = address;
- tsk->thread.error_code = writeaccess;
- force_sig(SIGSEGV, tsk);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = si_code;
+ info.si_addr = (void *) address;
+ force_sig_info(SIGSEGV, &info, tsk);
return;
}
@@ -166,10 +173,11 @@ do_sigbus:
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
- tsk->thread.address = address;
- tsk->thread.error_code = writeaccess;
- tsk->thread.trap_no = 14;
- force_sig(SIGBUS, tsk);
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ force_sig_info(SIGBUS, &info, tsk);
/* Kernel mode? Handle exceptions or die */
if (!user_mode(regs))