[SPARC64]: Fix lockdep, particularly on SMP.
authorDavid S. Miller <davem@sunset.davemloft.net>
Sun, 16 Sep 2007 18:51:15 +0000 (11:51 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 16 Sep 2007 18:51:15 +0000 (11:51 -0700)
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>
arch/sparc64/kernel/head.S
arch/sparc64/kernel/trampoline.S
arch/sparc64/prom/misc.c
include/asm-sparc64/oplib.h

index 63144ad..c4147ad 100644 (file)
@@ -98,7 +98,7 @@ sparc64_boot:
        .globl  prom_boot_mapped_pc, prom_boot_mapping_mode
        .globl  prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
        .globl  prom_compatible_name, prom_cpu_path, prom_cpu_compatible
-       .globl  is_sun4v, sun4v_chip_type
+       .globl  is_sun4v, sun4v_chip_type, prom_set_trap_table_name
 prom_peer_name:
        .asciz  "peer"
 prom_compatible_name:
@@ -121,6 +121,8 @@ prom_map_name:
        .asciz  "map"
 prom_unmap_name:
        .asciz  "unmap"
+prom_set_trap_table_name:
+       .asciz  "SUNW,set-trap-table"
 prom_sun4v_name:
        .asciz  "sun4v"
 prom_niagara_prefix:
@@ -691,15 +693,38 @@ setup_trap_table:
        sethi   %hi(kern_base), %g3
        ldx     [%g3 + %lo(kern_base)], %g3
        add     %g2, %g3, %o1
+       sethi   %hi(sparc64_ttable_tl0), %o0
 
-       call    prom_set_trap_table_sun4v
-        sethi  %hi(sparc64_ttable_tl0), %o0
+       set     prom_set_trap_table_name, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x00]
+       mov     2, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x08]
+       mov     0, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x10]
+       stx     %o0, [%sp + 2047 + 128 + 0x18]
+       stx     %o1, [%sp + 2047 + 128 + 0x20]
+       sethi   %hi(p1275buf), %g2
+       or      %g2, %lo(p1275buf), %g2
+       ldx     [%g2 + 0x08], %o1
+       call    %o1
+        add    %sp, (2047 + 128), %o0
 
        ba,pt   %xcc, 2f
         nop
 
-1:     call    prom_set_trap_table
-        sethi  %hi(sparc64_ttable_tl0), %o0
+1:     sethi   %hi(sparc64_ttable_tl0), %o0
+       set     prom_set_trap_table_name, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x00]
+       mov     1, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x08]
+       mov     0, %g2
+       stx     %g2, [%sp + 2047 + 128 + 0x10]
+       stx     %o0, [%sp + 2047 + 128 + 0x18]
+       sethi   %hi(p1275buf), %g2
+       or      %g2, %lo(p1275buf), %g2
+       ldx     [%g2 + 0x08], %o1
+       call    %o1
+        add    %sp, (2047 + 128), %o0
 
        /* Start using proper page size encodings in ctx register.  */
 2:     sethi   %hi(sparc64_kern_pri_context), %g3
index 9533a25..04e81dd 100644 (file)
@@ -345,7 +345,7 @@ after_lock_tlb:
        sethi           %hi(tramp_stack), %g1
        or              %g1, %lo(tramp_stack), %g1
        add             %g1, TRAMP_STACK_SIZE, %g1
-       sub             %g1, STACKFRAME_SZ + STACK_BIAS, %sp
+       sub             %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
        mov             0, %fp
 
        /* Put garbage in these registers to trap any access to them.  */
@@ -411,15 +411,38 @@ after_lock_tlb:
        sethi           %hi(kern_base), %g3
        ldx             [%g3 + %lo(kern_base)], %g3
        add             %g2, %g3, %o1
+       sethi           %hi(sparc64_ttable_tl0), %o0
 
-       call            prom_set_trap_table_sun4v
-        sethi          %hi(sparc64_ttable_tl0), %o0
+       set             prom_set_trap_table_name, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x00]
+       mov             2, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x08]
+       mov             0, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x10]
+       stx             %o0, [%sp + 2047 + 128 + 0x18]
+       stx             %o1, [%sp + 2047 + 128 + 0x20]
+       sethi           %hi(p1275buf), %g2
+       or              %g2, %lo(p1275buf), %g2
+       ldx             [%g2 + 0x08], %o1
+       call            %o1
+        add            %sp, (2047 + 128), %o0
 
        ba,pt           %xcc, 2f
         nop
 
-1:     call            prom_set_trap_table
-        sethi          %hi(sparc64_ttable_tl0), %o0
+1:     sethi           %hi(sparc64_ttable_tl0), %o0
+       set             prom_set_trap_table_name, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x00]
+       mov             1, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x08]
+       mov             0, %g2
+       stx             %g2, [%sp + 2047 + 128 + 0x10]
+       stx             %o0, [%sp + 2047 + 128 + 0x18]
+       sethi           %hi(p1275buf), %g2
+       or              %g2, %lo(p1275buf), %g2
+       ldx             [%g2 + 0x08], %o1
+       call            %o1
+        add            %sp, (2047 + 128), %o0
 
 2:     ldx             [%l0], %g6
        ldx             [%g6 + TI_TASK], %g4
index 68c83ad..bbec752 100644 (file)
@@ -143,22 +143,6 @@ unsigned char prom_get_idprom(char *idbuf, int num_bytes)
        return 0xff;
 }
 
-/* Install Linux trap table so PROM uses that instead of its own. */
-void prom_set_trap_table(unsigned long tba)
-{
-       p1275_cmd("SUNW,set-trap-table",
-                 (P1275_ARG(0, P1275_ARG_IN_64B) |
-                  P1275_INOUT(1, 0)), tba);
-}
-
-void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa)
-{
-       p1275_cmd("SUNW,set-trap-table",
-                 (P1275_ARG(0, P1275_ARG_IN_64B) |
-                  P1275_ARG(1, P1275_ARG_IN_64B) |
-                  P1275_INOUT(2, 0)), tba, mmfsa);
-}
-
 int prom_get_mmu_ihandle(void)
 {
        int node, ret;
index 86dc5c0..55c5bb2 100644 (file)
@@ -297,11 +297,7 @@ extern void prom_sun4v_guest_soft_state(void);
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
 
 /* Client interface level routines. */
-extern void prom_set_trap_table(unsigned long tba);
-extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa);
-
 extern long p1275_cmd(const char *, long, ...);
-                                  
 
 #if 0
 #define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))