On 24 May 2017 at 10:36, Robin Murphy <robin.murphy@xxxxxxx> wrote: > On 24/05/17 18:27, Ard Biesheuvel wrote: >> On 24 May 2017 at 09:56, Mason <slash.tmp@xxxxxxx> wrote: >>> On 24/05/2017 17:45, Robin Murphy wrote: >>> >>>> On 24/05/17 16:26, Mason wrote: >>>> >>>>> Consider the following user-space code, split over two files >>>>> to defeat the optimizer. >>>>> >>>>> This test program maps a page of memory not managed by Linux, >>>>> and writes 4 words to misaligned addresses within that page. >>>>> >>>>> $ cat store.c >>>>> void store_at_addr_plus_0(void *addr, int val) >>>>> { >>>>> __builtin_memcpy(addr + 0, &val, sizeof val); >>>>> } >>>>> void store_at_addr_plus_1(void *addr, int val) >>>>> { >>>>> __builtin_memcpy(addr + 1, &val, sizeof val); >>>>> } >>>>> >>>>> $ cat testcase.c >>>>> #include <fcntl.h> >>>>> #include <sys/mman.h> >>>>> #include <stdio.h> >>>>> void store_at_addr_plus_0(void *addr, int val); >>>>> void store_at_addr_plus_1(void *addr, int val); >>>>> int main(void) >>>>> { >>>>> int fd = open("/dev/mem", O_RDWR | O_SYNC); >>>>> void *ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xc0000000); >>>>> store_at_addr_plus_0(ptr + 0, fd); puts("X"); // store at ptr + 0 => OK >>>>> store_at_addr_plus_0(ptr + 1, fd); puts("X"); // store at ptr + 1 => OK >>>>> store_at_addr_plus_1(ptr + 3, fd); puts("X"); // store at ptr + 4 => OK >>>>> store_at_addr_plus_1(ptr + 0, fd); puts("X"); // store at ptr + 1 => ABORT >>>>> return 0; >>>>> } >>>>> >>>>> With optimizations turned off, the program works as expected. >>>>> >>>>> $ arm-linux-gnueabihf-gcc-6.3.1 -Wall -O0 testcase.c store.c -o misaligned_stores >>>>> $ ./misaligned_stores >>>>> X >>>>> X >>>>> X >>>>> X >>>>> >>>>> But if optimizations are enabled, the program aborts on the last store. >>>>> >>>>> $ arm-linux-gnueabihf-gcc-6.3.1 -Wall -O1 testcase.c store.c -o misaligned_stores >>>>> # ./misaligned_stores >>>>> X >>>>> X >>>>> X >>>>> Bus error >>>>> [ 8736.457254] Alignment trap: not handling instruction f8c01001 at [<000104aa>] >>>> ^^^ >>>> >>>> Note where that message comes from: The alignment fault fixup code >>>> doesn't recognise this instruction encoding, so it doesn't get fixed up. >>>> It's that simple. >> >> Well spotted. I missed that bit, but it makes perfect sense. Mason, >> care to propose a patch to the alignment fixup code that adds the >> missing encoding? > > No need for that - anything that could be executing 32-bit Thumb > encodings also supports (and will be using) the v6 unaligned access > model by definition. I would assume that the "regular" loads/stores are > deliberately unhandled for that reason (i.e. it would never be correct > to fix up). > Fair enough. It causes some inconsistencies, as the example shows, but the alignment fault handling is slightly inconsistent anyway, so I suppose that doesn't really matter (given that the code is not intended to deal with accesses to mappings with device attributes)