[SPARC64]: Sanitize %pstate writes for sun4v.
authorDavid S. Miller <davem@sunset.davemloft.net>
Mon, 6 Feb 2006 06:27:28 +0000 (22:27 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 20 Mar 2006 09:11:50 +0000 (01:11 -0800)
If we're just switching between different alternate global
sets, nop it out on sun4v.  Also, get rid of all of the
alternate global save/restore in the OBP CIF trampoline code.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/kernel/ktlb.S
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/tsb.S
arch/sparc64/kernel/vmlinux.lds.S
arch/sparc64/mm/ultra.S
arch/sparc64/prom/cif.S
include/asm-sparc64/cpudata.h

index 9b415ab6db6b0e09fb85bf59a221a7f163b6f4f1..c1335432124e3b4e1002a26b0714a2312cddff11 100644 (file)
@@ -60,8 +60,15 @@ kvmap_itlb_load:
        retry
 
 kvmap_itlb_longpath:
-       rdpr    %pstate, %g5
+
+661:   rdpr    %pstate, %g5
        wrpr    %g5, PSTATE_AG | PSTATE_MG, %pstate
+       .section .gl_2insn_patch, "ax"
+       .word   661b
+       nop
+       nop
+       .previous
+
        rdpr    %tpc, %g5
        ba,pt   %xcc, sparc64_realfault_common
         mov    FAULT_CODE_ITLB, %g4
@@ -161,8 +168,15 @@ kvmap_check_obp:
         nop
 
 kvmap_dtlb_longpath:
-       rdpr    %pstate, %g5
+
+661:   rdpr    %pstate, %g5
        wrpr    %g5, PSTATE_AG | PSTATE_MG, %pstate
+       .section .gl_2insn_patch, "ax"
+       .word   661b
+       nop
+       nop
+       .previous
+
        rdpr    %tl, %g4
        cmp     %g4, 1
        mov     TLB_TAG_ACCESS, %g4
index aaab319ad885e3bd0c9cb19dd4d48f32d6294920..e22bf5fc92ce8213d023d8ce0675f26a83a586f9 100644 (file)
@@ -547,19 +547,33 @@ static void __init per_cpu_patch(void)
 
 static void __init gl_patch(void)
 {
-       struct gl_1insn_patch_entry *p;
+       struct gl_1insn_patch_entry *p1;
+       struct gl_2insn_patch_entry *p2;
 
        if (tlb_type != hypervisor)
                return;
 
-       p = &__gl_1insn_patch;
-       while (p < &__gl_1insn_patch_end) {
-               unsigned long addr = p->addr;
+       p1 = &__gl_1insn_patch;
+       while (p1 < &__gl_1insn_patch_end) {
+               unsigned long addr = p1->addr;
 
-               *(unsigned int *) (addr +  0) = p->insn;
+               *(unsigned int *) (addr +  0) = p1->insn;
                __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
 
-               p++;
+               p1++;
+       }
+
+       p2 = &__gl_2insn_patch;
+       while (p2 < &__gl_2insn_patch_end) {
+               unsigned long addr = p2->addr;
+
+               *(unsigned int *) (addr +  0) = p2->insns[0];
+               __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
+
+               *(unsigned int *) (addr +  3) = p2->insns[1];
+               __asm__ __volatile__("flush     %0" : : "r" (addr +  4));
+
+               p2++;
        }
 }
 
index 3b45db98005a5a7a6e481ee9c53c2cd178b2a92b..96e63168d8b2644ad1fd958409b54f1a5f2276dc 100644 (file)
@@ -82,9 +82,17 @@ tsb_itlb_load:
        .globl          tsb_do_fault
 tsb_do_fault:
        cmp             %g3, FAULT_CODE_DTLB
-       rdpr            %pstate, %g5
+
+661:   rdpr            %pstate, %g5
+       wrpr            %g5, PSTATE_AG | PSTATE_MG, %pstate
+       .section        .gl_2insn_patch, "ax"
+       .word           661b
+       nop
+       nop
+       .previous
+
        bne,pn          %xcc, tsb_do_itlb_fault
-        wrpr           %g5, PSTATE_AG | PSTATE_MG, %pstate
+        nop
 
 tsb_do_dtlb_fault:
        rdpr    %tl, %g4
index 482d1ed87f4da6b59040c9c0818d5a87cb8a920c..686bf6b3b03f4cd82b8ca84208d3d47b502cd08e 100644 (file)
@@ -80,6 +80,9 @@ SECTIONS
   __gl_1insn_patch = .;
   .gl_1insn_patch : { *(.gl_1insn_patch) }
   __gl_1insn_patch_end = .;
+  __gl_2insn_patch = .;
+  .gl_2insn_patch : { *(.gl_2insn_patch) }
+  __gl_2insn_patch_end = .;
   . = ALIGN(8192); 
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
index cac58d66fca904f178c4a5b7b46acf01665a347e..5dd86ad0d29f83a1a75c0d25c2761af3cb6434f0 100644 (file)
@@ -444,8 +444,15 @@ xcall_flush_tlb_kernel_range:      /* 22 insns */
         */
        .globl          xcall_sync_tick
 xcall_sync_tick:
-       rdpr            %pstate, %g2
+
+661:   rdpr            %pstate, %g2
        wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
+       .section        .gl_2insn_patch, "ax"
+       .word           661b
+       nop
+       nop
+       .previous
+
        rdpr            %pil, %g2
        wrpr            %g0, 15, %pil
        sethi           %hi(109f), %g7
@@ -468,8 +475,15 @@ xcall_sync_tick:
         */
        .globl          xcall_report_regs
 xcall_report_regs:
-       rdpr            %pstate, %g2
+
+661:   rdpr            %pstate, %g2
        wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
+       .section        .gl_2insn_patch, "ax"
+       .word           661b
+       nop
+       nop
+       .previous
+
        rdpr            %pil, %g2
        wrpr            %g0, 15, %pil
        sethi           %hi(109f), %g7
index 29d0ae74aed8d8dc32b28f9cc64f4c8aadda7e34..5f27ad779c0c578097218e44b005eaed770acf7d 100644 (file)
@@ -1,10 +1,12 @@
 /* cif.S: PROM entry/exit assembler trampolines.
  *
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 2005, 2006 David S. Miller <davem@davemloft.net>
  */
 
 #include <asm/pstate.h>
+#include <asm/cpudata.h>
+#include <asm/thread_info.h>
 
        .text
        .globl  prom_cif_interface
@@ -12,78 +14,16 @@ prom_cif_interface:
        sethi   %hi(p1275buf), %o0
        or      %o0, %lo(p1275buf), %o0
        ldx     [%o0 + 0x010], %o1      ! prom_cif_stack
-       save    %o1, -0x190, %sp
+       save    %o1, -192, %sp
        ldx     [%i0 + 0x008], %l2      ! prom_cif_handler
-       rdpr    %pstate, %l4
-       wrpr    %g0, 0x15, %pstate      ! save alternate globals
-       stx     %g1, [%sp + 2047 + 0x0b0]
-       stx     %g2, [%sp + 2047 + 0x0b8]
-       stx     %g3, [%sp + 2047 + 0x0c0]
-       stx     %g4, [%sp + 2047 + 0x0c8]
-       stx     %g5, [%sp + 2047 + 0x0d0]
-       stx     %g6, [%sp + 2047 + 0x0d8]
-       stx     %g7, [%sp + 2047 + 0x0e0]
-       wrpr    %g0, 0x814, %pstate     ! save interrupt globals
-       stx     %g1, [%sp + 2047 + 0x0e8]
-       stx     %g2, [%sp + 2047 + 0x0f0]
-       stx     %g3, [%sp + 2047 + 0x0f8]
-       stx     %g4, [%sp + 2047 + 0x100]
-       stx     %g5, [%sp + 2047 + 0x108]
-       stx     %g6, [%sp + 2047 + 0x110]
-       stx     %g7, [%sp + 2047 + 0x118]
-       wrpr    %g0, 0x14, %pstate      ! save normal globals
-       stx     %g1, [%sp + 2047 + 0x120]
-       stx     %g2, [%sp + 2047 + 0x128]
-       stx     %g3, [%sp + 2047 + 0x130]
-       stx     %g4, [%sp + 2047 + 0x138]
-       stx     %g5, [%sp + 2047 + 0x140]
-       stx     %g6, [%sp + 2047 + 0x148]
-       stx     %g7, [%sp + 2047 + 0x150]
-       wrpr    %g0, 0x414, %pstate     ! save mmu globals
-       stx     %g1, [%sp + 2047 + 0x158]
-       stx     %g2, [%sp + 2047 + 0x160]
-       stx     %g3, [%sp + 2047 + 0x168]
-       stx     %g4, [%sp + 2047 + 0x170]
-       stx     %g5, [%sp + 2047 + 0x178]
-       stx     %g6, [%sp + 2047 + 0x180]
-       stx     %g7, [%sp + 2047 + 0x188]
-       mov     %g1, %l0                ! also save to locals, so we can handle
-       mov     %g2, %l1                ! tlb faults later on, when accessing
-       mov     %g3, %l3                ! the stack.
-       mov     %g7, %l5
-       wrpr    %l4, PSTATE_IE, %pstate ! turn off interrupts
+       mov     %g4, %l0
+       mov     %g5, %l1
+       mov     %g6, %l3
        call    %l2
         add    %i0, 0x018, %o0         ! prom_args
-       wrpr    %g0, 0x414, %pstate     ! restore mmu globals
-       mov     %l0, %g1
-       mov     %l1, %g2
-       mov     %l3, %g3
-       mov     %l5, %g7
-       wrpr    %g0, 0x14, %pstate      ! restore normal globals
-       ldx     [%sp + 2047 + 0x120], %g1
-       ldx     [%sp + 2047 + 0x128], %g2
-       ldx     [%sp + 2047 + 0x130], %g3
-       ldx     [%sp + 2047 + 0x138], %g4
-       ldx     [%sp + 2047 + 0x140], %g5
-       ldx     [%sp + 2047 + 0x148], %g6
-       ldx     [%sp + 2047 + 0x150], %g7
-       wrpr    %g0, 0x814, %pstate     ! restore interrupt globals
-       ldx     [%sp + 2047 + 0x0e8], %g1
-       ldx     [%sp + 2047 + 0x0f0], %g2
-       ldx     [%sp + 2047 + 0x0f8], %g3
-       ldx     [%sp + 2047 + 0x100], %g4
-       ldx     [%sp + 2047 + 0x108], %g5
-       ldx     [%sp + 2047 + 0x110], %g6
-       ldx     [%sp + 2047 + 0x118], %g7
-       wrpr    %g0, 0x15, %pstate      ! restore alternate globals
-       ldx     [%sp + 2047 + 0x0b0], %g1
-       ldx     [%sp + 2047 + 0x0b8], %g2
-       ldx     [%sp + 2047 + 0x0c0], %g3
-       ldx     [%sp + 2047 + 0x0c8], %g4
-       ldx     [%sp + 2047 + 0x0d0], %g5
-       ldx     [%sp + 2047 + 0x0d8], %g6
-       ldx     [%sp + 2047 + 0x0e0], %g7
-       wrpr    %l4, 0, %pstate ! restore original pstate
+       mov     %l0, %g4
+       mov     %l1, %g5
+       mov     %l3, %g6
        ret
         restore
 
@@ -91,135 +31,18 @@ prom_cif_interface:
 prom_cif_callback:
        sethi   %hi(p1275buf), %o1
        or      %o1, %lo(p1275buf), %o1
-       save    %sp, -0x270, %sp
-       rdpr    %pstate, %l4
-       wrpr    %g0, 0x15, %pstate      ! save PROM alternate globals
-       stx     %g1, [%sp + 2047 + 0x0b0]
-       stx     %g2, [%sp + 2047 + 0x0b8]
-       stx     %g3, [%sp + 2047 + 0x0c0]
-       stx     %g4, [%sp + 2047 + 0x0c8]
-       stx     %g5, [%sp + 2047 + 0x0d0]
-       stx     %g6, [%sp + 2047 + 0x0d8]
-       stx     %g7, [%sp + 2047 + 0x0e0]
-                                       ! restore Linux alternate globals
-       ldx     [%sp + 2047 + 0x190], %g1
-       ldx     [%sp + 2047 + 0x198], %g2
-       ldx     [%sp + 2047 + 0x1a0], %g3
-       ldx     [%sp + 2047 + 0x1a8], %g4
-       ldx     [%sp + 2047 + 0x1b0], %g5
-       ldx     [%sp + 2047 + 0x1b8], %g6
-       ldx     [%sp + 2047 + 0x1c0], %g7
-       wrpr    %g0, 0x814, %pstate     ! save PROM interrupt globals
-       stx     %g1, [%sp + 2047 + 0x0e8]
-       stx     %g2, [%sp + 2047 + 0x0f0]
-       stx     %g3, [%sp + 2047 + 0x0f8]
-       stx     %g4, [%sp + 2047 + 0x100]
-       stx     %g5, [%sp + 2047 + 0x108]
-       stx     %g6, [%sp + 2047 + 0x110]
-       stx     %g7, [%sp + 2047 + 0x118]
-                                       ! restore Linux interrupt globals
-       ldx     [%sp + 2047 + 0x1c8], %g1
-       ldx     [%sp + 2047 + 0x1d0], %g2
-       ldx     [%sp + 2047 + 0x1d8], %g3
-       ldx     [%sp + 2047 + 0x1e0], %g4
-       ldx     [%sp + 2047 + 0x1e8], %g5
-       ldx     [%sp + 2047 + 0x1f0], %g6
-       ldx     [%sp + 2047 + 0x1f8], %g7
-       wrpr    %g0, 0x14, %pstate      ! save PROM normal globals
-       stx     %g1, [%sp + 2047 + 0x120]
-       stx     %g2, [%sp + 2047 + 0x128]
-       stx     %g3, [%sp + 2047 + 0x130]
-       stx     %g4, [%sp + 2047 + 0x138]
-       stx     %g5, [%sp + 2047 + 0x140]
-       stx     %g6, [%sp + 2047 + 0x148]
-       stx     %g7, [%sp + 2047 + 0x150]
-                                       ! restore Linux normal globals
-       ldx     [%sp + 2047 + 0x200], %g1
-       ldx     [%sp + 2047 + 0x208], %g2
-       ldx     [%sp + 2047 + 0x210], %g3
-       ldx     [%sp + 2047 + 0x218], %g4
-       ldx     [%sp + 2047 + 0x220], %g5
-       ldx     [%sp + 2047 + 0x228], %g6
-       ldx     [%sp + 2047 + 0x230], %g7
-       wrpr    %g0, 0x414, %pstate     ! save PROM mmu globals
-       stx     %g1, [%sp + 2047 + 0x158]
-       stx     %g2, [%sp + 2047 + 0x160]
-       stx     %g3, [%sp + 2047 + 0x168]
-       stx     %g4, [%sp + 2047 + 0x170]
-       stx     %g5, [%sp + 2047 + 0x178]
-       stx     %g6, [%sp + 2047 + 0x180]
-       stx     %g7, [%sp + 2047 + 0x188]
-                                       ! restore Linux mmu globals
-       ldx     [%sp + 2047 + 0x238], %o0
-       ldx     [%sp + 2047 + 0x240], %o1
-       ldx     [%sp + 2047 + 0x248], %l2
-       ldx     [%sp + 2047 + 0x250], %l3
-       ldx     [%sp + 2047 + 0x258], %l5
-       ldx     [%sp + 2047 + 0x260], %l6
-       ldx     [%sp + 2047 + 0x268], %l7
-                                       ! switch to Linux tba
-       sethi   %hi(sparc64_ttable_tl0), %l1
-       rdpr    %tba, %l0               ! save PROM tba
-       mov     %o0, %g1
-       mov     %o1, %g2
-       mov     %l2, %g3
-       mov     %l3, %g4
-       mov     %l5, %g5
-       mov     %l6, %g6
-       mov     %l7, %g7
-       wrpr    %l1, %tba               ! install Linux tba
-       wrpr    %l4, 0, %pstate         ! restore PSTATE
+       save    %sp, -192, %sp
+       TRAP_LOAD_THREAD_REG(%g6, %g1)
+       LOAD_PER_CPU_BASE(%g5, %g6, %g4, %g3, %o0)
+       ldx     [%g6 + TI_TASK], %g4
        call    prom_world
-        mov    %g0, %o0
+        mov    0, %o0
        ldx     [%i1 + 0x000], %l2
        call    %l2
         mov    %i0, %o0
        mov     %o0, %l1
        call    prom_world
-        or     %g0, 1, %o0
-       wrpr    %g0, 0x14, %pstate      ! interrupts off
-                                       ! restore PROM mmu globals
-       ldx     [%sp + 2047 + 0x158], %o0
-       ldx     [%sp + 2047 + 0x160], %o1
-       ldx     [%sp + 2047 + 0x168], %l2
-       ldx     [%sp + 2047 + 0x170], %l3
-       ldx     [%sp + 2047 + 0x178], %l5
-       ldx     [%sp + 2047 + 0x180], %l6
-       ldx     [%sp + 2047 + 0x188], %l7
-       wrpr    %g0, 0x414, %pstate     ! restore PROM mmu globals
-       mov     %o0, %g1
-       mov     %o1, %g2
-       mov     %l2, %g3
-       mov     %l3, %g4
-       mov     %l5, %g5
-       mov     %l6, %g6
-       mov     %l7, %g7
-       wrpr    %l0, %tba               ! restore PROM tba
-       wrpr    %g0, 0x14, %pstate      ! restore PROM normal globals
-       ldx     [%sp + 2047 + 0x120], %g1
-       ldx     [%sp + 2047 + 0x128], %g2
-       ldx     [%sp + 2047 + 0x130], %g3
-       ldx     [%sp + 2047 + 0x138], %g4
-       ldx     [%sp + 2047 + 0x140], %g5
-       ldx     [%sp + 2047 + 0x148], %g6
-       ldx     [%sp + 2047 + 0x150], %g7
-       wrpr    %g0, 0x814, %pstate     ! restore PROM interrupt globals
-       ldx     [%sp + 2047 + 0x0e8], %g1
-       ldx     [%sp + 2047 + 0x0f0], %g2
-       ldx     [%sp + 2047 + 0x0f8], %g3
-       ldx     [%sp + 2047 + 0x100], %g4
-       ldx     [%sp + 2047 + 0x108], %g5
-       ldx     [%sp + 2047 + 0x110], %g6
-       ldx     [%sp + 2047 + 0x118], %g7
-       wrpr    %g0, 0x15, %pstate      ! restore PROM alternate globals
-       ldx     [%sp + 2047 + 0x0b0], %g1
-       ldx     [%sp + 2047 + 0x0b8], %g2
-       ldx     [%sp + 2047 + 0x0c0], %g3
-       ldx     [%sp + 2047 + 0x0c8], %g4
-       ldx     [%sp + 2047 + 0x0d0], %g5
-       ldx     [%sp + 2047 + 0x0d8], %g6
-       ldx     [%sp + 2047 + 0x0e0], %g7
-       wrpr    %l4, 0, %pstate
+        mov    1, %o0
        ret
         restore %l1, 0, %o0
 
index 8666440c89af1c7dfc331b047b9f08eb839aacb3..998145b92653d4d5d5d1a7ef5f5678471d78f9db 100644 (file)
@@ -78,6 +78,12 @@ struct gl_1insn_patch_entry {
        unsigned int    insn;
 };
 extern struct gl_1insn_patch_entry __gl_1insn_patch, __gl_1insn_patch_end;
+
+struct gl_2insn_patch_entry {
+       unsigned int    addr;
+       unsigned int    insns[2];
+};
+extern struct gl_2insn_patch_entry __gl_2insn_patch, __gl_2insn_patch_end;
 #endif /* !(__ASSEMBLY__) */
 
 #define TRAP_PER_CPU_THREAD    0x00