public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86 page fault handler not interrupt safe
@ 2001-05-06  1:26 Brian Gerst
  2001-05-07  0:53 ` Linus Torvalds
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Gerst @ 2001-05-06  1:26 UTC (permalink / raw)
  To: torvalds, alan; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 534 bytes --]

Currently the page fault handler on the x86 can get a clobbered value
for %cr2 if an interrupt occurs and causes another page fault (interrupt
handler touches a vmalloced area for example) before %cr2 is read.  This
patch changes the page fault and alignment check (currently unused)
handlers to interrupt gates so that %cr2 can be read before an interrupt
can occur.  I'm not certain how much of a problem this really is, but I
suspect it could cause random seg faults to user space under heavy
interrupt load.  Comments are welcome.

[-- Attachment #2: diff-pagefault --]
[-- Type: text/plain, Size: 4684 bytes --]

diff -urN linux-2.4.5-pre1/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.4.5-pre1/arch/i386/kernel/entry.S	Wed Nov  8 20:09:50 2000
+++ linux/arch/i386/kernel/entry.S	Sat May  5 16:32:42 2001
@@ -296,20 +296,21 @@
 	pushl %ds
 	pushl %eax
 	xorl %eax,%eax
+error_code_cr2:
 	pushl %ebp
 	pushl %edi
 	pushl %esi
 	pushl %edx
-	decl %eax			# eax = -1
 	pushl %ecx
 	pushl %ebx
 	cld
 	movl %es,%ecx
 	movl ORIG_EAX(%esp), %esi	# get the error code
 	movl ES(%esp), %edi		# get the function address
-	movl %eax, ORIG_EAX(%esp)
+	movl $-1, ORIG_EAX(%esp)
 	movl %ecx, ES(%esp)
 	movl %esp,%edx
+	pushl %eax			# push address (cr2)
 	pushl %esi			# push the error code
 	pushl %edx			# push the pt_regs pointer
 	movl $(__KERNEL_DS),%edx
@@ -317,7 +318,7 @@
 	movl %edx,%es
 	GET_CURRENT(%ebx)
 	call *%edi
-	addl $8,%esp
+	addl $12,%esp
 	jmp ret_from_exception
 
 ENTRY(coprocessor_error)
@@ -405,11 +406,18 @@
 
 ENTRY(alignment_check)
 	pushl $ SYMBOL_NAME(do_alignment_check)
-	jmp error_code
+	jmp get_cr2
 
 ENTRY(page_fault)
 	pushl $ SYMBOL_NAME(do_page_fault)
-	jmp error_code
+get_cr2:
+	pushl %ds
+	pushl %eax
+	movl %cr2,%eax
+	testl $IF_MASK,EFLAGS-EAX(%esp)
+	jz error_code_cr2
+	sti
+	jmp error_code_cr2
 
 ENTRY(machine_check)
 	pushl $0
diff -urN linux-2.4.5-pre1/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- linux-2.4.5-pre1/arch/i386/kernel/traps.c	Mon Mar 19 21:23:40 2001
+++ linux/arch/i386/kernel/traps.c	Sat May  5 16:03:22 2001
@@ -225,15 +225,6 @@
 		die(str, regs, err);
 }
 
-static inline unsigned long get_cr2(void)
-{
-	unsigned long address;
-
-	/* get the address */
-	__asm__("movl %%cr2,%0":"=r" (address));
-	return address;
-}
-
 static void inline do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
@@ -270,13 +261,13 @@
 }
 
 #define DO_ERROR(trapnr, signr, str, name) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code, unsigned long address) \
 { \
 	do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
 }
 
 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code, unsigned long address) \
 { \
 	siginfo_t info; \
 	info.si_signo = signr; \
@@ -287,13 +278,13 @@
 }
 
 #define DO_VM86_ERROR(trapnr, signr, str, name) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code, unsigned long address) \
 { \
 	do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
 }
 
 #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+asmlinkage void do_##name(struct pt_regs * regs, long error_code, unsigned long address) \
 { \
 	siginfo_t info; \
 	info.si_signo = signr; \
@@ -314,7 +305,7 @@
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
-DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
+DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, address)
 
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
@@ -973,10 +964,10 @@
 	set_trap_gate(11,&segment_not_present);
 	set_trap_gate(12,&stack_segment);
 	set_trap_gate(13,&general_protection);
-	set_trap_gate(14,&page_fault);
+	set_intr_gate(14,&page_fault);
 	set_trap_gate(15,&spurious_interrupt_bug);
 	set_trap_gate(16,&coprocessor_error);
-	set_trap_gate(17,&alignment_check);
+	set_intr_gate(17,&alignment_check);
 	set_trap_gate(18,&machine_check);
 	set_trap_gate(19,&simd_coprocessor_error);
 
diff -urN linux-2.4.5-pre1/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- linux-2.4.5-pre1/arch/i386/mm/fault.c	Wed May  2 09:24:09 2001
+++ linux/arch/i386/mm/fault.c	Sat May  5 17:34:41 2001
@@ -103,19 +103,15 @@
  *	bit 1 == 0 means read, 1 means write
  *	bit 2 == 0 means kernel, 1 means user-mode
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct * vma;
-	unsigned long address;
 	unsigned long page;
 	unsigned long fixup;
 	int write;
 	siginfo_t info;
-
-	/* get the address */
-	__asm__("movl %%cr2,%0":"=r" (address));
 
 	tsk = current;
 

^ permalink raw reply	[flat|nested] 24+ messages in thread
* RE: [PATCH] x86 page fault handler not interrupt safe
@ 2001-05-07 17:32 Dunlap, Randy
  2001-05-07 17:51 ` David Woodhouse
  0 siblings, 1 reply; 24+ messages in thread
