Beagle-Bone-Black, 13-1 GENERICSD release image panics in PF: login: Fatal kernel mode data abort: 'Alignment Fault' on read trapframe: 0xd71a7930 FSR=00000001, FAR=c3328224, spsr=60000013 r0 =d71a7a48, r1 =27244242, r2 =bf798103, r3 =c3328224 r4 =d1494200, r5 =d14db000, r6 =27244265, r7 =00000000 r8 =c092c92c, r9 =d71a7b68, r10=00000001, r11=d71a79d8 r12=d7297918, ssp=d71a79c0, slr=d724a5e8, pc =d7282800 panic: Fatal abort cpuid = 0 time = 1659683836 KDB: stack backtrace: #0 0xc0355b70 at kdb_backtrace+0x48 #1 0xc02fcb50 at vpanic+0x170 #2 0xc02fc9e0 at vpanic+0 #3 0xc061bc14 at abort_align+0 #4 0xc061bc70 at abort_align+0x5c #5 0xc061b8e4 at abort_handler+0x480 #6 0xc05fac68 at exception_exit+0 #7 0xd7282800 at pf_syncookie_validate+0x3c #8 0xd724a5e8 at $a.110+0x20 #9 0xd726c868 at $a.166+0x34 #10 0xc0441f68 at pfil_run_hooks+0xa0 #11 0xc046e808 at ip_input+0x694 #12 0xc0440c70 at netisr_dispatch_src+0xf8 #13 0xc043863c at ether_demux+0x1a4 #14 0xc0439cd0 at ether_nh_input+0x480 #15 0xc0440c70 at netisr_dispatch_src+0xf8 #16 0xc0438b08 at ether_input+0x50 #17 0xc0cfbee4 at $a.6+0x5a0 pf.conf available on request
Can you correlate the faulting PC with the source line?
In my non-invariants copy of pf_syncookie_validate(), the instr at offset 0x3c is ldrexd r4, [r3], which loads a 64-bit value from the address in r3, which according to the register dump below is not 8-byte aligned. That's part of the atomic_add_64() implementation. But, on arm uint64_t has 8-byte alignment, so I don't quite see how the misalignment can arise.
The issue stems from VNET allocations only being aligned to 4. how about this: diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 4f242b07f169..3a0d40a31b6a 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -377,7 +377,11 @@ vnet_data_alloc(int size) void *s; s = NULL; +#if __LP32__ + size = roundup2(size, 2 * sizeof(void *)); +#else size = roundup2(size, sizeof(void *)); +#endif sx_xlock(&vnet_data_free_lock); TAILQ_FOREACH(df, &vnet_data_free_head, vnd_link) { if (df->vnd_len < size) @@ -409,7 +413,11 @@ vnet_data_free(void *start_arg, int size) uintptr_t start; uintptr_t end; +#if __LP32__ + size = roundup2(size, 2 * sizeof(void *)); +#else size = roundup2(size, sizeof(void *)); +#endif start = (uintptr_t)start_arg; end = start + size; /*
heh, wow. there is no __LP32__ macro, someone(tm) will have to add one. In the meantime the point is to validate everything works fine after the size is rounded up to a multiply of 8.
This should do the trick: diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 4f242b07f169..da1fd0f36785 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -377,7 +377,17 @@ vnet_data_alloc(int size) void *s; s = NULL; +#ifdef __ILP32__ + /* + * Note that the area allocated here might hold fields + * modified with 64-bit atomics. Accomodate it by rounding + * the size up to a multiple of 64-bit to ensure the + * expected alignment. + */ + size = roundup2(size, 2 * sizeof(void *)); +#else size = roundup2(size, sizeof(void *)); +#endif sx_xlock(&vnet_data_free_lock); TAILQ_FOREACH(df, &vnet_data_free_head, vnd_link) { if (df->vnd_len < size) @@ -409,7 +419,11 @@ vnet_data_free(void *start_arg, int size) uintptr_t start; uintptr_t end; +#ifdef __ILP32__ + size = roundup2(size, 2 * sizeof(void *)); +#else size = roundup2(size, sizeof(void *)); +#endif start = (uintptr_t)start_arg; end = start + size; /*