summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2022-08-10 10:41:36 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2022-08-10 10:41:36 +0000
commit870f046a4e02f78cafdbbfc227da7986a63385dd (patch)
tree994559bec872855a4700a4fd10179fa91d8c7871
parent0b54e3b6d3aa558f8dfc9772cc1a948939a92f43 (diff)
Remove alpha kernel code to process userland misaligned accesses, and the
machdep.unaligned_* sysctl to control its behaviour. Such code made sense more than 20 years ago where a lot of code was not 64-bit clean, but this is no longer the case those days. ok jsg@ millert@ deraadt@
-rw-r--r--etc/etc.alpha/sysctl.conf3
-rw-r--r--sys/arch/alpha/alpha/machdep.c17
-rw-r--r--sys/arch/alpha/alpha/trap.c403
-rw-r--r--sys/arch/alpha/include/cpu.h12
4 files changed, 12 insertions, 423 deletions
diff --git a/etc/etc.alpha/sysctl.conf b/etc/etc.alpha/sysctl.conf
index 8174e5b77d5..f506f4546d8 100644
--- a/etc/etc.alpha/sysctl.conf
+++ b/etc/etc.alpha/sysctl.conf
@@ -1,5 +1,2 @@
-#machdep.unaligned_print=0 # 0 - disable printing of unaligned access
-#machdep.unaligned_fix=0 # 0 - disable fixup of unaligned access
-#machdep.unaligned_sigbus=0 # 0 - don't sigbus on unaligned access
#machdep.allowaperture=1 # see xf86(4)
#machdep.led_blink=1 # blink chassis leds on DEC 3000
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index d99e388c375..f4687ad2349 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.197 2022/08/10 03:18:19 jsg Exp $ */
+/* $OpenBSD: machdep.c,v 1.198 2022/08/10 10:41:35 miod Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -180,9 +180,6 @@ u_int8_t dec_3000_scsiid[2], dec_3000_scsifast[2];
struct platform platform;
/* for cpu_sysctl() */
-int alpha_unaligned_print = 1; /* warn about unaligned accesses */
-int alpha_unaligned_fix = 1; /* fix up unaligned accesses */
-int alpha_unaligned_sigbus = 1; /* SIGBUS on fixed-up accesses */
#ifndef NO_IEEE
int alpha_fp_sync_complete = 0; /* fp fixup if sync even without /s */
#endif
@@ -1555,18 +1552,6 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
sizeof consdev));
#ifndef SMALL_KERNEL
- case CPU_UNALIGNED_PRINT:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &alpha_unaligned_print));
-
- case CPU_UNALIGNED_FIX:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &alpha_unaligned_fix));
-
- case CPU_UNALIGNED_SIGBUS:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &alpha_unaligned_sigbus));
-
case CPU_BOOTED_KERNEL:
return (sysctl_rdstring(oldp, oldlenp, newp,
bootinfo.booted_kernel));
diff --git a/sys/arch/alpha/alpha/trap.c b/sys/arch/alpha/alpha/trap.c
index f5a8ca8f70c..0915657ccf5 100644
--- a/sys/arch/alpha/alpha/trap.c
+++ b/sys/arch/alpha/alpha/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.100 2021/12/09 00:26:11 guenther Exp $ */
+/* $OpenBSD: trap.c,v 1.101 2022/08/10 10:41:35 miod Exp $ */
/* $NetBSD: trap.c,v 1.52 2000/05/24 16:48:33 thorpej Exp $ */
/*-
@@ -110,21 +110,6 @@
#endif
#include <alpha/alpha/db_instruction.h>
-#ifndef SMALL_KERNEL
-
-unsigned long Sfloat_to_reg(unsigned int);
-unsigned int reg_to_Sfloat(unsigned long);
-unsigned long Tfloat_reg_cvt(unsigned long);
-#ifdef FIX_UNALIGNED_VAX_FP
-unsigned long Ffloat_to_reg(unsigned int);
-unsigned int reg_to_Ffloat(unsigned long);
-unsigned long Gfloat_reg_cvt(unsigned long);
-#endif
-
-int unaligned_fixup(unsigned long, unsigned long,
- unsigned long, struct proc *);
-#endif /* SMALL_KERNEL */
-
int handle_opdec(struct proc *p, u_int64_t *ucodep);
#ifndef NO_IEEE
@@ -249,19 +234,10 @@ trap(a0, a1, a2, entry, framep)
switch (entry) {
case ALPHA_KENTRY_UNA:
/*
- * If user-land, do whatever fixups, printing, and
- * signalling is appropriate (based on system-wide
- * and per-process unaligned-access-handling flags).
+ * If user-land, deliver SIGBUS unconditionally.
*/
if (user) {
-#ifndef SMALL_KERNEL
- KERNEL_LOCK();
- i = unaligned_fixup(a0, a1, a2, p);
- KERNEL_UNLOCK();
- if (i == 0)
- goto out;
-#endif
-
+ i = SIGBUS;
ucode = ILL_ILLADR;
v = (caddr_t)a0;
break;
@@ -716,11 +692,6 @@ ast(framep)
userret(p);
}
-/*
- * Unaligned access handler. It's not clear that this can get much slower...
- *
- */
-
const static int reg_to_framereg[32] = {
FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2,
FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6,
@@ -736,356 +707,6 @@ const static int reg_to_framereg[32] = {
((reg_to_framereg[(reg)] == -1) ? NULL : \
&(p)->p_md.md_tf->tf_regs[reg_to_framereg[(reg)]])
-#ifndef SMALL_KERNEL
-
-#define frp(p, reg) \
- (&(p)->p_addr->u_pcb.pcb_fp.fpr_regs[(reg)])
-
-#define dump_fp_regs() \
- if (p->p_addr->u_pcb.pcb_fpcpu != NULL) \
- fpusave_proc(p, 1);
-
-#define unaligned_load(storage, ptrf, mod) \
- if (copyin((caddr_t)va, &(storage), sizeof (storage)) != 0) { \
- p->p_md.md_tf->tf_regs[FRAME_PC] -= 4; \
- signal = SIGSEGV; \
- goto out; \
- } \
- signal = 0; \
- if ((regptr = ptrf(p, reg)) != NULL) \
- *regptr = mod (storage);
-
-#define unaligned_store(storage, ptrf, mod) \
- if ((regptr = ptrf(p, reg)) != NULL) \
- (storage) = mod (*regptr); \
- else \
- (storage) = 0; \
- if (copyout(&(storage), (caddr_t)va, sizeof (storage)) != 0) { \
- p->p_md.md_tf->tf_regs[FRAME_PC] -= 4; \
- signal = SIGSEGV; \
- goto out; \
- } \
- signal = 0;
-
-#define unaligned_load_integer(storage) \
- unaligned_load(storage, irp, )
-
-#define unaligned_store_integer(storage) \
- unaligned_store(storage, irp, )
-
-#define unaligned_load_floating(storage, mod) \
- dump_fp_regs(); \
- unaligned_load(storage, frp, mod)
-
-#define unaligned_store_floating(storage, mod) \
- dump_fp_regs(); \
- unaligned_store(storage, frp, mod)
-
-unsigned long
-Sfloat_to_reg(s)
- unsigned int s;
-{
- unsigned long sign, expn, frac;
- unsigned long result;
-
- sign = (s & 0x80000000) >> 31;
- expn = (s & 0x7f800000) >> 23;
- frac = (s & 0x007fffff) >> 0;
-
- /* map exponent part, as appropriate. */
- if (expn == 0xff)
- expn = 0x7ff;
- else if ((expn & 0x80) != 0)
- expn = (0x400 | (expn & ~0x80));
- else if ((expn & 0x80) == 0 && expn != 0)
- expn = (0x380 | (expn & ~0x80));
-
- result = (sign << 63) | (expn << 52) | (frac << 29);
- return (result);
-}
-
-unsigned int
-reg_to_Sfloat(r)
- unsigned long r;
-{
- unsigned long sign, expn, frac;
- unsigned int result;
-
- sign = (r & 0x8000000000000000) >> 63;
- expn = (r & 0x7ff0000000000000) >> 52;
- frac = (r & 0x000fffffe0000000) >> 29;
-
- /* map exponent part, as appropriate. */
- expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
-
- result = (sign << 31) | (expn << 23) | (frac << 0);
- return (result);
-}
-
-/*
- * Conversion of T floating datums to and from register format
- * requires no bit reordering whatsoever.
- */
-unsigned long
-Tfloat_reg_cvt(input)
- unsigned long input;
-{
-
- return (input);
-}
-
-#ifdef FIX_UNALIGNED_VAX_FP
-unsigned long
-Ffloat_to_reg(f)
- unsigned int f;
-{
- unsigned long sign, expn, frlo, frhi;
- unsigned long result;
-
- sign = (f & 0x00008000) >> 15;
- expn = (f & 0x00007f80) >> 7;
- frhi = (f & 0x0000007f) >> 0;
- frlo = (f & 0xffff0000) >> 16;
-
- /* map exponent part, as appropriate. */
- if ((expn & 0x80) != 0)
- expn = (0x400 | (expn & ~0x80));
- else if ((expn & 0x80) == 0 && expn != 0)
- expn = (0x380 | (expn & ~0x80));
-
- result = (sign << 63) | (expn << 52) | (frhi << 45) | (frlo << 29);
- return (result);
-}
-
-unsigned int
-reg_to_Ffloat(r)
- unsigned long r;
-{
- unsigned long sign, expn, frhi, frlo;
- unsigned int result;
-
- sign = (r & 0x8000000000000000) >> 63;
- expn = (r & 0x7ff0000000000000) >> 52;
- frhi = (r & 0x000fe00000000000) >> 45;
- frlo = (r & 0x00001fffe0000000) >> 29;
-
- /* map exponent part, as appropriate. */
- expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
-
- result = (sign << 15) | (expn << 7) | (frhi << 0) | (frlo << 16);
- return (result);
-}
-
-/*
- * Conversion of G floating datums to and from register format is
- * symmetrical. Just swap shorts in the quad...
- */
-unsigned long
-Gfloat_reg_cvt(input)
- unsigned long input;
-{
- unsigned long a, b, c, d;
- unsigned long result;
-
- a = (input & 0x000000000000ffff) >> 0;
- b = (input & 0x00000000ffff0000) >> 16;
- c = (input & 0x0000ffff00000000) >> 32;
- d = (input & 0xffff000000000000) >> 48;
-
- result = (a << 48) | (b << 32) | (c << 16) | (d << 0);
- return (result);
-}
-#endif /* FIX_UNALIGNED_VAX_FP */
-
-struct unaligned_fixup_data {
- const char *type; /* opcode name */
- int fixable; /* fixable, 0 if fixup not supported */
- int size; /* size, 0 if unknown */
-};
-
-#define UNKNOWN() { "0x%lx", 0, 0 }
-#define FIX_LD(n,s) { n, 1, s }
-#define FIX_ST(n,s) { n, 1, s }
-#define NOFIX_LD(n,s) { n, 0, s }
-#define NOFIX_ST(n,s) { n, 0, s }
-
-int
-unaligned_fixup(va, opcode, reg, p)
- unsigned long va, opcode, reg;
- struct proc *p;
-{
- const struct unaligned_fixup_data tab_unknown[1] = {
- UNKNOWN(),
- };
- const struct unaligned_fixup_data tab_0c[0x02] = {
- FIX_LD("ldwu", 2), FIX_ST("stw", 2),
- };
- const struct unaligned_fixup_data tab_20[0x10] = {
-#ifdef FIX_UNALIGNED_VAX_FP
- FIX_LD("ldf", 4), FIX_LD("ldg", 8),
-#else
- NOFIX_LD("ldf", 4), NOFIX_LD("ldg", 8),
-#endif
- FIX_LD("lds", 4), FIX_LD("ldt", 8),
-#ifdef FIX_UNALIGNED_VAX_FP
- FIX_ST("stf", 4), FIX_ST("stg", 8),
-#else
- NOFIX_ST("stf", 4), NOFIX_ST("stg", 8),
-#endif
- FIX_ST("sts", 4), FIX_ST("stt", 8),
- FIX_LD("ldl", 4), FIX_LD("ldq", 8),
- NOFIX_LD("ldl_c", 4), NOFIX_LD("ldq_c", 8),
- FIX_ST("stl", 4), FIX_ST("stq", 8),
- NOFIX_ST("stl_c", 4), NOFIX_ST("stq_c", 8),
- };
- const struct unaligned_fixup_data *selected_tab;
- int doprint, dofix, dosigbus, signal;
- unsigned long *regptr, longdata;
- int intdata; /* signed to get extension when storing */
- u_int16_t worddata; /* unsigned to _avoid_ extension */
-
- /*
- * Read USP into frame in case it's the register to be modified.
- * This keeps us from having to check for it in lots of places
- * later.
- */
- p->p_md.md_tf->tf_regs[FRAME_SP] = alpha_pal_rdusp();
-
- /*
- * Figure out what actions to take.
- *
- * XXX In the future, this should have a per-process component
- * as well.
- */
- doprint = alpha_unaligned_print;
- dofix = alpha_unaligned_fix;
- dosigbus = alpha_unaligned_sigbus;
-
- /*
- * Find out which opcode it is. Arrange to have the opcode
- * printed if it's an unknown opcode.
- */
- if (opcode >= 0x0c && opcode <= 0x0d)
- selected_tab = &tab_0c[opcode - 0x0c];
- else if (opcode >= 0x20 && opcode <= 0x2f)
- selected_tab = &tab_20[opcode - 0x20];
- else
- selected_tab = tab_unknown;
-
- /*
- * If we're supposed to be noisy, squawk now.
- */
- if (doprint) {
- uprintf(
- "pid %u (%s): unaligned access: va=0x%lx pc=0x%lx ra=0x%lx op=",
- p->p_p->ps_pid, p->p_p->ps_comm, va,
- p->p_md.md_tf->tf_regs[FRAME_PC] - 4,
- p->p_md.md_tf->tf_regs[FRAME_RA]);
- uprintf(selected_tab->type,opcode);
- uprintf("\n");
- }
-
- /*
- * If we should try to fix it and know how, give it a shot.
- *
- * We never allow bad data to be unknowingly used by the
- * user process. That is, if we decide not to fix up an
- * access we cause a SIGBUS rather than letting the user
- * process go on without warning.
- *
- * If we're trying to do a fixup, we assume that things
- * will be botched. If everything works out OK,
- * unaligned_{load,store}_* clears the signal flag.
- */
- signal = SIGBUS;
- if (dofix && selected_tab->fixable) {
- switch (opcode) {
- case 0x0c: /* ldwu */
- /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
- unaligned_load_integer(worddata);
- break;
-
- case 0x0d: /* stw */
- /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */
- unaligned_store_integer(worddata);
- break;
-
-#ifdef FIX_UNALIGNED_VAX_FP
- case 0x20: /* ldf */
- unaligned_load_floating(intdata, Ffloat_to_reg);
- break;
-
- case 0x21: /* ldg */
- unaligned_load_floating(longdata, Gfloat_reg_cvt);
- break;
-#endif
-
- case 0x22: /* lds */
- unaligned_load_floating(intdata, Sfloat_to_reg);
- break;
-
- case 0x23: /* ldt */
- unaligned_load_floating(longdata, Tfloat_reg_cvt);
- break;
-
-#ifdef FIX_UNALIGNED_VAX_FP
- case 0x24: /* stf */
- unaligned_store_floating(intdata, reg_to_Ffloat);
- break;
-
- case 0x25: /* stg */
- unaligned_store_floating(longdata, Gfloat_reg_cvt);
- break;
-#endif
-
- case 0x26: /* sts */
- unaligned_store_floating(intdata, reg_to_Sfloat);
- break;
-
- case 0x27: /* stt */
- unaligned_store_floating(longdata, Tfloat_reg_cvt);
- break;
-
- case 0x28: /* ldl */
- unaligned_load_integer(intdata);
- break;
-
- case 0x29: /* ldq */
- unaligned_load_integer(longdata);
- break;
-
- case 0x2c: /* stl */
- unaligned_store_integer(intdata);
- break;
-
- case 0x2d: /* stq */
- unaligned_store_integer(longdata);
- break;
-
-#ifdef DIAGNOSTIC
- default:
- panic("unaligned_fixup: can't get here");
-#endif
- }
- }
-
- /*
- * Force SIGBUS if requested.
- */
- if (dosigbus)
- signal = SIGBUS;
-
-out:
- /*
- * Write back USP.
- */
- alpha_pal_wrusp(p->p_md.md_tf->tf_regs[FRAME_SP]);
-
- return (signal);
-}
-
-#endif /* SMALL_KERNEL */
-
/*
* Reserved/unimplemented instruction (opDec fault) handler
*
@@ -1141,17 +762,9 @@ handle_opdec(p, ucodep)
if (inst.mem_format.opcode == op_ldwu ||
inst.mem_format.opcode == op_stw) {
- if (memaddr & 0x01) {
-#ifndef SMALL_KERNEL
- sig = unaligned_fixup(memaddr,
- inst.mem_format.opcode,
- inst.mem_format.ra, p);
- if (sig)
- goto unaligned_fixup_sig;
-#else
- goto sigill;
-#endif
- break;
+ if (memaddr & 0x01) { /* misaligned address */
+ sig = SIGBUS;
+ goto sigbus;
}
}
@@ -1265,9 +878,7 @@ sigill:
sigsegv:
sig = SIGSEGV;
p->p_md.md_tf->tf_regs[FRAME_PC] = inst_pc; /* re-run instr. */
-#ifndef SMALL_KERNEL
-unaligned_fixup_sig:
-#endif
+sigbus:
*ucodep = memaddr; /* faulting address */
return (sig);
}
diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h
index be5b57cc593..00d7508613e 100644
--- a/sys/arch/alpha/include/cpu.h
+++ b/sys/arch/alpha/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.65 2021/07/06 09:34:06 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.66 2022/08/10 10:41:35 miod Exp $ */
/* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */
/*-
@@ -113,7 +113,6 @@ extern u_long cpu_implver; /* from IMPLVER instruction */
extern u_long cpu_amask; /* from AMASK instruction */
extern int bootdev_debug;
extern int alpha_fp_sync_complete;
-extern int alpha_unaligned_print, alpha_unaligned_fix, alpha_unaligned_sigbus;
void XentArith(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */
void XentIF(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */
@@ -358,9 +357,6 @@ do { \
* CTL_MACHDEP definitions.
*/
#define CPU_CONSDEV 1 /* dev_t: console terminal device */
-#define CPU_UNALIGNED_PRINT 3 /* int: print unaligned accesses */
-#define CPU_UNALIGNED_FIX 4 /* int: fix unaligned accesses */
-#define CPU_UNALIGNED_SIGBUS 5 /* int: SIGBUS unaligned accesses */
#define CPU_BOOTED_KERNEL 6 /* string: booted kernel name */
#define CPU_FP_SYNC_COMPLETE 7 /* int: always fixup sync fp traps */
#define CPU_CHIPSET 8 /* chipset information */
@@ -381,9 +377,9 @@ do { \
{ 0, 0 }, \
{ "console_device", CTLTYPE_STRUCT }, \
{ 0, 0 }, \
- { "unaligned_print", CTLTYPE_INT }, \
- { "unaligned_fix", CTLTYPE_INT }, \
- { "unaligned_sigbus", CTLTYPE_INT }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
{ "booted_kernel", CTLTYPE_STRING }, \
{ "fp_sync_complete", CTLTYPE_INT }, \
{ "chipset", CTLTYPE_NODE }, \