Commit 301feb652441a7168b59256fc44918075dcab0d5

Authored by David S. Miller
1 parent 58ea1aa07e

[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>

Showing 4 changed files with 58 additions and 30 deletions Side-by-side Diff

arch/sparc64/kernel/head.S
... ... @@ -98,7 +98,7 @@
98 98 .globl prom_boot_mapped_pc, prom_boot_mapping_mode
99 99 .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
100 100 .globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible
101   - .globl is_sun4v, sun4v_chip_type
  101 + .globl is_sun4v, sun4v_chip_type, prom_set_trap_table_name
102 102 prom_peer_name:
103 103 .asciz "peer"
104 104 prom_compatible_name:
... ... @@ -121,6 +121,8 @@
121 121 .asciz "map"
122 122 prom_unmap_name:
123 123 .asciz "unmap"
  124 +prom_set_trap_table_name:
  125 + .asciz "SUNW,set-trap-table"
124 126 prom_sun4v_name:
125 127 .asciz "sun4v"
126 128 prom_niagara_prefix:
127 129  
128 130  
... ... @@ -691,15 +693,38 @@
691 693 sethi %hi(kern_base), %g3
692 694 ldx [%g3 + %lo(kern_base)], %g3
693 695 add %g2, %g3, %o1
  696 + sethi %hi(sparc64_ttable_tl0), %o0
694 697  
695   - call prom_set_trap_table_sun4v
696   - sethi %hi(sparc64_ttable_tl0), %o0
  698 + set prom_set_trap_table_name, %g2
  699 + stx %g2, [%sp + 2047 + 128 + 0x00]
  700 + mov 2, %g2
  701 + stx %g2, [%sp + 2047 + 128 + 0x08]
  702 + mov 0, %g2
  703 + stx %g2, [%sp + 2047 + 128 + 0x10]
  704 + stx %o0, [%sp + 2047 + 128 + 0x18]
  705 + stx %o1, [%sp + 2047 + 128 + 0x20]
  706 + sethi %hi(p1275buf), %g2
  707 + or %g2, %lo(p1275buf), %g2
  708 + ldx [%g2 + 0x08], %o1
  709 + call %o1
  710 + add %sp, (2047 + 128), %o0
697 711  
698 712 ba,pt %xcc, 2f
699 713 nop
700 714  
701   -1: call prom_set_trap_table
702   - sethi %hi(sparc64_ttable_tl0), %o0
  715 +1: sethi %hi(sparc64_ttable_tl0), %o0
  716 + set prom_set_trap_table_name, %g2
  717 + stx %g2, [%sp + 2047 + 128 + 0x00]
  718 + mov 1, %g2
  719 + stx %g2, [%sp + 2047 + 128 + 0x08]
  720 + mov 0, %g2
  721 + stx %g2, [%sp + 2047 + 128 + 0x10]
  722 + stx %o0, [%sp + 2047 + 128 + 0x18]
  723 + sethi %hi(p1275buf), %g2
  724 + or %g2, %lo(p1275buf), %g2
  725 + ldx [%g2 + 0x08], %o1
  726 + call %o1
  727 + add %sp, (2047 + 128), %o0
703 728  
704 729 /* Start using proper page size encodings in ctx register. */
705 730 2: sethi %hi(sparc64_kern_pri_context), %g3
arch/sparc64/kernel/trampoline.S
... ... @@ -345,7 +345,7 @@
345 345 sethi %hi(tramp_stack), %g1
346 346 or %g1, %lo(tramp_stack), %g1
347 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 349 mov 0, %fp
350 350  
351 351 /* Put garbage in these registers to trap any access to them. */
352 352  
353 353  
... ... @@ -411,15 +411,38 @@
411 411 sethi %hi(kern_base), %g3
412 412 ldx [%g3 + %lo(kern_base)], %g3
413 413 add %g2, %g3, %o1
  414 + sethi %hi(sparc64_ttable_tl0), %o0
414 415  
415   - call prom_set_trap_table_sun4v
416   - sethi %hi(sparc64_ttable_tl0), %o0
  416 + set prom_set_trap_table_name, %g2
  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 430 ba,pt %xcc, 2f
419 431 nop
420 432  
421   -1: call prom_set_trap_table
422   - sethi %hi(sparc64_ttable_tl0), %o0
  433 +1: 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 447 2: ldx [%l0], %g6
425 448 ldx [%g6 + TI_TASK], %g4
arch/sparc64/prom/misc.c
... ... @@ -143,22 +143,6 @@
143 143 return 0xff;
144 144 }
145 145  
146   -/* Install Linux trap table so PROM uses that instead of its own. */
147   -void prom_set_trap_table(unsigned long tba)
148   -{
149   - p1275_cmd("SUNW,set-trap-table",
150   - (P1275_ARG(0, P1275_ARG_IN_64B) |
151   - P1275_INOUT(1, 0)), tba);
152   -}
153   -
154   -void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa)
155   -{
156   - p1275_cmd("SUNW,set-trap-table",
157   - (P1275_ARG(0, P1275_ARG_IN_64B) |
158   - P1275_ARG(1, P1275_ARG_IN_64B) |
159   - P1275_INOUT(2, 0)), tba, mmfsa);
160   -}
161   -
162 146 int prom_get_mmu_ihandle(void)
163 147 {
164 148 int node, ret;
include/asm-sparc64/oplib.h
... ... @@ -297,11 +297,7 @@
297 297 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
298 298  
299 299 /* Client interface level routines. */
300   -extern void prom_set_trap_table(unsigned long tba);
301   -extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa);
302   -
303 300 extern long p1275_cmd(const char *, long, ...);
304   -
305 301  
306 302 #if 0
307 303 #define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))