[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) }