Commit 301feb652441a7168b59256fc44918075dcab0d5
1 parent
58ea1aa07e
Exists in
master
and in
7 other branches
[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)) |