diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-11-27 19:41:49 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-11-27 19:41:49 +0000 |
commit | 5e5b8791118667f1de14d12971ebf359c1488cec (patch) | |
tree | 8ef8fc332086d1d57b516461cec92512db09c7f1 /sys/arch | |
parent | fe2d826627bc16fcdd5d11e7b1533270cd4bb587 (diff) |
Misaligned load/store recovery code in the kernel, enabled by T_FIXALIGN
userland traps on a per-process basis, were necessary for *some* SunOS
binaries on sparc, which had to compiled with explicit misaligned access code
generation (i.e. for vendors to release a working SunOS/sparc version of their
code until they could fix their bogus code).
There is no reason to keep this code on sparc64, and now that we don't provide
COMPAT_SUNOS anymore, there is no reason to keep this code on sparc.
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sparc/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/sparc/include/proc.h | 6 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/emul.c | 166 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/trap.c | 12 | ||||
-rw-r--r-- | sys/arch/sparc64/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/sparc64/include/proc.h | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/emul.c | 174 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/trap.c | 14 |
10 files changed, 15 insertions, 377 deletions
diff --git a/sys/arch/sparc/include/cpu.h b/sys/arch/sparc/include/cpu.h index 2f68e5bb6aa..acc93fbe407 100644 --- a/sys/arch/sparc/include/cpu.h +++ b/sys/arch/sparc/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.32 2009/04/10 20:53:54 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.33 2010/11/27 19:41:45 miod Exp $ */ /* $NetBSD: cpu.h,v 1.24 1997/03/15 22:25:15 pk Exp $ */ /* @@ -180,7 +180,6 @@ void iommu_enter(u_int, u_int); void iommu_remove(u_int, u_int); /* emul.c */ struct trapframe; -int fixalign(struct proc *, struct trapframe *); int emulinstr(int, struct trapframe *); /* diff --git a/sys/arch/sparc/include/proc.h b/sys/arch/sparc/include/proc.h index 68217bc4bf2..419d945ac75 100644 --- a/sys/arch/sparc/include/proc.h +++ b/sys/arch/sparc/include/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.3 2003/06/02 23:27:54 millert Exp $ */ +/* $OpenBSD: proc.h,v 1.4 2010/11/27 19:41:45 miod Exp $ */ /* $NetBSD: proc.h,v 1.3 1996/09/26 18:51:17 christos Exp $ */ /* @@ -47,8 +47,4 @@ struct mdproc { struct trapframe *md_tf; /* trap/syscall registers */ struct fpstate *md_fpstate; /* fpu state, if any; always resident */ - u_long md_flags; }; - -/* md_flags */ -#define MDP_FIXALIGN 0x1 /* Fix unaligned memory accesses */ diff --git a/sys/arch/sparc/sparc/emul.c b/sys/arch/sparc/sparc/emul.c index e41a676eedf..75a281937ba 100644 --- a/sys/arch/sparc/sparc/emul.c +++ b/sys/arch/sparc/sparc/emul.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emul.c,v 1.4 2010/09/05 18:08:52 kettenis Exp $ */ +/* $OpenBSD: emul.c,v 1.5 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: emul.c,v 1.3 1997/07/29 09:42:01 fair Exp $ */ /* @@ -222,170 +222,6 @@ muldiv(tf, code, rd, rs1, rs2) } /* - * Code to handle alignment faults on the sparc. This is enabled by sending - * a fixalign trap. Such code is generated by compiling with cc -misalign - * on SunOS, but we don't have such a feature yet on our gcc. - */ - -int -fixalign(p, tf) - struct proc *p; - struct trapframe *tf; -{ - static u_char sizedef[] = { 0x4, 0xff, 0x2, 0x8 }; - - /* - * This is particular to load and store instructions - */ - union { - struct { - unsigned unused:26; /* 26 padding */ - unsigned fl:1; /* 1 bit float flag */ - unsigned op:1; /* 1 bit opcode */ - unsigned sgn:1; /* 1 bit sign */ - unsigned st:1; /* 1 bit load/store */ - unsigned sz:2; /* 2 bit size register */ - } bits; - int num; - } op; - - union { - double d; - int32_t i[2]; - int16_t s[4]; - int8_t c[8]; - } data; - - union instr code; - size_t size; - int32_t rs1, rs2; - int error; - - /* fetch and check the instruction that caused the fault */ - error = copyin((caddr_t) tf->tf_pc, &code.i_int, sizeof(code.i_int)); - if (error != 0) { - DPRINTF(("fixalign: Bad instruction fetch\n")); - return EINVAL; - } - - /* Only support format 3 */ - if (code.i_any.i_op != 3) { - DPRINTF(("fixalign: Not a load or store\n")); - return EINVAL; - } - - op.num = code.i_loadstore.i_op3; - - /* Check operand size */ - if ((size = sizedef[op.bits.sz]) == 0xff) { - DPRINTF(("fixalign: Bad operand size\n")); - return EINVAL; - } - - write_user_windows(); - - if ((error = readgpreg(tf, code.i_op3.i_rs1, &rs1)) != 0) { - DPRINTF(("emulinstr: read rs1 %d\n", error)); - return error; - } - - if ((error = decodeaddr(tf, &code, &rs2)) != 0) { - DPRINTF(("emulinstr: decode addr %d\n", error)); - return error; - } - - - rs1 += rs2; - -#ifdef DEBUG_EMUL - uprintf("memalign 0x%x: %s%c%c %c%d, %c%d, ", code.i_int, - op.bits.st ? "st" : "ld", "us"[op.bits.sgn], - "w*hd"[op.bits.sz], op.bits.fl ? 'f' : REGNAME(code.i_op3.i_rd), - REGNAME(code.i_op3.i_rs1)); - if (code.i_loadstore.i_i) - uprintf("0x%x\n", rs2); - else - uprintf("%c%d\n", REGNAME(code.i_asi.i_rs2)); -#endif -#ifdef DIAGNOSTIC - if (op.bits.fl && p != cpuinfo.fpproc) - panic("fp align without being the FP owning process"); -#endif - - if (op.bits.st) { - if (op.bits.fl) { - savefpstate(p->p_md.md_fpstate); - - error = readfpreg(p, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = readfpreg(p, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - } - else { - error = readgpreg(tf, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = readgpreg(tf, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - } - - if (size == 2) - return copyout(&data.s[1], (caddr_t) rs1, size); - else - return copyout(&data.d, (caddr_t) rs1, size); - } - else { /* load */ - if (size == 2) { - error = copyin((caddr_t) rs1, &data.s[1], size); - if (error) - return error; - - /* Sign extend if necessary */ - if (op.bits.sgn && (data.s[1] & 0x8000) != 0) - data.s[0] = ~0; - else - data.s[0] = 0; - } - else - error = copyin((caddr_t) rs1, &data.d, size); - - if (error) - return error; - - if (op.bits.fl) { - error = writefpreg(p, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = writefpreg(p, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - loadfpstate(p->p_md.md_fpstate); - } - else { - error = writegpreg(tf, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) - error = writegpreg(tf, code.i_op3.i_rd + 1, - &data.i[1]); - } - } - return error; -} - -/* * Emulate unimplemented instructions on earlier sparc chips. */ int diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index dd9e3421c42..5b0239fa0cf 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.130 2010/07/02 19:57:15 tedu Exp $ */ +/* $OpenBSD: machdep.c,v 1.131 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */ /* @@ -264,9 +264,6 @@ setregs(p, pack, stack, retval) break; } - /* Don't allow misaligned code by default */ - p->p_md.md_flags &= ~MDP_FIXALIGN; - /* * The syscall will ``return'' to npc or %g7 or %g2; set them all. * Set the rest of the registers to 0 except for %o6 (stack pointer, diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c index 71e425a0944..cf558026188 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.54 2010/07/10 19:32:25 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.55 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: trap.c,v 1.58 1997/09/12 08:55:01 pk Exp $ */ /* @@ -461,11 +461,6 @@ badtrap: break; case T_ALIGN: - if ((p->p_md.md_flags & MDP_FIXALIGN) != 0 && - fixalign(p, tf) == 0) { - ADVANCE; - break; - } trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); break; @@ -530,12 +525,9 @@ badtrap: break; case T_FIXALIGN: -#ifdef DEBUG_ALIGN uprintf("T_FIXALIGN\n"); -#endif - /* User wants us to fix alignment faults */ - p->p_md.md_flags |= MDP_FIXALIGN; ADVANCE; + trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); break; case T_INTOF: diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h index dcee1819254..ce179324090 100644 --- a/sys/arch/sparc64/include/cpu.h +++ b/sys/arch/sparc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.73 2010/09/28 20:27:55 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.74 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */ /* @@ -288,7 +288,6 @@ void fb_unblank(void); /* tda.c */ void tda_full_blast(void); /* emul.c */ -int fixalign(struct proc *, struct trapframe64 *); int emulinstr(vaddr_t, struct trapframe64 *); int emul_qf(int32_t, struct proc *, union sigval, struct trapframe64 *); int emul_popc(int32_t, struct proc *, union sigval, struct trapframe64 *); diff --git a/sys/arch/sparc64/include/proc.h b/sys/arch/sparc64/include/proc.h index 84d8a86f7ac..0559c74bcc9 100644 --- a/sys/arch/sparc64/include/proc.h +++ b/sys/arch/sparc64/include/proc.h @@ -46,9 +46,5 @@ struct mdproc { struct trapframe64 *md_tf; /* trap/syscall registers */ struct fpstate64 *md_fpstate; /* fpu state, if any; always resident */ - u_long md_flags; __volatile int md_astpending; }; - -/* md_flags */ -#define MDP_FIXALIGN 0x1 /* Fix unaligned memory accesses */ diff --git a/sys/arch/sparc64/sparc64/emul.c b/sys/arch/sparc64/sparc64/emul.c index 33437668251..9fbdb976ce5 100644 --- a/sys/arch/sparc64/sparc64/emul.c +++ b/sys/arch/sparc64/sparc64/emul.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emul.c,v 1.18 2010/04/11 13:12:16 kettenis Exp $ */ +/* $OpenBSD: emul.c,v 1.19 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: emul.c,v 1.8 2001/06/29 23:58:40 eeh Exp $ */ /*- @@ -225,171 +225,6 @@ muldiv(tf, code, rd, rs1, rs2) } /* - * Code to handle alignment faults on the sparc. This is enabled by sending - * a fixalign trap. Such code is generated by compiling with cc -misalign - * on SunOS, but we don't have such a feature yet on our gcc. - */ - -int -fixalign(p, tf) - struct proc *p; - struct trapframe64 *tf; -{ - static u_char sizedef[] = { 0x4, 0xff, 0x2, 0x8 }; - - /* - * This is particular to load and store instructions - */ - union { - struct { - unsigned unused:26; /* 26 padding */ - unsigned fl:1; /* 1 bit float flag */ - unsigned op:1; /* 1 bit opcode */ - unsigned sgn:1; /* 1 bit sign */ - unsigned st:1; /* 1 bit load/store */ - unsigned sz:2; /* 2 bit size register */ - } bits; - int num; - } op; - - union { - double d; - int32_t i[2]; - int16_t s[4]; - int8_t c[8]; - } data; - - union instr code; - size_t size; - int64_t rs1, rs2; - int error; - - /* fetch and check the instruction that caused the fault */ - error = copyin((caddr_t)(u_long)tf->tf_pc, &code.i_int, sizeof(code.i_int)); - if (error != 0) { - DPRINTF(("fixalign: Bad instruction fetch\n")); - return EINVAL; - } - - /* Only support format 3 */ - if (code.i_any.i_op != 3) { - DPRINTF(("fixalign: Not a load or store\n")); - return EINVAL; - } - - op.num = code.i_loadstore.i_op3; - - /* Check operand size */ - if ((size = sizedef[op.bits.sz]) == 0xff) { - DPRINTF(("fixalign: Bad operand size\n")); - return EINVAL; - } - - write_user_windows(); - - if ((error = readgpreg(tf, code.i_op3.i_rs1, &rs1)) != 0) { - DPRINTF(("fixalign: read rs1 %d\n", error)); - return error; - } - - if ((error = decodeaddr(tf, &code, &rs2)) != 0) { - DPRINTF(("fixalign: decode addr %d\n", error)); - return error; - } - - - rs1 += rs2; - -#ifdef DEBUG_EMUL - printf("memalign 0x%x: %s%c%c %c%d, %c%d, ", code.i_int, - op.bits.st ? "st" : "ld", "us"[op.bits.sgn], - "w*hd"[op.bits.sz], op.bits.fl ? 'f' : REGNAME(code.i_op3.i_rd), - REGNAME(code.i_op3.i_rs1)); - if (code.i_loadstore.i_i) - printf("0x%llx\n", (unsigned long long)rs2); - else - printf("%c%d\n", REGNAME(code.i_asi.i_rs2)); -#endif -#ifdef DIAGNOSTIC - if (op.bits.fl && p != fpproc) - panic("fp align without being the FP owning process"); -#endif - - if (op.bits.st) { - if (op.bits.fl) { - fpusave_proc(p, 1); - - error = readfpreg(p, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = readfpreg(p, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - } - else { - error = readgpreg(tf, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = readgpreg(tf, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - } - - if (size == 2) - return copyout(&data.s[1], (caddr_t)(u_long)rs1, size); - else - return copyout(&data.d, (caddr_t)(u_long)rs1, size); - } - else { /* load */ - if (size == 2) { - error = copyin((caddr_t)(u_long)rs1, &data.s[1], size); - if (error) - return error; - - /* Sign extend if necessary */ - if (op.bits.sgn && (data.s[1] & 0x8000) != 0) - data.s[0] = ~0; - else - data.s[0] = 0; - } - else - error = copyin((caddr_t)(u_long)rs1, &data.d, size); - - if (error) - return error; - - if (op.bits.fl) { - error = writefpreg(p, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) { - error = writefpreg(p, code.i_op3.i_rd + 1, - &data.i[1]); - if (error) - return error; - } - loadfpstate(p->p_md.md_fpstate); - fpproc = p; - } - else { - error = writegpreg(tf, code.i_op3.i_rd, &data.i[0]); - if (error) - return error; - if (size == 8) - error = writegpreg(tf, code.i_op3.i_rd + 1, - &data.i[1]); - } - } - return error; -} - -/* * Emulate unimplemented instructions on earlier sparc chips. */ int @@ -517,11 +352,8 @@ emul_qf(int32_t insv, struct proc *p, union sigval sv, struct trapframe *tf) return (0); } - if ((p->p_md.md_flags & MDP_FIXALIGN) == 0 && (addr & 3) != 0) { - /* - * If process doesn't want us to fix alignment and the - * request isn't aligned, kill it. - */ + if ((addr & 3) != 0) { + /* request is not aligned */ KERNEL_PROC_LOCK(p); trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); KERNEL_PROC_UNLOCK(p); diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index 96d03b8e255..04b8206257c 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.125 2010/11/20 20:33:24 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.126 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -307,9 +307,6 @@ setregs(p, pack, stack, retval) break; } - /* Don't allow misaligned code by default */ - p->p_md.md_flags &= ~MDP_FIXALIGN; - /* * Set the registers to 0 except for: * %o6: stack pointer, built in exec()) diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c index 873c9ea0e5e..05159280724 100644 --- a/sys/arch/sparc64/sparc64/trap.c +++ b/sys/arch/sparc64/sparc64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.65 2010/08/07 00:13:09 krw Exp $ */ +/* $OpenBSD: trap.c,v 1.66 2010/11/27 19:41:48 miod Exp $ */ /* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */ /* @@ -673,11 +673,6 @@ badtrap: break; } - if ((p->p_md.md_flags & MDP_FIXALIGN) != 0 && - fixalign(p, tf) == 0) { - ADVANCE; - break; - } /* XXX sv.sival_ptr should be the fault address! */ KERNEL_PROC_LOCK(p); trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); /* XXX code? */ @@ -753,12 +748,11 @@ badtrap: break; case T_FIXALIGN: -#ifdef DEBUG_ALIGN uprintf("T_FIXALIGN\n"); -#endif - /* User wants us to fix alignment faults */ - p->p_md.md_flags |= MDP_FIXALIGN; ADVANCE; + KERNEL_PROC_LOCK(p); + trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv); /* XXX code? */ + KERNEL_PROC_UNLOCK(p); break; case T_INTOF: |