a question about IP checksum helper for arm64

From: Bo Yan
Date: Fri Jul 06 2018 - 12:27:50 EST


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