summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-11-27 19:41:49 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-11-27 19:41:49 +0000
commit5e5b8791118667f1de14d12971ebf359c1488cec (patch)
tree8ef8fc332086d1d57b516461cec92512db09c7f1 /sys/arch
parentfe2d826627bc16fcdd5d11e7b1533270cd4bb587 (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.h3
-rw-r--r--sys/arch/sparc/include/proc.h6
-rw-r--r--sys/arch/sparc/sparc/emul.c166
-rw-r--r--sys/arch/sparc/sparc/machdep.c5
-rw-r--r--sys/arch/sparc/sparc/trap.c12
-rw-r--r--sys/arch/sparc64/include/cpu.h3
-rw-r--r--sys/arch/sparc64/include/proc.h4
-rw-r--r--sys/arch/sparc64/sparc64/emul.c174
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c5
-rw-r--r--sys/arch/sparc64/sparc64/trap.c14
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: