diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-19 11:37:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-19 11:37:14 -0700 |
commit | dbe3ed1c078c193be34326728d494c5c4bc115e2 (patch) | |
tree | 9624273ee199b70db0c8adc0ea38a8b2e0984544 /arch | |
parent | 4f01a757e75f2a3cab2bab89c4176498963946b9 (diff) | |
download | kernel_samsung_crespo-dbe3ed1c078c193be34326728d494c5c4bc115e2.zip kernel_samsung_crespo-dbe3ed1c078c193be34326728d494c5c4bc115e2.tar.gz kernel_samsung_crespo-dbe3ed1c078c193be34326728d494c5c4bc115e2.tar.bz2 |
x86-64: page faults from user mode are always user faults
Randy Dunlap noticed an interesting "crashme" behaviour on his dual
Prescott Xeon setup, where he gets page faults with the error code
having a zero "user" bit, but the register state points back to user
mode.
This may be a CPU microcode buglet triggered by some strange instruction
pattern that crashme generates, and loading a microcode update seems to
possibly have fixed it.
Regardless, we really should trust the register state more than the
error code, since it's really the register state that determines whether
we can actually send a signal, or whether we're in kernel mode and need
to oops/kill the process in the case of a page fault.
Cc: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/mm/fault.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 327c9f2..54816ad 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -374,6 +374,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (unlikely(in_atomic() || !mm)) goto bad_area_nosemaphore; + /* + * User-mode registers count as a user access even for any + * potential system fault or CPU buglet. + */ + if (user_mode_vm(regs)) + error_code |= PF_USER; + again: /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the |