diff options
-rw-r--r-- | arch/x86/mm/fault_32.c | 20 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 29 |
2 files changed, 31 insertions, 18 deletions
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index 52c13d2e011e..31113deeb7c0 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c | |||
@@ -36,10 +36,10 @@ | |||
36 | * bit 3 == 1 means use of reserved bit detected | 36 | * bit 3 == 1 means use of reserved bit detected |
37 | * bit 4 == 1 means fault was an instruction fetch | 37 | * bit 4 == 1 means fault was an instruction fetch |
38 | */ | 38 | */ |
39 | #define PF_PROT (1<<0) | 39 | #define PF_PROT (1<<0) |
40 | #define PF_WRITE (1<<1) | 40 | #define PF_WRITE (1<<1) |
41 | #define PF_USER (1<<2) | 41 | #define PF_USER (1<<2) |
42 | #define PF_RSVD (1<<3) | 42 | #define PF_RSVD (1<<3) |
43 | #define PF_INSTR (1<<4) | 43 | #define PF_INSTR (1<<4) |
44 | 44 | ||
45 | static inline int notify_page_fault(struct pt_regs *regs) | 45 | static inline int notify_page_fault(struct pt_regs *regs) |
@@ -460,11 +460,15 @@ bad_area_nosemaphore: | |||
460 | 460 | ||
461 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 461 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
462 | printk_ratelimit()) { | 462 | printk_ratelimit()) { |
463 | printk("%s%s[%d]: segfault at %08lx ip %08lx " | 463 | printk( |
464 | "sp %08lx error %lx\n", | 464 | #ifdef CONFIG_X86_32 |
465 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | 465 | "%s%s[%d]: segfault at %08lx ip %08lx sp %08lx error %lx\n", |
466 | tsk->comm, task_pid_nr(tsk), address, regs->ip, | 466 | #else |
467 | regs->sp, error_code); | 467 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", |
468 | #endif | ||
469 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | ||
470 | tsk->comm, task_pid_nr(tsk), address, regs->ip, | ||
471 | regs->sp, error_code); | ||
468 | } | 472 | } |
469 | tsk->thread.cr2 = address; | 473 | tsk->thread.cr2 = address; |
470 | /* Kernel addresses are always protection faults */ | 474 | /* Kernel addresses are always protection faults */ |
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index c6b3ad515cf1..c48d95c306df 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c | |||
@@ -440,8 +440,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
440 | if (!(vma->vm_flags & VM_GROWSDOWN)) | 440 | if (!(vma->vm_flags & VM_GROWSDOWN)) |
441 | goto bad_area; | 441 | goto bad_area; |
442 | if (error_code & PF_USER) { | 442 | if (error_code & PF_USER) { |
443 | /* Allow userspace just enough access below the stack pointer | 443 | /* |
444 | * to let the 'enter' instruction work. | 444 | * Accessing the stack below %sp is always a bug. |
445 | * The large cushion allows instructions like enter | ||
446 | * and pusha to work. ("enter $65535,$31" pushes | ||
447 | * 32 pointers and then decrements %sp by 65535.) | ||
445 | */ | 448 | */ |
446 | if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp) | 449 | if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp) |
447 | goto bad_area; | 450 | goto bad_area; |
@@ -522,10 +525,14 @@ bad_area_nosemaphore: | |||
522 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 525 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
523 | printk_ratelimit()) { | 526 | printk_ratelimit()) { |
524 | printk( | 527 | printk( |
525 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", | 528 | #ifdef CONFIG_X86_32 |
526 | tsk->pid > 1 ? KERN_INFO : KERN_EMERG, | 529 | "%s%s[%d]: segfault at %08lx ip %08lx sp %08lx error %lx\n", |
527 | tsk->comm, tsk->pid, address, regs->ip, | 530 | #else |
528 | regs->sp, error_code); | 531 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", |
532 | #endif | ||
533 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | ||
534 | tsk->comm, task_pid_nr(tsk), address, regs->ip, | ||
535 | regs->sp, error_code); | ||
529 | } | 536 | } |
530 | 537 | ||
531 | tsk->thread.cr2 = address; | 538 | tsk->thread.cr2 = address; |
@@ -609,10 +616,12 @@ LIST_HEAD(pgd_list); | |||
609 | 616 | ||
610 | void vmalloc_sync_all(void) | 617 | void vmalloc_sync_all(void) |
611 | { | 618 | { |
612 | /* Note that races in the updates of insync and start aren't | 619 | /* |
613 | problematic: | 620 | * Note that races in the updates of insync and start aren't |
614 | insync can only get set bits added, and updates to start are only | 621 | * problematic: insync can only get set bits added, and updates to |
615 | improving performance (without affecting correctness if undone). */ | 622 | * start are only improving performance (without affecting correctness |
623 | * if undone). | ||
624 | */ | ||
616 | static DECLARE_BITMAP(insync, PTRS_PER_PGD); | 625 | static DECLARE_BITMAP(insync, PTRS_PER_PGD); |
617 | static unsigned long start = VMALLOC_START & PGDIR_MASK; | 626 | static unsigned long start = VMALLOC_START & PGDIR_MASK; |
618 | unsigned long address; | 627 | unsigned long address; |