sh: cleanup of do_address_error()

This patch fixes a few problems with the existing code in do_address_error().

a) the variable used to printk()d the offending instruction wasn't
   initialized correctly. This is a fix to bug 5727

b) behaviour for CONFIG_CPU_SH2A wasn't correct

c) the 'ignore address error' behaviour didn't update the PC, causing an
   infinite loop.

Signed-off-by: Andre Draszik <andre.draszik@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 0ad356d..c581dc3 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -621,12 +621,21 @@
 
 		se_user += 1;
 
+#ifndef CONFIG_CPU_SH2A
+		set_fs(USER_DS);
+		if (copy_from_user(&instruction, (u16 *)(regs->pc & ~1), 2)) {
+			set_fs(oldfs);
+			goto uspace_segv;
+		}
+		set_fs(oldfs);
+
 		/* shout about userspace fixups */
 		if (se_usermode & 1)
 			printk(KERN_NOTICE "Unaligned userspace access "
 			       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
 			       current->comm, current->pid, (void *)regs->pc,
 			       instruction);
+#endif
 
 		if (se_usermode & 2)
 			goto fixup;
@@ -635,7 +644,7 @@
 			goto uspace_segv;
 		else {
 			/* ignore */
-			trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
+			regs->pc += instruction_size(instruction);
 			return;
 		}
 
@@ -647,15 +656,6 @@
 		}
 
 		set_fs(USER_DS);
-		if (copy_from_user(&instruction, (void __user *)(regs->pc),
-				   sizeof(instruction))) {
-			/* Argh. Fault on the instruction itself.
-			   This should never happen non-SMP
-			*/
-			set_fs(oldfs);
-			goto uspace_segv;
-		}
-
 		tmp = handle_unaligned_access(instruction, regs,
 					      &user_mem_access);
 		set_fs(oldfs);