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>
This commit is contained in:

committed by
Paul Mundt

parent
f0bc814cfb
commit
b5a1bcbee4
@@ -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))
|
||||
|
Reference in New Issue
Block a user