From: Dunlap, Randy @ 2001-05-07 17:32 UTC (permalink / raw)
  To: 'David Woodhouse', Linus Torvalds
  Cc: Alan Cox, Brian Gerst, linux-kernel

> From: David Woodhouse [mailto:dwmw2@infradead.org]
> 
> torvalds@transmeta.com said:
> >  If anybody has such a beast, please try this kernel patch _and_
> > running the F0 0F bug-producing program (search for it on the 'net -
> > it must be out there somewhere) to verify that the code still
> > correctly handles that case. 
> 
> Something along the lines of:
> 
> echo "unsigned long main=0xf00fc7c8;" > f00fbug.c ; make f00fbug

Yes, that's what the (SGI) program uses:
http://lwn.net/2001/0329/a/ltp-f00f.php3

~Randy


^ permalink raw reply	[flat|nested] 24+ messages in thread
[parent not found: <D5E932F578EBD111AC3F00A0C96B1E6F07DBE26F@orsmsx31.jf.intel .com>]
[parent not found: <3AF712D5.5D712E0F@didntduck.org>]
* Re: [PATCH] x86 page fault handler not interrupt safe
@ 2001-05-07 21:58 Anton Altaparmakov
  0 siblings, 0 replies; 24+ messages in thread
From: Anton Altaparmakov @ 2001-05-07 21:58 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Alan Cox, Brian Gerst, linux-kernel

At 18:12 07/05/2001, Linus Torvalds wrote:
>In particular, does anybody have a buggy Pentium to test with the F0 0F
>lock-up bug?
[snip]
>If anybody has such a beast, please try this kernel patch _and_ running

Still works ok (2.4.5-pre1 + patch). SIGILL is sent.

Best regards,

Anton


-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Linux NTFS Maintainer / WWW: http://sourceforge.net/projects/linux-ntfs/
ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2001-05-09 22:20 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-05-06  1:26 [PATCH] x86 page fault handler not interrupt safe Brian Gerst
2001-05-07  0:53 ` Linus Torvalds
2001-05-07  3:54   ` Brian Gerst
2001-05-07 10:45   ` Alan Cox
2001-05-07 14:57     ` Brian Gerst
2001-05-07 15:07       ` Alan Cox
2001-05-07 17:12         ` Linus Torvalds
2001-05-07 17:27           ` David Woodhouse
2001-05-07 19:54           ` Brian Gerst
2001-05-07 20:16             ` Linus Torvalds
2001-05-07 21:37           ` Alan Cox
2001-05-07 22:52           ` Jesper Juhl
2001-05-07 18:35         ` Anton Altaparmakov
2001-05-07 16:51     ` Linus Torvalds
  -- strict thread matches above, loose matches on Subject: below --
2001-05-07 17:32 Dunlap, Randy
2001-05-07 17:51 ` David Woodhouse
     [not found] <D5E932F578EBD111AC3F00A0C96B1E6F07DBE26F@orsmsx31.jf.intel .com>
2001-05-07 17:52 ` Anton Altaparmakov
     [not found] <3AF712D5.5D712E0F@didntduck.org>
2001-05-07 21:44 ` Linus Torvalds
2001-05-07 22:10   ` Brian Gerst
2001-05-08 10:45   ` Alan Cox
2001-05-08 16:45     ` Linus Torvalds
2001-05-09 22:12       ` Brian Gerst
2001-05-07 21:53 ` Nigel Gamble
2001-05-07 21:58 Anton Altaparmakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox