patch-2.1.23 linux/arch/sparc/kernel/unaligned.c
Next file: linux/arch/sparc/kernel/windows.c
Previous file: linux/arch/sparc/kernel/traps.c
Back to the patch index
Back to the overall index
- Lines: 77
- Date:
Sun Jan 26 12:07:09 1997
- Orig file:
v2.1.22/linux/arch/sparc/kernel/unaligned.c
- Orig date:
Wed Jan 15 19:45:41 1997
diff -u --recursive --new-file v2.1.22/linux/arch/sparc/kernel/unaligned.c linux/arch/sparc/kernel/unaligned.c
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.13 1996/11/26 14:01:57 jj Exp $
+/* $Id: unaligned.c,v 1.15 1997/01/16 14:14:42 davem Exp $
* unaligned.c: Unaligned load/store trap handling with special
* cases for the kernel to do them more quickly.
*
@@ -14,6 +14,8 @@
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
/* #define DEBUG_MNA */
@@ -206,7 +208,7 @@
: : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \
: "l1", "l2", "g7", "g1"); \
})
-
+
#define store_common(dst_addr, size, src_val, errh) ({ \
__asm__ __volatile__ ( \
"ld [%2], %%l1\n" \
@@ -332,6 +334,7 @@
enum direction dir = decode_direction(insn);
int size = decode_access_size(insn);
+ lock_kernel();
if(!ok_for_kernel(insn) || dir == both) {
printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
regs->pc);
@@ -344,8 +347,6 @@
" mov %1, %%o1\n\t"
: : "r" (regs), "r" (insn)
: "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7");
-
- return;
} else {
unsigned long addr = compute_effective_address(regs, insn);
@@ -379,6 +380,7 @@
}
advance(regs);
}
+ unlock_kernel();
}
static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
@@ -431,6 +433,7 @@
{
enum direction dir;
+ lock_kernel();
if(!(current->tss.flags & SPARC_FLAG_UNALIGNED) ||
(((insn >> 30) & 3) != 3))
goto kill_user;
@@ -477,15 +480,16 @@
" mov %1, %%o1\n\t"
: : "r" (regs), "r" (insn)
: "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7");
-
- return;
+ goto out;
}
advance(regs);
- return;
+ goto out;
}
kill_user:
current->tss.sig_address = regs->pc;
current->tss.sig_desc = SUBSIG_PRIVINST;
send_sig(SIGBUS, current, 1);
+out:
+ unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov