Getting rid of alignment faults in userspace

Andy Green andy.green at linaro.org
Fri Jun 17 21:54:58 UTC 2011


On 06/17/2011 08:17 PM, Somebody in the thread at some point said:
> On 06/17/2011 08:11 AM, Andy Green wrote:
>> On 06/17/2011 01:10 PM, Somebody in the thread at some point said:
>>
>> Hi -
>>
>>> I've recently become aware that a few packages are causing alignment
>>> faults on ARM, and are relying on the alignment fixup emulation code in
>>> the kernel in order to work.
>>
>> Just a FYI a lot of later ARM chips are solving alignment fixups in
>> hardware in the Bus Interface Unit, so the problems won't show up in
>> kernel stats.
>>
>>> Such faults are very expensive in terms of CPU cycles, and can generally
>>> only result from wrong code (for example, C/C++ code which violates the
>>> relevant language standards, assembler which makes invalid assumptions,
>>> or functions called with misaligned pointers due to other bugs).
>>
>> Agreed it's usually evidence of something broken and / or evil in the code.
>>
>> There is still going to be a small cost even in hardware fixup so this
>> is very much worth solving despite it's "becoming invisible" because the
>> chips are hiding / solving it already.
>>
>
> But I believe that h/w feature is turned off in Linux by default. You
> have to add noalign to the kernel command line to enable.

I think you'll find the hardware fixups are enabled by default on CPUs 
with that design, quite possibly it can't be turned off.

This test was done on a Panda:

root at linaro:~# cat /proc/cmdline
console=tty0 console=ttyO2,115200n8 earlycon=ttyO2,115200n8 
earlyprintk=1 root=/dev/mmcblk0p2 rootwait ro fixrtc vram=32M 
omapfb.vram=0:16M,1:16M mem=456M

ie, nothing about "noalign".

Test code crafted to blow alignment faults on the dereference:

#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[])
{
      char buf[8];
      void *v = &buf[1];
      unsigned int *p = (unsigned int *)v;

      strcpy(buf, "abcdefg");

      printf("0x%08x\n", *p);

      return 0;
}

Default case with soft fixup enabled:

root at linaro:~# cat /proc/cpu/alignment
User:		0
System:		0
Skipped:	0
Half:		0
Word:		0
DWord:		0
Multi:		0
User faults:	2 (fixup)

root at linaro:~# gcc test.c
root at linaro:~# ./a.out
0x65646362

Test case with soft fixup disabled:

root at linaro:~# echo 0 > /proc/cpu/alignment
root at linaro:~# cat /proc/cpu/alignment
User:		0
System:		0
Skipped:	0
Half:		0
Word:		0
DWord:		0
Multi:		0
User faults:	0 (ignored)

root at linaro:~# ./a.out
0x65646362

ie, the result is always fixed up on OMAP4 and kernel fixup code never 
gets an exception even.

-Andy



More information about the ubuntu-devel mailing list