diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-01-30 07:32:35 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:32:35 -0500 |
commit | c4aba4a8ec795124394bc79e3e8dbbc319338a98 (patch) | |
tree | eeb46bfa28897a3a3730667b399731271dd39c24 | |
parent | 1dc85be087d6645575847dc23c37147a2352312b (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.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 31 |
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 | ||
252 | static noinline void force_sig_info_fault(int si_signo, int si_code, | 252 | static 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 | ||
255 | static 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 | |||
255 | static int bad_address(void *p) | 267 | static 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 | */ |
534 | good_area: | 546 | good_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 | ||