diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-09-16 14:51:15 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-09-16 14:51:15 -0400 |
commit | 301feb652441a7168b59256fc44918075dcab0d5 (patch) | |
tree | 68721bebf1375659be165c4810bb439785d6e96f /arch/sparc64/kernel/trampoline.S | |
parent | 58ea1aa07e3cb4674ab0261b45aa1ba68282a79d (diff) |
[SPARC64]: Fix lockdep, particularly on SMP.
As noted by Al Viro, when we try to call prom_set_trap_table()
in the SMP trampoline code we try to take the PROM call spinlock
which doesn't work because the current thread pointer isn't
valid yet and lockdep depends upon that being correct.
Furthermore, we cannot set the current thread pointer register
because it can't be properly dereferenced until we return from
prom_set_trap_table(). Kernel TLB misses only work after that
call.
So do the PROM call to set the trap table directly instead of
going through the OBP library C code, and thus avoid the lock
altogether.
These calls are guarenteed to be serialized fully.
Since there are now no calls to the prom_set_trap_table{_sun4v}()
library functions, they can be deleted.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/trampoline.S')
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 9533a25ce5d2..04e81dda13d0 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -345,7 +345,7 @@ after_lock_tlb: | |||
345 | sethi %hi(tramp_stack), %g1 | 345 | sethi %hi(tramp_stack), %g1 |
346 | or %g1, %lo(tramp_stack), %g1 | 346 | or %g1, %lo(tramp_stack), %g1 |
347 | add %g1, TRAMP_STACK_SIZE, %g1 | 347 | add %g1, TRAMP_STACK_SIZE, %g1 |
348 | sub %g1, STACKFRAME_SZ + STACK_BIAS, %sp | 348 | sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp |
349 | mov 0, %fp | 349 | mov 0, %fp |
350 | 350 | ||
351 | /* Put garbage in these registers to trap any access to them. */ | 351 | /* Put garbage in these registers to trap any access to them. */ |
@@ -411,15 +411,38 @@ after_lock_tlb: | |||
411 | sethi %hi(kern_base), %g3 | 411 | sethi %hi(kern_base), %g3 |
412 | ldx [%g3 + %lo(kern_base)], %g3 | 412 | ldx [%g3 + %lo(kern_base)], %g3 |
413 | add %g2, %g3, %o1 | 413 | add %g2, %g3, %o1 |
414 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
414 | 415 | ||
415 | call prom_set_trap_table_sun4v | 416 | set prom_set_trap_table_name, %g2 |
416 | sethi %hi(sparc64_ttable_tl0), %o0 | 417 | stx %g2, [%sp + 2047 + 128 + 0x00] |
418 | mov 2, %g2 | ||
419 | stx %g2, [%sp + 2047 + 128 + 0x08] | ||
420 | mov 0, %g2 | ||
421 | stx %g2, [%sp + 2047 + 128 + 0x10] | ||
422 | stx %o0, [%sp + 2047 + 128 + 0x18] | ||
423 | stx %o1, [%sp + 2047 + 128 + 0x20] | ||
424 | sethi %hi(p1275buf), %g2 | ||
425 | or %g2, %lo(p1275buf), %g2 | ||
426 | ldx [%g2 + 0x08], %o1 | ||
427 | call %o1 | ||
428 | add %sp, (2047 + 128), %o0 | ||
417 | 429 | ||
418 | ba,pt %xcc, 2f | 430 | ba,pt %xcc, 2f |
419 | nop | 431 | nop |
420 | 432 | ||
421 | 1: call prom_set_trap_table | 433 | 1: sethi %hi(sparc64_ttable_tl0), %o0 |
422 | sethi %hi(sparc64_ttable_tl0), %o0 | 434 | set prom_set_trap_table_name, %g2 |
435 | stx %g2, [%sp + 2047 + 128 + 0x00] | ||
436 | mov 1, %g2 | ||
437 | stx %g2, [%sp + 2047 + 128 + 0x08] | ||
438 | mov 0, %g2 | ||
439 | stx %g2, [%sp + 2047 + 128 + 0x10] | ||
440 | stx %o0, [%sp + 2047 + 128 + 0x18] | ||
441 | sethi %hi(p1275buf), %g2 | ||
442 | or %g2, %lo(p1275buf), %g2 | ||
443 | ldx [%g2 + 0x08], %o1 | ||
444 | call %o1 | ||
445 | add %sp, (2047 + 128), %o0 | ||
423 | 446 | ||
424 | 2: ldx [%l0], %g6 | 447 | 2: ldx [%l0], %g6 |
425 | ldx [%g6 + TI_TASK], %g4 | 448 | ldx [%g6 + TI_TASK], %g4 |