public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH][RFC] exception processing in early boot
@ 2006-08-30  6:39 Willy Tarreau
  2006-08-30  9:51 ` Andi Kleen
  0 siblings, 1 reply; 20+ messages in thread
From: Willy Tarreau @ 2006-08-30  6:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: Riley, davej, pageexec

Hi,

PaX Team has sent me this patch for inclusion. Basically, during early
boot on x86, the exception handler does not make a special case for
exceptions which push an error code onto the stack, leading to a return
to a wrong address. Two patches were proposed, one which would add a
special case for all exceptions using the return code, and this one. The
former was of no use in its form because the return from the exception
handler would get back to the faulting exception, causing it to loop.

This one should be better as it effectively hangs the system using HLT
to prevent CPU from burning.

If nobody has any objections, I will merge it. In this case, I would also
like someone to check if 2.6 needs it and to port it in this case.

Thanks,
Willy

--

fix the longest existing kernel bug ever (since 0.01 ;-). basically,
the dummy interrupt handler installed for the early boot period does
not work for exceptions that push an error code as well, effectively
making the iret at the end of the handler to trigger another exception,
ad infinitum, or rather, until the kernel stack runs over, trashes all
memory below and eventually causes a CPU reset or a hang. without this
fix the early printk facility in 2.6 is also rather useless.


diff -Nurp linux-2.4.33/arch/i386/kernel/head.S linux-2.4.33-early-
inthandler/arch/i386/kernel/head.S
--- linux-2.4.33/arch/i386/kernel/head.S	2003-11-28 19:26:19.000000000 +0100
+++ linux-2.4.33-early-inthandler/arch/i386/kernel/head.S	2006-08-29 
14:19:55.000000000 +0200
@@ -325,27 +325,21 @@ ENTRY(stack_start)
 
 /* This is the default interrupt "handler" :-) */
 int_msg:
-	.asciz "Unknown interrupt\n"
+	.asciz "Unknown interrupt, stack: %p %p %p %p\n"
 	ALIGN
 ignore_int:
 	cld
-	pushl %eax
-	pushl %ecx
-	pushl %edx
-	pushl %es
-	pushl %ds
 	movl $(__KERNEL_DS),%eax
 	movl %eax,%ds
 	movl %eax,%es
+	pushl 12(%esp)
+	pushl 12(%esp)
+	pushl 12(%esp)
+	pushl 12(%esp)
 	pushl $int_msg
 	call SYMBOL_NAME(printk)
-	popl %eax
-	popl %ds
-	popl %es
-	popl %edx
-	popl %ecx
-	popl %eax
-	iret
+1:	hlt
+	jmp 1b
 
 /*
  * The interrupt descriptor table has room for 256 idt's,


^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: [PATCH][RFC] exception processing in early boot
@ 2006-08-31  2:05 Chuck Ebbert
  0 siblings, 0 replies; 20+ messages in thread
From: Chuck Ebbert @ 2006-08-31  2:05 UTC (permalink / raw)
  To: Andi Kleen; +Cc: pageexec, linux-kernel, Willy Tarreau

In-Reply-To: <200608301830.40994.ak@suse.de>

On Wed, 30 Aug 2006 18:30:40 +0200, Andi Kleen wrote:

> It would be better to separate exceptions from interrupts here.
> A spurious interrupt is not necessarily fatal, just an exception is.
> 
> But I went with the simpler patch with some changes now 
> (added PANIC to the message etc.) 

This is already in -mm:

================================================================================
From: Chuck Ebbert <76306.1226@compuserve.com>

Add early i386 fault handlers with debug information for common faults. 
Handles:

        divide error
        invalid opcode
        protection fault
        page fault

Also adds code to detect early recursive/multiple faults and halt the
system when they happen (taken from x86_64.)

Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Andi Kleen <ak@muc.de>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 arch/i386/kernel/head.S |   67 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff -puN arch/i386/kernel/head.S~i386-early-fault-handler arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S~i386-early-fault-handler
+++ a/arch/i386/kernel/head.S
@@ -371,8 +371,65 @@ rp_sidt:
 	addl $8,%edi
 	dec %ecx
 	jne rp_sidt
+
+.macro	set_early_handler handler,trapno
+	lea \handler,%edx
+	movl $(__KERNEL_CS << 16),%eax
+	movw %dx,%ax
+	movw $0x8E00,%dx	/* interrupt gate - dpl=0, present */
+	lea idt_table,%edi
+	movl %eax,8*\trapno(%edi)
+	movl %edx,8*\trapno+4(%edi)
+.endm
+
+	set_early_handler handler=early_divide_err,trapno=0
+	set_early_handler handler=early_illegal_opcode,trapno=6
+	set_early_handler handler=early_protection_fault,trapno=13
+	set_early_handler handler=early_page_fault,trapno=14
+
 	ret
 
+early_divide_err:
+	xor %edx,%edx
+	pushl $0	/* fake errcode */
+	jmp early_fault
+
+early_illegal_opcode:
+	movl $6,%edx
+	pushl $0	/* fake errcode */
+	jmp early_fault
+
+early_protection_fault:
+	movl $13,%edx
+	jmp early_fault
+
+early_page_fault:
+	movl $14,%edx
+	jmp early_fault
+
+early_fault:
+	cld
+#ifdef CONFIG_PRINTK
+	movl $(__KERNEL_DS),%eax
+	movl %eax,%ds
+	movl %eax,%es
+	cmpl $2,early_recursion_flag
+	je hlt_loop
+	incl early_recursion_flag
+	movl %cr2,%eax
+	pushl %eax
+	pushl %edx		/* trapno */
+	pushl $fault_msg
+#ifdef CONFIG_EARLY_PRINTK
+	call early_printk
+#else
+	call printk
+#endif
+#endif
+hlt_loop:
+	hlt
+	jmp hlt_loop
+
 /* This is the default interrupt "handler" :-) */
 	ALIGN
 ignore_int:
@@ -386,6 +443,9 @@ ignore_int:
 	movl $(__KERNEL_DS),%eax
 	movl %eax,%ds
 	movl %eax,%es
+	cmpl $2,early_recursion_flag
+	je hlt_loop
+	incl early_recursion_flag
 	pushl 16(%esp)
 	pushl 24(%esp)
 	pushl 32(%esp)
@@ -431,9 +491,16 @@ ENTRY(stack_start)
 
 ready:	.byte 0
 
+early_recursion_flag:
+	.long 0
+
 int_msg:
 	.asciz "Unknown interrupt or fault at EIP %p %p %p\n"
 
+fault_msg:
+	.ascii "Int %d: CR2 %p  err %p  EIP %p  CS %p  flags %p\n"
+	.asciz "Stack: %p %p %p %p %p %p %p %p\n"
+
 /*
  * The IDT and GDT 'descriptors' are a strange 48-bit object
  * only used by the lidt and lgdt instructions. They are not
_
-- 
Chuck

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

end of thread, other threads:[~2006-08-31  2:12 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-30  6:39 [PATCH][RFC] exception processing in early boot Willy Tarreau
2006-08-30  9:51 ` Andi Kleen
2006-08-30 12:18   ` Willy Tarreau
2006-08-30 12:59     ` Andi Kleen
2006-08-30 13:16       ` Willy Tarreau
     [not found]         ` <20060830100015.6b967c32.seanlkml@sympatico.ca>
2006-08-30 13:46           ` Willy Tarreau
2006-08-30 14:00           ` Sean
     [not found]       ` <44F5D81A.9650.5BE48F99@pageexec.freemail.hu>
2006-08-30 16:30         ` Andi Kleen
2006-08-30 16:59           ` linux-os (Dick Johnson)
2006-08-30 17:02             ` Andi Kleen
2006-08-30 17:15               ` linux-os (Dick Johnson)
     [not found]           ` <44F5E818.20898.5C230A79@pageexec.freemail.hu>
2006-08-30 17:52             ` Andi Kleen
     [not found]               ` <44F5F348.1251.5C4EBCCB@pageexec.freemail.hu>
2006-08-30 18:26                 ` Andi Kleen
2006-08-30 19:01                   ` Willy Tarreau
2006-08-30 19:36                     ` Andi Kleen
2006-08-30 20:03                       ` Willy Tarreau
2006-08-30 20:06                         ` Andi Kleen
2006-08-30 20:40                           ` Willy Tarreau
2006-08-30 21:31                         ` Alan Cox
  -- strict thread matches above, loose matches on Subject: below --
2006-08-31  2:05 Chuck Ebbert

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