[kernel/f14/master] fix i8k inline asm to workaround miscompilation with newer gcc

Kyle McMartin kyle at fedoraproject.org
Tue Nov 23 14:47:19 UTC 2010


commit cc7fb594a9e2a08972632e098556816acc9529e1
Author: Kyle McMartin <kyle at mcmartin.ca>
Date:   Tue Nov 23 09:47:06 2010 -0500

    fix i8k inline asm to workaround miscompilation with newer gcc

 fix-i8k-inline-asm.patch                           |   84 ++++++++++++++++++++
 kernel.spec                                        |   11 ++-
 ...x-regression-with-cmpxchg8b-on-i386-hosts.patch |   70 ----------------
 3 files changed, 92 insertions(+), 73 deletions(-)
---
diff --git a/fix-i8k-inline-asm.patch b/fix-i8k-inline-asm.patch
new file mode 100644
index 0000000..87fadc0
--- /dev/null
+++ b/fix-i8k-inline-asm.patch
@@ -0,0 +1,84 @@
+commit 22d3243de86bc92d874abb7c5b185d5c47aba323
+Author: Jim Bos <jim876 at xs4all.nl>
+Date:   Mon Nov 15 21:22:37 2010 +0100
+
+    Fix gcc 4.5.1 miscompiling drivers/char/i8k.c (again)
+    
+    The fix in commit 6b4e81db2552 ("i8k: Tell gcc that *regs gets
+    clobbered") to work around the gcc miscompiling i8k.c to add "+m
+    (*regs)" caused register pressure problems and a build failure.
+    
+    Changing the 'asm' statement to 'asm volatile' instead should prevent
+    that and works around the gcc bug as well, so we can remove the "+m".
+    
+    [ Background on the gcc bug: a memory clobber fails to mark the function
+      the asm resides in as non-pure (aka "__attribute__((const))"), so if
+      the function does nothing else that triggers the non-pure logic, gcc
+      will think that that function has no side effects at all. As a result,
+      callers will be mis-compiled.
+    
+      Adding the "+m" made gcc see that it's not a pure function, and so
+      does "asm volatile". The problem was never really the need to mark
+      "*regs" as changed, since the memory clobber did that part - the
+      problem was just a bug in the gcc "pure" function analysis  - Linus ]
+    
+    Signed-off-by: Jim Bos <jim876 at xs4all.nl>
+    Acked-by: Jakub Jelinek <jakub at redhat.com>
+    Cc: Andi Kleen <andi at firstfloor.org>
+    Cc: Andreas Schwab <schwab at linux-m68k.org>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+commit 6b4e81db2552bad04100e7d5ddeed7e848f53b48
+Author: Jim Bos <jim876 at xs4all.nl>
+Date:   Sat Nov 13 12:13:53 2010 +0100
+
+    i8k: Tell gcc that *regs gets clobbered
+    
+    More recent GCC caused the i8k driver to stop working, on Slackware
+    compiler was upgraded from gcc-4.4.4 to gcc-4.5.1 after which it didn't
+    work anymore, meaning the driver didn't load or gave total nonsensical
+    output.
+    
+    As it turned out the asm(..) statement forgot to mention it modifies the
+    *regs variable.
+    
+    Credits to Andi Kleen and Andreas Schwab for providing the fix.
+    
+    Signed-off-by: Jim Bos <jim876 at xs4all.nl>
+    Cc: Andi Kleen <andi at firstfloor.org>
+    Cc: Andreas Schwab <schwab at linux-m68k.org>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+---
+diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
+index 3bc0eef..d72433f 100644
+--- a/drivers/char/i8k.c
++++ b/drivers/char/i8k.c
+@@ -120,7 +120,7 @@ static int i8k_smm(struct smm_regs *regs)
+ 	int eax = regs->eax;
+ 
+ #if defined(CONFIG_X86_64)
+-	asm("pushq %%rax\n\t"
++	asm volatile("pushq %%rax\n\t"
+ 		"movl 0(%%rax),%%edx\n\t"
+ 		"pushq %%rdx\n\t"
+ 		"movl 4(%%rax),%%ebx\n\t"
+@@ -146,7 +146,7 @@ static int i8k_smm(struct smm_regs *regs)
+ 		:    "a"(regs)
+ 		:    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+ #else
+-	asm("pushl %%eax\n\t"
++	asm volatile("pushl %%eax\n\t"
+ 	    "movl 0(%%eax),%%edx\n\t"
+ 	    "push %%edx\n\t"
+ 	    "movl 4(%%eax),%%ebx\n\t"
+@@ -167,7 +167,8 @@ static int i8k_smm(struct smm_regs *regs)
+ 	    "movl %%edx,0(%%eax)\n\t"
+ 	    "lahf\n\t"
+ 	    "shrl $8,%%eax\n\t"
+-	    "andl $1,%%eax\n":"=a"(rc)
++	    "andl $1,%%eax\n"
++	    :"=a"(rc)
+ 	    :    "a"(regs)
+ 	    :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+ #endif
diff --git a/kernel.spec b/kernel.spec
index fc7ae59..cb77cf1 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -656,8 +656,6 @@ Patch800: linux-2.6-crash-driver.patch
 
 # virt + ksm patches
 Patch1555: fix_xen_guest_on_old_EC2.patch
-# Already upstream (commit 16518d5ada690643453eb0aef3cc7841d3623c2d)
-Patch1556: kvm-fix-regression-with-cmpxchg8b-on-i386-hosts.patch
 
 # DRM
 Patch1801: drm-polling-fixes.patch
@@ -777,6 +775,8 @@ Patch13645: tpm-autodetect-itpm-devices.patch
 
 Patch13651: kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch
 
+Patch13652: fix-i8k-inline-asm.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1322,7 +1322,6 @@ ApplyPatch linux-2.6-e1000-ich9-montevina.patch
 
 # Assorted Virt Fixes
 ApplyPatch fix_xen_guest_on_old_EC2.patch
-#ApplyPatch kvm-fix-regression-with-cmpxchg8b-on-i386-hosts.patch
 
 ApplyPatch drm-polling-fixes.patch
 ApplyPatch drm-edid-invalid.patch
@@ -1450,6 +1449,8 @@ ApplyPatch tpm-autodetect-itpm-devices.patch
 # CVE-2010-3698
 ApplyPatch kvm-fix-fs-gs-reload-oops-with-invalid-ldt.patch
 
+ApplyPatch fix-i8k-inline-asm.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2036,6 +2037,10 @@ fi
 # and build.
 
 %changelog
+* Tue Nov 23 2010 Kyle McMartin <kyle at redhat.com>
+- fix-i8k-inline-asm.patch: backport gcc miscompilation fix from git
+  [22d3243d, 6b4e81db] (rhbz#647677)
+
 * Mon Nov 22 2010 Jarod Wilson <jarod at redhat.com> 2.6.35.9-62
 - Linux 2.6.35.9
 - IR driver fixes from upstream


More information about the scm-commits mailing list