[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <141d76cc-d43b-5412-fb39-426d7c2261b9@nvidia.com>
Date: Fri, 6 Jul 2018 09:27:42 -0700
From: Bo Yan <byan@...dia.com>
To: <robin.murphy@....com>
CC: <linux-kernel@...r.kernel.org>, <luke.starrett@...adcom.com>
Subject: a question about IP checksum helper for arm64
Hi Robin, Luke,
Recently I bumped into an error when running GCC undefined behavior
sanitizer:
UBSAN: Undefined behaviour in
kernel-4.9/arch/arm64/include/asm/checksum.h:34:6
load of misaligned address ffffffc198c8b254 for type 'const
__int128 unsigned'
which requires 16 byte alignment
The relevant code:
tmp = *(const __uint128_t *)iph;
iph += 16;
ihl -= 4;
tmp += ((tmp >> 64) | (tmp << 64));
sum = tmp >> 64;
do {
sum += *(const u32 *)iph;
iph += 4;
} while (--ihl);
But, I checked the generated disassembly, it doesn't look like anything
special is generated taking advantage of that.
I'm using Linaro GCC 6.4-2017.08, expecting ldp instructions to be
emitted, but don't see it.
There were some prior discussions about GCC behavior, like this thread:
https://patchwork.kernel.org/patch/9081911/ , in which you talked about
the difference between GCC4 and GCC5.3. It looks to me this is regressed
in Linaro GCC6.4 build.
I have not checked newer GCC versions.
Will it be more stable to just do this with inline assembly instead of
relying on __uint128_t data type?
GCC documentation says __int128 is supported for targets which have an
integer mode wide enough to hold 128 bits. aarch64 doesn't have such an
integer mode.
Thanks
Bo
Powered by blists - more mailing lists