public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i386/gcc bug with do_test_wp_bit
@ 2004-10-06  1:45 Zachary Amsden
  2004-10-06  2:05 ` Linus Torvalds
  2004-10-06 11:55 ` Andi Kleen
  0 siblings, 2 replies; 5+ messages in thread
From: Zachary Amsden @ 2004-10-06  1:45 UTC (permalink / raw)
  To: linux-kernel, Riley, davej, hpa, Linus Torvalds, Andi Kleen

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

Playing around with gcc 3.3.3, I compiled a 2.6 series kernel for i386 
and discovered it panics on boot.  The problem was gcc 3.3.3 can inline 
functions even if declared after their call sites.  This causes i386 to 
not boot, since do_test_wp_bit() must not exist in the __init section.  
Similar problems may exist in the boot code for other architectures, but 
I can't confirm that at this time.  x86_64 is not affected.

I've included a small trivial fix that is harmless for users not using 
gcc 3.3.3.  Testing: my 2.6 kernel now boots when compiled with gcc 
3.3.3 compiler.

Cheers,
Zach Amsden
zach@vmware.com

[-- Attachment #2: i386-wp-test.patch --]
[-- Type: text/plain, Size: 588 bytes --]

diff -ru linux-2.6.9-rc3/arch/i386/mm/init.c linux-2.6.9-rc3-za1/arch/i386/mm/init.c
--- linux-2.6.9-rc3/arch/i386/mm/init.c	2004-10-05 18:21:03.000000000 -0700
+++ linux-2.6.9-rc3-za1/arch/i386/mm/init.c	2004-10-05 18:24:08.000000000 -0700
@@ -671,9 +671,9 @@
 
 /*
  * This function cannot be __init, since exceptions don't work in that
- * section.  Put this after the callers, so that it cannot be inlined.
+ * section.  This function must not be inlined.
  */
-static int do_test_wp_bit(void)
+__attribute__((noinline)) static int do_test_wp_bit(void)
 {
 	char tmp_reg;
 	int flag;

[-- Attachment #3: README.i386-wp-test --]
[-- Type: text/plain, Size: 1172 bytes --]

When compiling a Linux 2.6 kernel using gcc 3.3.3, gcc was able to inline the function do_test_wp_bit().  This causes i386 kernels to panic on boot, since the exception handler doesn't work properly.

The fix is straightforward - don't ever allow this function to be inlined.

Here's a disassembly to confirm the bad inline:

c02aecf1 <test_wp_bit>:
c02aecf1:       55                      push   %ebp
c02aecf2:       89 e5                   mov    %esp,%ebp
c02aecf4:       83 ec 0c                sub    $0xc,%esp
c02aecf7:       c7 04 24 0c a0 25 c0    movl   $0xc025a00c,(%esp)
c02aecfe:       e8 63 73 e6 ff          call   c0116066 <printk>
c02aed03:       c7 44 24 08 25 00 00    movl   $0x25,0x8(%esp)
c02aed0a:       00 
c02aed0b:       c7 44 24 04 00 10 10    movl   $0x101000,0x4(%esp)
c02aed12:       00 
c02aed13:       c7 04 24 12 00 00 00    movl   $0x12,(%esp)
c02aed1a:       e8 d5 11 e6 ff          call   c010fef4 <__set_fixmap>
c02aed1f:       b8 01 00 00 00          mov    $0x1,%eax
c02aed24:       8a 15 00 d0 fe ff       mov    0xfffed000,%dl
c02aed2a:       88 15 00 d0 fe ff       mov    %dl,0xfffed000

Cheers,

Zachary Amsden (zach@vmware.com)

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

end of thread, other threads:[~2004-10-06 19:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-06  1:45 [PATCH] i386/gcc bug with do_test_wp_bit Zachary Amsden
2004-10-06  2:05 ` Linus Torvalds
2004-10-06  3:19   ` Zachary Amsden
2004-10-06 11:55 ` Andi Kleen
2004-10-06 19:34   ` Zachary Amsden

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