[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>
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index 9b415ab..c133543 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -60,8 +60,15 @@
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 @@
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
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index aaab319..e22bf5f 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -547,19 +547,33 @@
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++;
}
}
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 3b45db9..96e6316 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -82,9 +82,17 @@
.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
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 482d1ed..686bf6b 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -80,6 +80,9 @@
__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) }