The alpha part contains code in the kernel to handle unaligned memory accesses from userland programs, to prevent them from dying in horrible SIGBUS.
This made sense in the '90s, but since then people have learned to work with strict-alignment architectures, and this code has been less and less triggered - in my own experience I don't remember seeing it triggered in the last 20 years. I think it's time to send it to the Attic for a well-deserved retirement, and let these ill-behaved userland programs catch the SIGBUS they deserve. Index: etc/etc.alpha/sysctl.conf =================================================================== RCS file: /OpenBSD/src/etc/etc.alpha/sysctl.conf,v retrieving revision 1.8 diff -u -p -r1.8 sysctl.conf --- etc/etc.alpha/sysctl.conf 2 Mar 2013 22:53:10 -0000 1.8 +++ etc/etc.alpha/sysctl.conf 9 Aug 2022 06:16:34 -0000 @@ -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 Index: sys/arch/alpha/alpha/machdep.c =================================================================== RCS file: /OpenBSD/src/sys/arch/alpha/alpha/machdep.c,v retrieving revision 1.196 diff -u -p -r1.196 machdep.c --- sys/arch/alpha/alpha/machdep.c 6 Oct 2021 15:46:03 -0000 1.196 +++ sys/arch/alpha/alpha/machdep.c 9 Aug 2022 06:16:34 -0000 @@ -180,9 +180,6 @@ u_int8_t dec_3000_scsiid[2], dec_3000_sc 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, voi 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)); Index: sys/arch/alpha/alpha/trap.c =================================================================== RCS file: /OpenBSD/src/sys/arch/alpha/alpha/trap.c,v retrieving revision 1.100 diff -u -p -r1.100 trap.c --- sys/arch/alpha/alpha/trap.c 9 Dec 2021 00:26:11 -0000 1.100 +++ sys/arch/alpha/alpha/trap.c 9 Aug 2022 06:16:35 -0000 @@ -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); } Index: sys/arch/alpha/include/cpu.h =================================================================== RCS file: /OpenBSD/src/sys/arch/alpha/include/cpu.h,v retrieving revision 1.65 diff -u -p -r1.65 cpu.h --- sys/arch/alpha/include/cpu.h 6 Jul 2021 09:34:06 -0000 1.65 +++ sys/arch/alpha/include/cpu.h 9 Aug 2022 06:16:35 -0000 @@ -113,7 +113,6 @@ extern u_long cpu_implver; /* from IMPL 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 }, \