diff options
| author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
| commit | 185a257f2f73bcd89050ad02da5bedbc28fc43fa (patch) | |
| tree | 5e32586114534ed3f2165614cba3d578f5d87307 /arch/i386/mm/fault.c | |
| parent | 3f1a9aaeffd8d1cbc5ab9776c45cbd66af1c9699 (diff) | |
| parent | a77c64c1a641950626181b4857abb701d8f38ccc (diff) | |
Merge branch 'master' into gfs2
Diffstat (limited to 'arch/i386/mm/fault.c')
| -rw-r--r-- | arch/i386/mm/fault.c | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index f7279468323a..5e17a3f43b41 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
| @@ -27,21 +27,24 @@ | |||
| 27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
| 28 | #include <asm/desc.h> | 28 | #include <asm/desc.h> |
| 29 | #include <asm/kdebug.h> | 29 | #include <asm/kdebug.h> |
| 30 | #include <asm/segment.h> | ||
| 30 | 31 | ||
| 31 | extern void die(const char *,struct pt_regs *,long); | 32 | extern void die(const char *,struct pt_regs *,long); |
| 32 | 33 | ||
| 33 | #ifdef CONFIG_KPROBES | 34 | static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); |
| 34 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | 35 | |
| 35 | int register_page_fault_notifier(struct notifier_block *nb) | 36 | int register_page_fault_notifier(struct notifier_block *nb) |
| 36 | { | 37 | { |
| 37 | vmalloc_sync_all(); | 38 | vmalloc_sync_all(); |
| 38 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | 39 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); |
| 39 | } | 40 | } |
| 41 | EXPORT_SYMBOL_GPL(register_page_fault_notifier); | ||
| 40 | 42 | ||
| 41 | int unregister_page_fault_notifier(struct notifier_block *nb) | 43 | int unregister_page_fault_notifier(struct notifier_block *nb) |
| 42 | { | 44 | { |
| 43 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | 45 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); |
| 44 | } | 46 | } |
| 47 | EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); | ||
| 45 | 48 | ||
| 46 | static inline int notify_page_fault(enum die_val val, const char *str, | 49 | static inline int notify_page_fault(enum die_val val, const char *str, |
| 47 | struct pt_regs *regs, long err, int trap, int sig) | 50 | struct pt_regs *regs, long err, int trap, int sig) |
| @@ -55,14 +58,6 @@ static inline int notify_page_fault(enum die_val val, const char *str, | |||
| 55 | }; | 58 | }; |
| 56 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | 59 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); |
| 57 | } | 60 | } |
| 58 | #else | ||
| 59 | static inline int notify_page_fault(enum die_val val, const char *str, | ||
| 60 | struct pt_regs *regs, long err, int trap, int sig) | ||
| 61 | { | ||
| 62 | return NOTIFY_DONE; | ||
| 63 | } | ||
| 64 | #endif | ||
| 65 | |||
| 66 | 61 | ||
| 67 | /* | 62 | /* |
| 68 | * Unlock any spinlocks which will prevent us from getting the | 63 | * Unlock any spinlocks which will prevent us from getting the |
| @@ -119,10 +114,10 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, | |||
| 119 | } | 114 | } |
| 120 | 115 | ||
| 121 | /* The standard kernel/user address space limit. */ | 116 | /* The standard kernel/user address space limit. */ |
| 122 | *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; | 117 | *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg; |
| 123 | 118 | ||
| 124 | /* By far the most common cases. */ | 119 | /* By far the most common cases. */ |
| 125 | if (likely(seg == __USER_CS || seg == __KERNEL_CS)) | 120 | if (likely(SEGMENT_IS_FLAT_CODE(seg))) |
| 126 | return eip; | 121 | return eip; |
| 127 | 122 | ||
| 128 | /* Check the segment exists, is within the current LDT/GDT size, | 123 | /* Check the segment exists, is within the current LDT/GDT size, |
| @@ -436,11 +431,7 @@ good_area: | |||
| 436 | write = 0; | 431 | write = 0; |
| 437 | switch (error_code & 3) { | 432 | switch (error_code & 3) { |
| 438 | default: /* 3: write, present */ | 433 | default: /* 3: write, present */ |
| 439 | #ifdef TEST_VERIFY_AREA | 434 | /* fall through */ |
| 440 | if (regs->cs == KERNEL_CS) | ||
| 441 | printk("WP fault at %08lx\n", regs->eip); | ||
| 442 | #endif | ||
| 443 | /* fall through */ | ||
| 444 | case 2: /* write, not present */ | 435 | case 2: /* write, not present */ |
| 445 | if (!(vma->vm_flags & VM_WRITE)) | 436 | if (!(vma->vm_flags & VM_WRITE)) |
| 446 | goto bad_area; | 437 | goto bad_area; |
