diff options
author | Jan Beulich <jbeulich@novell.com> | 2005-09-12 12:49:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-12 13:50:57 -0400 |
commit | 1209140c3c70aaa32d1a0462d79557f2a44a4ef8 (patch) | |
tree | 2dc299ad357392f7d81e85131615bb61f0b1a14c /arch/x86_64/mm | |
parent | 059bf0f6c33058680e4381f17d554baaa4f45d68 (diff) |
[PATCH] x86-64: Safe interrupts in oops_begin/end
Rather than blindly re-enabling interrupts in oops_end(), save their state
in oope_begin() and then restore that state.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/mm')
-rw-r--r-- | arch/x86_64/mm/fault.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 816732d8858c..b75b872ec154 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -221,12 +221,13 @@ int unhandled_signal(struct task_struct *tsk, int sig) | |||
221 | static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | 221 | static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, |
222 | unsigned long error_code) | 222 | unsigned long error_code) |
223 | { | 223 | { |
224 | oops_begin(); | 224 | unsigned long flags = oops_begin(); |
225 | |||
225 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", | 226 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", |
226 | current->comm, address); | 227 | current->comm, address); |
227 | dump_pagetable(address); | 228 | dump_pagetable(address); |
228 | __die("Bad pagetable", regs, error_code); | 229 | __die("Bad pagetable", regs, error_code); |
229 | oops_end(); | 230 | oops_end(flags); |
230 | do_exit(SIGKILL); | 231 | do_exit(SIGKILL); |
231 | } | 232 | } |
232 | 233 | ||
@@ -304,6 +305,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
304 | unsigned long address; | 305 | unsigned long address; |
305 | const struct exception_table_entry *fixup; | 306 | const struct exception_table_entry *fixup; |
306 | int write; | 307 | int write; |
308 | unsigned long flags; | ||
307 | siginfo_t info; | 309 | siginfo_t info; |
308 | 310 | ||
309 | #ifdef CONFIG_CHECKING | 311 | #ifdef CONFIG_CHECKING |
@@ -521,7 +523,7 @@ no_context: | |||
521 | * terminate things with extreme prejudice. | 523 | * terminate things with extreme prejudice. |
522 | */ | 524 | */ |
523 | 525 | ||
524 | oops_begin(); | 526 | flags = oops_begin(); |
525 | 527 | ||
526 | if (address < PAGE_SIZE) | 528 | if (address < PAGE_SIZE) |
527 | printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); | 529 | printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); |
@@ -534,7 +536,7 @@ no_context: | |||
534 | __die("Oops", regs, error_code); | 536 | __die("Oops", regs, error_code); |
535 | /* Executive summary in case the body of the oops scrolled away */ | 537 | /* Executive summary in case the body of the oops scrolled away */ |
536 | printk(KERN_EMERG "CR2: %016lx\n", address); | 538 | printk(KERN_EMERG "CR2: %016lx\n", address); |
537 | oops_end(); | 539 | oops_end(flags); |
538 | do_exit(SIGKILL); | 540 | do_exit(SIGKILL); |
539 | 541 | ||
540 | /* | 542 | /* |