diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-06 01:27:28 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:11:50 -0500 |
commit | 45fec05f805a113372c9a7ff4c653ac749f6921c (patch) | |
tree | 36fc99d10656775acb8e9442719447d64ac30a03 /arch/sparc64/kernel | |
parent | 314981ac7177a933319e3c071a5cf0a579205e6e (diff) |
[SPARC64]: Sanitize %pstate writes for sun4v.
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>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/ktlb.S | 18 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 26 | ||||
-rw-r--r-- | arch/sparc64/kernel/tsb.S | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/vmlinux.lds.S | 3 |
4 files changed, 49 insertions, 10 deletions
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S index 9b415ab6db6b..c1335432124e 100644 --- a/arch/sparc64/kernel/ktlb.S +++ b/arch/sparc64/kernel/ktlb.S | |||
@@ -60,8 +60,15 @@ kvmap_itlb_load: | |||
60 | retry | 60 | retry |
61 | 61 | ||
62 | kvmap_itlb_longpath: | 62 | kvmap_itlb_longpath: |
63 | rdpr %pstate, %g5 | 63 | |
64 | 661: rdpr %pstate, %g5 | ||
64 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate | 65 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate |
66 | .section .gl_2insn_patch, "ax" | ||
67 | .word 661b | ||
68 | nop | ||
69 | nop | ||
70 | .previous | ||
71 | |||
65 | rdpr %tpc, %g5 | 72 | rdpr %tpc, %g5 |
66 | ba,pt %xcc, sparc64_realfault_common | 73 | ba,pt %xcc, sparc64_realfault_common |
67 | mov FAULT_CODE_ITLB, %g4 | 74 | mov FAULT_CODE_ITLB, %g4 |
@@ -161,8 +168,15 @@ kvmap_check_obp: | |||
161 | nop | 168 | nop |
162 | 169 | ||
163 | kvmap_dtlb_longpath: | 170 | kvmap_dtlb_longpath: |
164 | rdpr %pstate, %g5 | 171 | |
172 | 661: rdpr %pstate, %g5 | ||
165 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate | 173 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate |
174 | .section .gl_2insn_patch, "ax" | ||
175 | .word 661b | ||
176 | nop | ||
177 | nop | ||
178 | .previous | ||
179 | |||
166 | rdpr %tl, %g4 | 180 | rdpr %tl, %g4 |
167 | cmp %g4, 1 | 181 | cmp %g4, 1 |
168 | mov TLB_TAG_ACCESS, %g4 | 182 | mov TLB_TAG_ACCESS, %g4 |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index aaab319ad885..e22bf5fc92ce 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -547,19 +547,33 @@ static void __init per_cpu_patch(void) | |||
547 | 547 | ||
548 | static void __init gl_patch(void) | 548 | static void __init gl_patch(void) |
549 | { | 549 | { |
550 | struct gl_1insn_patch_entry *p; | 550 | struct gl_1insn_patch_entry *p1; |
551 | struct gl_2insn_patch_entry *p2; | ||
551 | 552 | ||
552 | if (tlb_type != hypervisor) | 553 | if (tlb_type != hypervisor) |
553 | return; | 554 | return; |
554 | 555 | ||
555 | p = &__gl_1insn_patch; | 556 | p1 = &__gl_1insn_patch; |
556 | while (p < &__gl_1insn_patch_end) { | 557 | while (p1 < &__gl_1insn_patch_end) { |
557 | unsigned long addr = p->addr; | 558 | unsigned long addr = p1->addr; |
558 | 559 | ||
559 | *(unsigned int *) (addr + 0) = p->insn; | 560 | *(unsigned int *) (addr + 0) = p1->insn; |
560 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); | 561 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); |
561 | 562 | ||
562 | p++; | 563 | p1++; |
564 | } | ||
565 | |||
566 | p2 = &__gl_2insn_patch; | ||
567 | while (p2 < &__gl_2insn_patch_end) { | ||
568 | unsigned long addr = p2->addr; | ||
569 | |||
570 | *(unsigned int *) (addr + 0) = p2->insns[0]; | ||
571 | __asm__ __volatile__("flush %0" : : "r" (addr + 0)); | ||
572 | |||
573 | *(unsigned int *) (addr + 3) = p2->insns[1]; | ||
574 | __asm__ __volatile__("flush %0" : : "r" (addr + 4)); | ||
575 | |||
576 | p2++; | ||
563 | } | 577 | } |
564 | } | 578 | } |
565 | 579 | ||
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S index 3b45db98005a..96e63168d8b2 100644 --- a/arch/sparc64/kernel/tsb.S +++ b/arch/sparc64/kernel/tsb.S | |||
@@ -82,9 +82,17 @@ tsb_itlb_load: | |||
82 | .globl tsb_do_fault | 82 | .globl tsb_do_fault |
83 | tsb_do_fault: | 83 | tsb_do_fault: |
84 | cmp %g3, FAULT_CODE_DTLB | 84 | cmp %g3, FAULT_CODE_DTLB |
85 | rdpr %pstate, %g5 | 85 | |
86 | 661: rdpr %pstate, %g5 | ||
87 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate | ||
88 | .section .gl_2insn_patch, "ax" | ||
89 | .word 661b | ||
90 | nop | ||
91 | nop | ||
92 | .previous | ||
93 | |||
86 | bne,pn %xcc, tsb_do_itlb_fault | 94 | bne,pn %xcc, tsb_do_itlb_fault |
87 | wrpr %g5, PSTATE_AG | PSTATE_MG, %pstate | 95 | nop |
88 | 96 | ||
89 | tsb_do_dtlb_fault: | 97 | tsb_do_dtlb_fault: |
90 | rdpr %tl, %g4 | 98 | rdpr %tl, %g4 |
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index 482d1ed87f4d..686bf6b3b03f 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -80,6 +80,9 @@ SECTIONS | |||
80 | __gl_1insn_patch = .; | 80 | __gl_1insn_patch = .; |
81 | .gl_1insn_patch : { *(.gl_1insn_patch) } | 81 | .gl_1insn_patch : { *(.gl_1insn_patch) } |
82 | __gl_1insn_patch_end = .; | 82 | __gl_1insn_patch_end = .; |
83 | __gl_2insn_patch = .; | ||
84 | .gl_2insn_patch : { *(.gl_2insn_patch) } | ||
85 | __gl_2insn_patch_end = .; | ||
83 | . = ALIGN(8192); | 86 | . = ALIGN(8192); |
84 | __initramfs_start = .; | 87 | __initramfs_start = .; |
85 | .init.ramfs : { *(.init.ramfs) } | 88 | .init.ramfs : { *(.init.ramfs) } |