[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1349950926.21172.8521.camel@edumazet-glaptop>
Date: Thu, 11 Oct 2012 12:22:06 +0200
From: Eric Dumazet <eric.dumazet@...il.com>
To: Måns Rullgård <mans@...sr.com>
Cc: David Laight <David.Laight@...LAB.COM>,
Jon Masters <jonathan@...masters.org>,
linux-arm-kernel@...ts.infradead.org, netdev@...r.kernel.org
Subject: Re: alignment faults in 3.6
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
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists