aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-06-20 15:19:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-06-20 15:25:34 -0400
commit1f6ef2342972dc7fd623f360f84006e2304eb935 (patch)
tree4bc32bb53b6203ba570e21025e1385c0f1db6061
parent89f5b7da2a6bad2e84670422ab8192382a5aeb9f (diff)
[watchdog] hpwdt: fix use of inline assembly
The inline assembly in drivers/watchdog/hpwdt.c was incredibly broken, and included all the function prologue and epilogue stuff, even though it was itself then inside a C function where the compiler would add its own prologue and epilogue on top of it all. This then just _happened_ to work if you had exactly the right compiler version and exactly the right compiler flags, so that gcc just happened to not create any prologue at all (the gcc-generated epilogue wouldn't matter, since it would never be reached). But the more proper way to fix it is to simply not do this. Move the inline asm to the top level, with no surrounding function at all (the better alternative would be to remove the prologue and make it actually use proper description of the arguments to the inline asm, but that's a bigger change than the one I'm willing to make right now). Tested-by: S.Çağlar Onur <caglar@pardus.org.tr> Acked-by: Thomas Mingarelli <Thomas.Mingarelli@hp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/watchdog/hpwdt.c155
1 files changed, 80 insertions, 75 deletions
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 2686f3eaeedf..eaa3f2a79ff5 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -140,49 +140,53 @@ static struct pci_device_id hpwdt_devices[] = {
140}; 140};
141MODULE_DEVICE_TABLE(pci, hpwdt_devices); 141MODULE_DEVICE_TABLE(pci, hpwdt_devices);
142 142
143extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, unsigned long *pRomEntry);
144
143#ifndef CONFIG_X86_64 145#ifndef CONFIG_X86_64
144/* --32 Bit Bios------------------------------------------------------------ */ 146/* --32 Bit Bios------------------------------------------------------------ */
145 147
146#define HPWDT_ARCH 32 148#define HPWDT_ARCH 32
147 149
148asmlinkage void asminline_call(struct cmn_registers *pi86Regs, 150asm(".text \n\t"
149 unsigned long *pRomEntry) 151 ".align 4 \n"
150{ 152 "asminline_call: \n\t"
151 asm("pushl %ebp \n\t" 153 "pushl %ebp \n\t"
152 "movl %esp, %ebp \n\t" 154 "movl %esp, %ebp \n\t"
153 "pusha \n\t" 155 "pusha \n\t"
154 "pushf \n\t" 156 "pushf \n\t"
155 "push %es \n\t" 157 "push %es \n\t"
156 "push %ds \n\t" 158 "push %ds \n\t"
157 "pop %es \n\t" 159 "pop %es \n\t"
158 "movl 8(%ebp),%eax \n\t" 160 "movl 8(%ebp),%eax \n\t"
159 "movl 4(%eax),%ebx \n\t" 161 "movl 4(%eax),%ebx \n\t"
160 "movl 8(%eax),%ecx \n\t" 162 "movl 8(%eax),%ecx \n\t"
161 "movl 12(%eax),%edx \n\t" 163 "movl 12(%eax),%edx \n\t"
162 "movl 16(%eax),%esi \n\t" 164 "movl 16(%eax),%esi \n\t"
163 "movl 20(%eax),%edi \n\t" 165 "movl 20(%eax),%edi \n\t"
164 "movl (%eax),%eax \n\t" 166 "movl (%eax),%eax \n\t"
165 "push %cs \n\t" 167 "push %cs \n\t"
166 "call *12(%ebp) \n\t" 168 "call *12(%ebp) \n\t"
167 "pushf \n\t" 169 "pushf \n\t"
168 "pushl %eax \n\t" 170 "pushl %eax \n\t"
169 "movl 8(%ebp),%eax \n\t" 171 "movl 8(%ebp),%eax \n\t"
170 "movl %ebx,4(%eax) \n\t" 172 "movl %ebx,4(%eax) \n\t"
171 "movl %ecx,8(%eax) \n\t" 173 "movl %ecx,8(%eax) \n\t"
172 "movl %edx,12(%eax) \n\t" 174 "movl %edx,12(%eax) \n\t"
173 "movl %esi,16(%eax) \n\t" 175 "movl %esi,16(%eax) \n\t"
174 "movl %edi,20(%eax) \n\t" 176 "movl %edi,20(%eax) \n\t"
175 "movw %ds,24(%eax) \n\t" 177 "movw %ds,24(%eax) \n\t"
176 "movw %es,26(%eax) \n\t" 178 "movw %es,26(%eax) \n\t"
177 "popl %ebx \n\t" 179 "popl %ebx \n\t"
178 "movl %ebx,(%eax) \n\t" 180 "movl %ebx,(%eax) \n\t"
179 "popl %ebx \n\t" 181 "popl %ebx \n\t"
180 "movl %ebx,28(%eax) \n\t" 182 "movl %ebx,28(%eax) \n\t"
181 "pop %es \n\t" 183 "pop %es \n\t"
182 "popf \n\t" 184 "popf \n\t"
183 "popa \n\t" 185 "popa \n\t"
184 "leave \n\t" "ret"); 186 "leave \n\t"
185} 187 "ret \n\t"
188 ".previous");
189
186 190
187/* 191/*
188 * cru_detect 192 * cru_detect
@@ -333,43 +337,44 @@ static int __devinit detect_cru_service(void)
333 337
334#define HPWDT_ARCH 64 338#define HPWDT_ARCH 64
335 339
336asmlinkage void asminline_call(struct cmn_registers *pi86Regs, 340asm(".text \n\t"
337 unsigned long *pRomEntry) 341 ".align 4 \n"
338{ 342 "asminline_call: \n\t"
339 asm("pushq %rbp \n\t" 343 "pushq %rbp \n\t"
340 "movq %rsp, %rbp \n\t" 344 "movq %rsp, %rbp \n\t"
341 "pushq %rax \n\t" 345 "pushq %rax \n\t"
342 "pushq %rbx \n\t" 346 "pushq %rbx \n\t"
343 "pushq %rdx \n\t" 347 "pushq %rdx \n\t"
344 "pushq %r12 \n\t" 348 "pushq %r12 \n\t"
345 "pushq %r9 \n\t" 349 "pushq %r9 \n\t"
346 "movq %rsi, %r12 \n\t" 350 "movq %rsi, %r12 \n\t"
347 "movq %rdi, %r9 \n\t" 351 "movq %rdi, %r9 \n\t"
348 "movl 4(%r9),%ebx \n\t" 352 "movl 4(%r9),%ebx \n\t"
349 "movl 8(%r9),%ecx \n\t" 353 "movl 8(%r9),%ecx \n\t"
350 "movl 12(%r9),%edx \n\t" 354 "movl 12(%r9),%edx \n\t"
351 "movl 16(%r9),%esi \n\t" 355 "movl 16(%r9),%esi \n\t"
352 "movl 20(%r9),%edi \n\t" 356 "movl 20(%r9),%edi \n\t"
353 "movl (%r9),%eax \n\t" 357 "movl (%r9),%eax \n\t"
354 "call *%r12 \n\t" 358 "call *%r12 \n\t"
355 "pushfq \n\t" 359 "pushfq \n\t"
356 "popq %r12 \n\t" 360 "popq %r12 \n\t"
357 "popfq \n\t" 361 "popfq \n\t"
358 "movl %eax, (%r9) \n\t" 362 "movl %eax, (%r9) \n\t"
359 "movl %ebx, 4(%r9) \n\t" 363 "movl %ebx, 4(%r9) \n\t"
360 "movl %ecx, 8(%r9) \n\t" 364 "movl %ecx, 8(%r9) \n\t"
361 "movl %edx, 12(%r9) \n\t" 365 "movl %edx, 12(%r9) \n\t"
362 "movl %esi, 16(%r9) \n\t" 366 "movl %esi, 16(%r9) \n\t"
363 "movl %edi, 20(%r9) \n\t" 367 "movl %edi, 20(%r9) \n\t"
364 "movq %r12, %rax \n\t" 368 "movq %r12, %rax \n\t"
365 "movl %eax, 28(%r9) \n\t" 369 "movl %eax, 28(%r9) \n\t"
366 "popq %r9 \n\t" 370 "popq %r9 \n\t"
367 "popq %r12 \n\t" 371 "popq %r12 \n\t"
368 "popq %rdx \n\t" 372 "popq %rdx \n\t"
369 "popq %rbx \n\t" 373 "popq %rbx \n\t"
370 "popq %rax \n\t" 374 "popq %rax \n\t"
371 "leave \n\t" "ret"); 375 "leave \n\t"
372} 376 "ret \n\t"
377 ".previous");
373 378
374/* 379/*
375 * dmi_find_cru 380 * dmi_find_cru