| commit 22d3243de86bc92d874abb7c5b185d5c47aba323 |
| Author: Jim Bos <jim876@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@xs4all.nl> |
| Acked-by: Jakub Jelinek <jakub@redhat.com> |
| Cc: Andi Kleen <andi@firstfloor.org> |
| Cc: Andreas Schwab <schwab@linux-m68k.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| commit 6b4e81db2552bad04100e7d5ddeed7e848f53b48 |
| Author: Jim Bos <jim876@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@xs4all.nl> |
| Cc: Andi Kleen <andi@firstfloor.org> |
| Cc: Andreas Schwab <schwab@linux-m68k.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| |
| diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c |
| index 3bc0eef..d72433f 100644 |
| |
| |
| @@ -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 |