unaligned memory access on ARMs: how to test CP15 flags

614 views
Skip to first unread message

pps

unread,
Apr 5, 2013, 3:34:27 PM4/5/13
to andro...@googlegroups.com
In some specific case I'm forced to use unaligned reads/writes (ldr, str from/to addresses that are not 4-byte aligned).
I don't care for anything pre-armv6. Behavior of the CPU when unaligned access is made is controlled by a few flags: U flag to enable unaligned access, and A flag for unaligned access check. It seems that most of the phones that I have have unaligned access enabled by default.

My question: how can I check if unaligned access is OK on a particular android arm phone?

Unaligned memory access might potentially be handled by a trap in the kernel that does necessary stuff to "fix" the unaligned read making it exceptionally slow.

To be able to read the flags I need to access privileged CPU instruction (mrc p15,0,rN,c1,c0,0) that's not accessible to me.
I'd like to test somehow that this unaligned access is available and if it's not, then I'd use unoptimized slow functions that do not have alignment issues.

David Given

unread,
Apr 5, 2013, 3:51:29 PM4/5/13
to andro...@googlegroups.com
On 05/04/13 20:34, pps wrote:
[...]
> My question: how can I check if unaligned access is OK on a particular
> android arm phone?

Look at /proc/cpu/alignment --- it's globally readable (or at least
should be). On my ARM server it says:

User: 0
System: 0
Skipped: 0
Half: 0
Word: 0
DWord: 0
Multi: 0
User faults: 2 (fixup)

The field you want is the last one. The values are described here:

https://www.kernel.org/doc/Documentation/arm/mem_alignment

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ "Home is where, when you have to go there, they have to take you in."
│ --- Cordelia Naismith (via Robert Frost)

pps

unread,
Apr 5, 2013, 6:10:36 PM4/5/13
to andro...@googlegroups.com
I know about it, but it's completely useless or broken IMO.

For example, on my phone it says:

User:        0
System:      34

Skipped:     0
Half:        0
Word:        0
DWord:       0
Multi:       34
User faults: 4 (signal)

I also run that test before and after performing unaligned reads and the numbers weren't affected (I read that /proc/cpu/alignment from my own process obviously)

4 means send a SIGBUS. If I intentionally do unaligned read, I don't get any SIGBUS. I'm also sure that it's not the kernel trapped and handled it, because in that case I wouldn't see considerable speedup in my code.
In other words, the CPU is configured to accept and handle prolery unaligned reads/stores (U is set and A is cleared in cp15). I don't want to universally enable analigned access in my app because there could easily be a device that doesn't have these flags set properly.

David Given

unread,
Apr 5, 2013, 6:55:45 PM4/5/13
to andro...@googlegroups.com
On 05/04/13 23:10, pps wrote:
> I know about it, but it's completely useless or broken IMO.
[...]
> User faults: 4 (signal)
[...]
> 4 means send a SIGBUS. If I intentionally do unaligned read, I don't get
> any SIGBUS.

Hmm. You're right --- I've knocked up a simple test program on a
Cyanogen device I've got handy with a debian chroot (easy to get at the
compiler, you see) and it behaves identically. The results it's
producing look like gibberish

Trying it on my ARM server produces identical results, and changing the
alignment setting makes no difference to the behaviour. Smells like a
kernel bug to me, I'm afraid.

pps

unread,
Apr 5, 2013, 9:10:36 PM4/5/13
to andro...@googlegroups.com
I think there is no bug in kernel.
that unaligned trap in kernel will only work if A-bit is set in cp15. If A-bit isn't set then cpu won't generate any exception and obviously whatever kernel has in that /proc/cpu/alignment will be unused. I'd say that it's a bug if docs for /proc/cpu/alignment mentioned a way to enable unaligned access of the cpu itself and not emulated alignment.

old ARMs would abort if ldr was performed on non 4-byte aligned address. Current CPUs have unaligned access, but ldrd or ldm are more strict in this regard as far as I know. Just tested and confirmed: unaligned ldrd generates SIGBUS. If A-bit was set then regular LDR of unaligned address would abort and I want to be able to know if it will abort or not before running my code.
Obviously, I can write a simple test that will try to read unaligned memory and catch sigbus... but I had some androids that crash with that approach with signals and I also would have to make sure that /proc/cpu/alignment is 4.

David Turner

unread,
Apr 8, 2013, 5:42:25 AM4/8/13
to andro...@googlegroups.com
On Fri, Apr 5, 2013 at 9:34 PM, pps <pavlov...@gmail.com> wrote:
In some specific case I'm forced to use unaligned reads/writes (ldr, str from/to addresses that are not 4-byte aligned).
I don't care for anything pre-armv6. Behavior of the CPU when unaligned access is made is controlled by a few flags: U flag to enable unaligned access, and A flag for unaligned access check. It seems that most of the phones that I have have unaligned access enabled by default.

My question: how can I check if unaligned access is OK on a particular android arm phone?


The only reliable way is to perform an unaligned access and trap the signal from it. Unfortunately, the kernel often doesn't report accurate information, and the coprocessor instruction you would want to use is not accessible from user processes, only the kernel.

There are two ways to achieve this, and none of them are terribly portable:

1/ Fork a child process, and perform the unaligned access here, then simply exit(0). In the parent, detect if the process terminated normally or with an error.
2/ Setup a SIGILL handler, and use setjmp() /  longjmp() before calling it, and before returning from it, respectively.

Of course, the best thing would be to completely avoid un-aligned memory accesses anyway.
 
Unaligned memory access might potentially be handled by a trap in the kernel that does necessary stuff to "fix" the unaligned read making it exceptionally slow.

To be able to read the flags I need to access privileged CPU instruction (mrc p15,0,rN,c1,c0,0) that's not accessible to me.
I'd like to test somehow that this unaligned access is available and if it's not, then I'd use unoptimized slow functions that do not have alignment issues.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at http://groups.google.com/group/android-ndk?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages