aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-01-30 07:32:35 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:32:35 -0500
commitc4aba4a8ec795124394bc79e3e8dbbc319338a98 (patch)
treeeeb46bfa28897a3a3730667b399731271dd39c24
parent1dc85be087d6645575847dc23c37147a2352312b (diff)
x86: introduce force_sig_info_fault helper to X86_64
Use the force_sig_info_fault helper from X86_32 in X86_64. Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/mm/fault_32.c2
-rw-r--r--arch/x86/mm/fault_64.c31
2 files changed, 19 insertions, 14 deletions
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index 300c9d8b684a..b1893ebf6456 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -249,7 +249,7 @@ static int is_prefetch(struct pt_regs *regs, unsigned long addr,
249 return prefetch; 249 return prefetch;
250} 250}
251 251
252static noinline void force_sig_info_fault(int si_signo, int si_code, 252static void force_sig_info_fault(int si_signo, int si_code,
253 unsigned long address, struct task_struct *tsk) 253 unsigned long address, struct task_struct *tsk)
254{ 254{
255 siginfo_t info; 255 siginfo_t info;
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 0d3d5979ce2c..dcf430bb62ee 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -252,6 +252,18 @@ static int is_prefetch(struct pt_regs *regs, unsigned long addr,
252 return prefetch; 252 return prefetch;
253} 253}
254 254
255static void force_sig_info_fault(int si_signo, int si_code,
256 unsigned long address, struct task_struct *tsk)
257{
258 siginfo_t info;
259
260 info.si_signo = si_signo;
261 info.si_errno = 0;
262 info.si_code = si_code;
263 info.si_addr = (void __user *)address;
264 force_sig_info(si_signo, &info, tsk);
265}
266
255static int bad_address(void *p) 267static int bad_address(void *p)
256{ 268{
257 unsigned long dummy; 269 unsigned long dummy;
@@ -415,7 +427,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
415 unsigned long address; 427 unsigned long address;
416 int write, fault; 428 int write, fault;
417 unsigned long flags; 429 unsigned long flags;
418 siginfo_t info; 430 int si_code;
419 431
420 /* 432 /*
421 * We can fault from pretty much anywhere, with unknown IRQ state. 433 * We can fault from pretty much anywhere, with unknown IRQ state.
@@ -429,7 +441,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
429 /* get the address */ 441 /* get the address */
430 address = read_cr2(); 442 address = read_cr2();
431 443
432 info.si_code = SEGV_MAPERR; 444 si_code = SEGV_MAPERR;
433 445
434 446
435 /* 447 /*
@@ -532,7 +544,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
532 * we can handle it.. 544 * we can handle it..
533 */ 545 */
534good_area: 546good_area:
535 info.si_code = SEGV_ACCERR; 547 si_code = SEGV_ACCERR;
536 write = 0; 548 write = 0;
537 switch (error_code & (PF_PROT|PF_WRITE)) { 549 switch (error_code & (PF_PROT|PF_WRITE)) {
538 default: /* 3: write, present */ 550 default: /* 3: write, present */
@@ -611,11 +623,8 @@ bad_area_nosemaphore:
611 /* Kernel addresses are always protection faults */ 623 /* Kernel addresses are always protection faults */
612 tsk->thread.error_code = error_code | (address >= TASK_SIZE); 624 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
613 tsk->thread.trap_no = 14; 625 tsk->thread.trap_no = 14;
614 info.si_signo = SIGSEGV; 626
615 info.si_errno = 0; 627 force_sig_info_fault(SIGSEGV, si_code, address, tsk);
616 /* info.si_code has been set above */
617 info.si_addr = (void __user *)address;
618 force_sig_info(SIGSEGV, &info, tsk);
619 return; 628 return;
620 } 629 }
621 630
@@ -682,11 +691,7 @@ do_sigbus:
682 tsk->thread.cr2 = address; 691 tsk->thread.cr2 = address;
683 tsk->thread.error_code = error_code; 692 tsk->thread.error_code = error_code;
684 tsk->thread.trap_no = 14; 693 tsk->thread.trap_no = 14;
685 info.si_signo = SIGBUS; 694 force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
686 info.si_errno = 0;
687 info.si_code = BUS_ADRERR;
688 info.si_addr = (void __user *)address;
689 force_sig_info(SIGBUS, &info, tsk);
690 return; 695 return;
691} 696}
692 697