There have to be some strict-aligned architectures which don't emulate
unaligned access, because there will always be architectures which have
a high emulation cost, and I'm ok with alpha joining that group.


Miod Vallat <m...@online.fr> wrote:

> 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 }, \
> 

Reply via email to