alignment faults in 3.6

Eric Dumazet eric.dumazet at gmail.com
Thu Oct 11 06:22:06 EDT 2012


On Thu, 2012-10-11 at 12:00 +0200, Eric Dumazet wrote:
> On Thu, 2012-10-11 at 10:45 +0100, Måns Rullgård wrote:

> 
> I have no idea what is the problem, 
> 
> -ENOTENOUGHCONTEXT
> 
> 

I took a look, and I dont see why/how gcc could use a ldm instruction

Doing so assumed the alignment of the structure was 8 bytes, but its
not.

Networking stack mandates that IP headers are aligned on 4 bytes
boundaries, not 8 bytes.

(Some arches like x86 dont care, so we might have some bugs in some
drivers, but not in the GRO code)

Some drivers are not aware of the NET_IP_ALIGN stuff.
They should be fixed, or else you have alignment faults.

struct iphdr {
 	__u8	ihl:4,
		version:4;
	__u8	tos;
	__be16	tot_len;
	__be16	id;
	__be16	frag_off;
	__u8	ttl;
	__u8	protocol;
	__sum16	check;
	__be32	saddr;
	__be32	daddr;
	/*The options start here. */
};

The alignment of iphdr is 4, not 8

doing id = ntohl(*(__be32 *)&iph->id); is valid

doing flush = (u16)((ntohl(*(__be32 *)iph) ^ len) | (id ^ IP_DF)); is valid as well.

If arm compiler decided to use a 8bytes load, thats a compiler bug.

(unless compiler was specifically told that alignment did not matter)

c02ac020:       e8920840        ldm     r2, {r6, fp}    // HERE
c02ac024:       e6bfbf3b        rev     fp, fp
c02ac028:       e6bf6f36        rev     r6, r6
c02ac02c:       e22bc901        eor     ip, fp, #16384  ; 0x4000
c02ac030:       e0266008        eor     r6, r6, r8
c02ac034:       e18c6006        orr     r6, ip, r6





More information about the linux-arm-kernel mailing list