* Bad traps for unaligned access in STM instruction @ 2012-09-15 10:46 Lluís Batlle i Rossell 2012-09-15 10:51 ` Lluís Batlle i Rossell 0 siblings, 1 reply; 7+ messages in thread From: Lluís Batlle i Rossell @ 2012-09-15 10:46 UTC (permalink / raw) To: linux-arm-kernel Hello all, I'm trying to diagnose a problem... on armv5tel, I have a userland software that runs an STM instruction in those conditions: r2 0xbeffeb95 r3 0x400000 r4 0x0 Instruction: stm r2, {r3, r4} After stepping the instruction, I get: (gdb) x/xg $r2 0xbeffeb95: 0xd800000000004000 While it should be: 0x0000000000400000 What can be going wrong? Linux 3.4.6 on armv5tel, gnueabi. I know the kernel trap goes in, I told the kernel to report the unaligned accesses, but I think it should fix them. From dmesg: Alignment trap: mkfs.btrfs (28871) PC=0x00039ac0 Instr=0xe8820018 Address=0xbeffeb95 FSR 0x801 I'll start looking at the arm traps for unaligned accesses, but maybe someone here can give a quick answer. Regards, Llu?s. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-15 10:46 Bad traps for unaligned access in STM instruction Lluís Batlle i Rossell @ 2012-09-15 10:51 ` Lluís Batlle i Rossell 2012-09-18 15:25 ` Dave Martin 0 siblings, 1 reply; 7+ messages in thread From: Lluís Batlle i Rossell @ 2012-09-15 10:51 UTC (permalink / raw) To: linux-arm-kernel On Sat, Sep 15, 2012 at 12:46:02PM +0200, Llu?s Batlle i Rossell wrote: > I'll start looking at the arm traps for unaligned accesses, but maybe someone > here can give a quick answer. Ah stupid me, here goes the quick answer. I had mode 'warn', and not 'fixup+warn'. With 'fixup' enabled, all works fine. I was used to mips, where I think there isn't a 'warn' that doesn't 'fixup'. Regards, Llu?s. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-15 10:51 ` Lluís Batlle i Rossell @ 2012-09-18 15:25 ` Dave Martin 2012-09-18 15:31 ` Lluís Batlle i Rossell 0 siblings, 1 reply; 7+ messages in thread From: Dave Martin @ 2012-09-18 15:25 UTC (permalink / raw) To: linux-arm-kernel On Sat, Sep 15, 2012 at 12:51:51PM +0200, Llu?s Batlle i Rossell wrote: > On Sat, Sep 15, 2012 at 12:46:02PM +0200, Llu?s Batlle i Rossell wrote: > > I'll start looking at the arm traps for unaligned accesses, but maybe someone > > here can give a quick answer. > > Ah stupid me, here goes the quick answer. I had mode 'warn', and not > 'fixup+warn'. With 'fixup' enabled, all works fine. > > I was used to mips, where I think there isn't a 'warn' that doesn't 'fixup'. What source are you actually trying to build/run here? The "fixup" alignment mode is primarily a workaround for incorrect code, because the legacy rotated unaligned access behaviour would cause really weird things to happen silently in the offending code. (Although misaligned LDM/STM was never permitted by the architecture anyway, and normally indicates badly-written code.) Pure C code should never trigger alignment faults fixups unless it violates the C language specification. Assembler should not trigger faults at all, because it's arch-specific and so you can and should fix it not to cause faults. Optimising code in assembler becomes pointless if you write or use it in a way which triggers unnecessary faults into the kernel. If you are getting faults in compiled code and the source code follows the C standard with regard to alignment requirements, this suggests a bug in the compiler. Either way, it needs investigating. Cheers ---Dave ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-18 15:25 ` Dave Martin @ 2012-09-18 15:31 ` Lluís Batlle i Rossell 2012-09-18 15:44 ` Nicolas Pitre 2012-09-18 19:07 ` Dave Martin 0 siblings, 2 replies; 7+ messages in thread From: Lluís Batlle i Rossell @ 2012-09-18 15:31 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 18, 2012 at 04:25:02PM +0100, Dave Martin wrote: > On Sat, Sep 15, 2012 at 12:51:51PM +0200, Llu?s Batlle i Rossell wrote: > > On Sat, Sep 15, 2012 at 12:46:02PM +0200, Llu?s Batlle i Rossell wrote: > > > I'll start looking at the arm traps for unaligned accesses, but maybe someone > > > here can give a quick answer. > > > > Ah stupid me, here goes the quick answer. I had mode 'warn', and not > > 'fixup+warn'. With 'fixup' enabled, all works fine. > > > > I was used to mips, where I think there isn't a 'warn' that doesn't 'fixup'. > > What source are you actually trying to build/run here? The "fixup" alignment > mode is primarily a workaround for incorrect code, because the legacy rotated > unaligned access behaviour would cause really weird things to happen silently > in the offending code. (Although misaligned LDM/STM was never permitted by > the architecture anyway, and normally indicates badly-written code.) > > Pure C code should never trigger alignment faults fixups unless it > violates the C language specification. > > Assembler should not trigger faults at all, because it's arch-specific > and so you can and should fix it not to cause faults. Optimising code > in assembler becomes pointless if you write or use it in a way which > triggers unnecessary faults into the kernel. > > If you are getting faults in compiled code and the source code follows > the C standard with regard to alignment requirements, this suggests a > bug in the compiler. This happened in the btrfs userland code, where there are packed structs, and structs stored at some offsets of datablocks. Offsets like '+17 bytes' since block start loaded from disk, and so. Then, some functions take pointers to structs. The "datablock+17bytes" is passed to processing functions as a pointer to struct. The code in those functions, expects that the structs are properly aligned. In an ideal userland software world, the counters of the traps would be zero. But they are not. And without fixup, the mkfs.btrfs fails to run properly, and creates a broken filesystem that crashes the kernel. Is the best way to deal with it, to allocate the structs in stack, copy from unaligned places to stack, and then work with those stack struct pointers? Thank you a lot for your answer, Llu?s. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-18 15:31 ` Lluís Batlle i Rossell @ 2012-09-18 15:44 ` Nicolas Pitre 2012-09-18 15:46 ` Lluís Batlle i Rossell 2012-09-18 19:07 ` Dave Martin 1 sibling, 1 reply; 7+ messages in thread From: Nicolas Pitre @ 2012-09-18 15:44 UTC (permalink / raw) To: linux-arm-kernel On Tue, 18 Sep 2012, Llu?s Batlle i Rossell wrote: > In an ideal userland software world, the counters of the traps would be zero. > But they are not. And without fixup, the mkfs.btrfs fails to run properly, and > creates a broken filesystem that crashes the kernel. If a broken btrfs filesystem crashes the kernel, you should definitively report it as a bug to the btrfs developers. Filesystem code must be immune to any kind of corruptions and gracefully cope with them. Nicolas ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-18 15:44 ` Nicolas Pitre @ 2012-09-18 15:46 ` Lluís Batlle i Rossell 0 siblings, 0 replies; 7+ messages in thread From: Lluís Batlle i Rossell @ 2012-09-18 15:46 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 18, 2012 at 11:44:02AM -0400, Nicolas Pitre wrote: > On Tue, 18 Sep 2012, Llu?s Batlle i Rossell wrote: > > > In an ideal userland software world, the counters of the traps would be zero. > > But they are not. And without fixup, the mkfs.btrfs fails to run properly, and > > creates a broken filesystem that crashes the kernel. > > If a broken btrfs filesystem crashes the kernel, you should definitively > report it as a bug to the btrfs developers. Filesystem code must be > immune to any kind of corruptions and gracefully cope with them. Yes I know; I did report that. Thank you ^ permalink raw reply [flat|nested] 7+ messages in thread
* Bad traps for unaligned access in STM instruction 2012-09-18 15:31 ` Lluís Batlle i Rossell 2012-09-18 15:44 ` Nicolas Pitre @ 2012-09-18 19:07 ` Dave Martin 1 sibling, 0 replies; 7+ messages in thread From: Dave Martin @ 2012-09-18 19:07 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 18, 2012 at 05:31:19PM +0200, Llu?s Batlle i Rossell wrote: > On Tue, Sep 18, 2012 at 04:25:02PM +0100, Dave Martin wrote: > > On Sat, Sep 15, 2012 at 12:51:51PM +0200, Llu?s Batlle i Rossell wrote: > > > On Sat, Sep 15, 2012 at 12:46:02PM +0200, Llu?s Batlle i Rossell wrote: > > > > I'll start looking at the arm traps for unaligned accesses, but maybe someone > > > > here can give a quick answer. > > > > > > Ah stupid me, here goes the quick answer. I had mode 'warn', and not > > > 'fixup+warn'. With 'fixup' enabled, all works fine. > > > > > > I was used to mips, where I think there isn't a 'warn' that doesn't 'fixup'. > > > > What source are you actually trying to build/run here? The "fixup" alignment > > mode is primarily a workaround for incorrect code, because the legacy rotated > > unaligned access behaviour would cause really weird things to happen silently > > in the offending code. (Although misaligned LDM/STM was never permitted by > > the architecture anyway, and normally indicates badly-written code.) > > > > Pure C code should never trigger alignment faults fixups unless it > > violates the C language specification. > > > > Assembler should not trigger faults at all, because it's arch-specific > > and so you can and should fix it not to cause faults. Optimising code > > in assembler becomes pointless if you write or use it in a way which > > triggers unnecessary faults into the kernel. > > > > If you are getting faults in compiled code and the source code follows > > the C standard with regard to alignment requirements, this suggests a > > bug in the compiler. > > This happened in the btrfs userland code, where there are packed structs, and > structs stored at some offsets of datablocks. Offsets like '+17 bytes' since > block start loaded from disk, and so. > > Then, some functions take pointers to structs. The "datablock+17bytes" is passed > to processing functions as a pointer to struct. The code in those functions, > expects that the structs are properly aligned. Right, so this is not portable C code. It will work with some architecture/compiler combinations, but the C language makes no guarantee about it. If the structure members are naturally aligned internally but the whole structure is misaligned, then simple pointer casting tricks will work with some arches/compilers, as the btrfs tools apparently assume. Where this doesn't work... If the structures are truly packed (i.e., padding bytes are removed so that members are not naturally aligned internally), then you have no choice except to access them using packed structure types, or implement a load of accessors to get at the individual members. Otherwise, if you are sure that the internal layout of the strcuture will be the same with or without the packed attribute, you can access the structs with packed structure types to cope with the misalignment ... but with some performance cost on some architectures. (Note that you still can't have void foo(struct bar *p) { } if p might be misaligned for struct bar, even if foo() uses clever misaligned accessors internally. This is because that function declaration is a guarantee to the compiler that at run-time your program ensures that p will always be suitably aligned for a struct bar on every call. If the alignment requirement is > 1 byte, you may find that the compiler unexpectedly ignores or masks off the bottom bits of in some situations -- I've seen real examples of this happening.) > Is the best way to deal with it, to allocate the structs in stack, copy from > unaligned places to stack, and then work with those stack struct pointers? Fixes, in decreasing order of preference (just my opinion, of course): 1) The preferred fix would be to naturally align all elements in the _on-disk_ data structures, so that there is never any need to munge them around. The ext2/3/4 implementations and the ELF file format do a pretty good job of this for example... but I suspect that is may be too late for fix this for btrfs (?) 2) Do what you suggest and memcpy the structures from/to their packed locations into properly declared storage. This could be made build-time selectable based on the target-arch, to avoid the extra copy on arches where it doesn't matter, at the expense of adding a little complexity to the source code. If the on-disk structures may be in a foreign endianness, you may have some overhead already in some configurations, in which case the memcpy might look less expensive. But I would hope that btrfs is not foreign-endian in most normal setups. (I don't know anything about the btfrs on-disk format though.) memcpy may not be desirable if the amount of data the code manipulates per structure on a typical run is much smaller than the whole structure, because memcpy may dominate the overhead. mkfs may generate enough storage I/O delay to mask those overheads, though, depending on various factors. 3) Alternatively, you need the argument types for all those functions to be packed too. This gets rather inelegant, because GCC attribute handling is inelegant. You'll also need it everywhere on the affected call paths. Also, GCC tends to generate rather inefficient code for accessing packed structures prior to ARMv6. Basically everything has to be split into byte accesses. So you may want alternate, non-packed versions of all those functions too if you hit performance problems. Attributes are also not portable between toolchains (which you may or may not care about... but there should be no good reason for something like mkfs.btrfs to be non-portable.) If fixing the on-disk structures to align data naturally is not an option, I guess the most straightforward solutions are to use memcpy() or to put __attribute__ (( __packed__ )) on all your structure type definitions everywhere, if you can do this without the definitions no longer matching the on-disk structure layouts on any architecture. Both will result some inefficiency, but I suspect the impact of the packed attribute may be worse for ARM, at least prior to ARMv6. You could try both and run some benchmarks if you think that performance is likely to be an issue. > In an ideal userland software world, the counters of the traps would be zero. > But they are not. And without fixup, the mkfs.btrfs fails to run properly, and > creates a broken filesystem that crashes the kernel. I agree with Nicolas: if you can crash or compromise the kernel with a badly or maliciously formatted filesystem, that's a separate, serious bug in the filesystem driver which absolutely needs to be fixed (especially when typical desktop environments now like to automount every filesystem within a 10m radius of your machine...) Cheers ---Dave ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-09-18 19:07 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-09-15 10:46 Bad traps for unaligned access in STM instruction Lluís Batlle i Rossell 2012-09-15 10:51 ` Lluís Batlle i Rossell 2012-09-18 15:25 ` Dave Martin 2012-09-18 15:31 ` Lluís Batlle i Rossell 2012-09-18 15:44 ` Nicolas Pitre 2012-09-18 15:46 ` Lluís Batlle i Rossell 2012-09-18 19:07 ` Dave Martin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).