[SPARC64]: Fix unaligned access winfxup handling on SUN4V.

Another case where we have to force ourselves into global register
level one.  Also make sure the arguments passed to sun4v_do_mna() are
correct.

This area actually needs some more work, for example spill fixup is
not necessarily going to do the right thing for this case.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S
index 57ccdae..654244a 100644
--- a/arch/sparc64/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc64/kernel/sun4v_tlb_miss.S
@@ -137,7 +137,7 @@
 sun4v_dtlb_prot:
 	SET_GL(1)
 
-	/* Load MMU Miss base into %g2.  */
+	/* Load MMU Miss base into %g5.  */
 	ldxa	[%g0] ASI_SCRATCHPAD, %g5
 	
 	ldx	[%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
@@ -148,9 +148,10 @@
 	ba,pt	%xcc, sparc64_realfault_common
 	 mov	FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
 
-	/* Called from trap table with TAG TARGET placed into
-	 * %g6, SCRATCHPAD_UTSBREG1 contents in %g1, and
-	 * SCRATCHPAD_MMU_MISS contents in %g2.
+	/* Called from trap table:
+	 * %g4:	vaddr
+	 * %g5:	context
+	 * %g6: TAG TARGET
 	 */
 sun4v_itsb_miss:
 	mov	SCRATCHPAD_UTSBREG1, %g1
@@ -159,8 +160,10 @@
 	 mov	FAULT_CODE_ITLB, %g3
 	ba,a,pt	%xcc, sun4v_tsb_miss_common
 
-	/* Called from trap table with TAG TARGET placed into
-	 * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1.
+	/* Called from trap table:
+	 * %g4:	vaddr
+	 * %g5:	context
+	 * %g6: TAG TARGET
 	 */
 sun4v_dtsb_miss:
 	mov	SCRATCHPAD_UTSBREG1, %g1
@@ -168,6 +171,8 @@
 	brz,pn	%g5, kvmap_dtlb_4v
 	 mov	FAULT_CODE_DTLB, %g3
 
+	/* fallthrough */
+
 	/* Create TSB pointer into %g1.  This is something like:
 	 *
 	 * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
@@ -304,19 +309,30 @@
 
 	/* Memory Address Unaligned.  */
 sun4v_mna:
-	ldxa	[%g0] ASI_SCRATCHPAD, %g2
+	/* Window fixup? */
+	rdpr	%tl, %g2
+	cmp	%g2, 1
+	ble,pt	%icc, 1f
+	 nop
+
+	SET_GL(1)
+	ldxa	[%g0] ASI_SCRATCHPAD, %g5
+	ldx	[%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
+	mov	HV_FAULT_TYPE_UNALIGNED, %g3
+	ldx	[%g5 + HV_FAULT_D_CTX_OFFSET], %g4
+	sllx	%g3, 16, %g3
+	or	%g4, %g3, %g4
+	ba,pt	%xcc, winfix_mna
+	 rdpr	%tpc, %g3
+	/* not reached */
+
+1:	ldxa	[%g0] ASI_SCRATCHPAD, %g2
 	mov	HV_FAULT_TYPE_UNALIGNED, %g3
 	ldx	[%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 	ldx	[%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 	sllx	%g3, 16, %g3
 	or	%g5, %g3, %g5
 
-	/* Window fixup? */
-	rdpr	%tl, %g2
-	cmp	%g2, 1
-	bgu,pn	%icc, winfix_mna
-	 rdpr	%tpc, %g3
-
 	ba,pt	%xcc, etrap
 	 rd	%pc, %g7
 	mov	%l4, %o1
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index 1613713..c4aa110 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -115,16 +115,17 @@
 	ba,pt	%xcc, etrap
 	 rd	%pc, %g7
 	sethi	%hi(tlb_type), %g1
-	mov	%l4, %o1
 	lduw	[%g1 + %lo(tlb_type)], %g1
-	mov	%l5, %o2
 	cmp	%g1, 3
 	bne,pt	%icc, 1f
 	 add	%sp, PTREGS_OFF, %o0
+	mov	%l4, %o2
 	call	sun4v_do_mna
-	 nop
+	 mov	%l5, %o1
 	ba,a,pt	%xcc, rtrap_clr_l6
-1:	call	mem_address_unaligned
+1:	mov	%l4, %o1
+	mov	%l5, %o2
+	call	mem_address_unaligned
 	 nop
 	ba,a,pt	%xcc, rtrap_clr_l6