Re: dc(4) related misalignment trap

From: John Baldwin <jhb_at_freebsd.org>
Date: Mon, 21 Nov 2005 09:49:10 -0500
On Saturday 19 November 2005 08:11 pm, Marcel Moolenaar wrote:
> All,
>
> On alpha this time:
>
>
> swapon: adding /dev/da0b as swap device
> Starting file system checks:
> /dev/da0a: 38800 files, 486252 used, 3308480 free (41816 frags,
> 408333 blocks, 1.1% fragmentation)
> Setting hostname: ds10.pn.xcllnt.net.
>
> fatal kernel trap:
>
>      trap entry     = 0x4 (unaligned access fault)
>      faulting va    = 0xfffffc000096b73b
>      opcode         = 0xc
>      register       = 0x1
>      pc             = 0xfffffc0000389cd8
>      ra             = 0xfffffc0000389c98
>      sp             = 0xfffffe001a581800
>      usp            = 0x11ffe4f8
>      curthread      = 0xfffffc003eb1d340
>          pid = 165, comm = ifconfig
>
> [thread pid 165 tid 100034 ]
> Stopped at      dc_setfilt_21143+0x368: stl     t0,0x9c(s3)
> <0xfffffc000095879c>
> <t0=0xfffffc000096b733,s3=0xfffffc0000958700>
> db> bt
> Tracing pid 165 tid 100034 td 0xfffffc003eb1d340
> dc_setfilt_21143() at dc_setfilt_21143+0x368
> dc_setfilt() at dc_setfilt+0x58
> dc_init_locked() at dc_init_locked+0x9c8
> dc_init() at dc_init+0x78
> ether_ioctl() at ether_ioctl+0xd8
> dc_ioctl() at dc_ioctl+0x370
> in6_ifinit() at in6_ifinit+0x11c
> in6_update_ifa() at in6_update_ifa+0x604
> in6_ifattach_linklocal() at in6_ifattach_linklocal+0x198
> in6_ifattach() at in6_ifattach+0x110
> in6_if_up() at in6_if_up+0xa8
> if_route() at if_route+0xa4
> if_up() at if_up+0x1c
> ifhwioctl() at ifhwioctl+0x3a8
> ifioctl() at ifioctl+0x178
> soo_ioctl() at soo_ioctl+0x6e4
> ioctl() at ioctl+0x6e8
> syscall() at syscall+0x458
> XentSys() at XentSys+0x64
> --- syscall (54, FreeBSD ELF64, ioctl) ---
>
>
> Note that the faulting instruction is really the instruction before
> the one shown. In kgdb:
>
> 0xfffffc0000389cd4 <dc_setfilt_21143+868>:      ldwu    t0,8(t0)
> 0xfffffc0000389cd8 <dc_setfilt_21143+872>:      stl     t0,156(s3)
>
> ldwu = load word unsigned.
>
>
> (kgdb) l *dc_setfilt_21143+0x368
> 0xfffffc0000389cd8 is in dc_setfilt_21143 (../../../dev/dc/if_dc.c:
> 1129).
> 1124                    h = dc_mchash_le(sc, ifp->if_broadcastaddr);
> 1125                    sp[h >> 4] |= htole32(1 << (h & 0xF));
> 1126            }
> 1127
> 1128            /* Set our MAC address */
> 1129            sp[39] = DC_SP_MAC(((u_int16_t *)IF_LLADDR(sc-
>
>  >dc_ifp))[0]);
>
> 1130            sp[40] = DC_SP_MAC(((u_int16_t *)IF_LLADDR(sc-
>
>  >dc_ifp))[1]);
>
> 1131            sp[41] = DC_SP_MAC(((u_int16_t *)IF_LLADDR(sc-
>
>  >dc_ifp))[2]);
>
> 1132
> 1133            sframe->dc_status = htole32(DC_TXSTAT_OWN);
>
> (kgdb) f 12
> #12 0xfffffc0000389cd8 in dc_setfilt_21143 (sc=0xfffffc0000842000)
> at ../../../dev/dc/if_dc.c:1129
> 1129            sp[39] = DC_SP_MAC(((u_int16_t *)IF_LLADDR(sc-
>
>  >dc_ifp))[0]);
>
> (kgdb) p sp
> $2 = (u_int32_t *) 0xfffffc0000958700
> (kgdb) p sc->dc_ifp->if_addr->ifa_addr
> $5 = (struct sockaddr *) 0xfffffc000096b730
> (kgdb) p *(struct sockaddr_dl *)$5
> $6 = {sdl_len = 56 '8', sdl_family = 18 '\022', sdl_index = 1,
> sdl_type = 6 '\006', sdl_nlen = 3 '\003', sdl_alen = 6 '\006',
> sdl_slen = 0 '\0', sdl_data = "dc0\b\000+\206\"J", '\0' <repeats 36
> times>}
> (kgdb) p $6.sdl_data + $6.sdl_nlen
> $7 = 0xfffffc000096b73b "\b"
>
> Register s3 holds the sp variable ($2 in kgdb)
> Register t0 holds the result the left-hand side of the statement, which
> is not properly aligned for a 16-bit load ($7 = register t0 + 8).
>
> Rough patch to fix the problem attached:

I think de(4) would need the same fix as well at least.

-- 
John Baldwin <jhb_at_FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
Received on Mon Nov 21 2005 - 13:49:07 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:48 UTC