shared: replace packed-struct get/put_unaligned with memcpy#445
shared: replace packed-struct get/put_unaligned with memcpy#445rawrmonster17 wants to merge 1 commit into
Conversation
Relevant kernel commit: a339671db64b ("vdso: Switch get/put_unaligned() from packed struct to memcpy()") |
|
Please use a real user for commit author and add your s-o-b. It doesn't pass a warning-free build: and also triggers array out of bounds: I think adopting a exact same macro as the kernel uses should be fine. This simplified version doesn't work as expected. |
The packed-struct pointer-cast pattern used by get_unaligned()/put_unaligned() is not portable. With GCC 14 at -O2 on RISC-V, and historically on other strict-alignment architectures, surrounding code can still be compiled into aligned accesses and fault at runtime. Switch the helpers to the same memcpy-based pattern the Linux kernel uses: strip qualifiers from the temporary object type, then use __builtin_memcpy() with void * casts for the load/store. This preserves the existing macro API while avoiding the discarded-qualifiers and array-bounds build failures reported in review. Fixes: kmod-project#338 Signed-off-by: Chris Beck <beck.chris88@outlook.com>
b62339a to
b5ce7e7
Compare
|
Updated the PR branch.
No call sites changed; the update is still localized to |
|
Thanks for the PR @rawrmonster17 - few questions/suggestions, in random order:
|
|
typeof_unqual is gcc >= 14 only. Also, even after that, it doesn't seem the generated code is really the same. |
Fixes #338.
Problem
The current
get_unaligned/put_unalignedmacros inshared/util.huse a packed-struct pointer-cast pattern:This is not guaranteed portable. With GCC 14 at
-O2on RISC-V (and historically on MIPS/SPARC strict-alignment targets), the auto-vectoriser can emit aligned vector loads for the surrounding loop inhash_superfast(), causing SIGBUS on hardware that enforces natural alignment (reported in #338).The bug affects
shared/hash.c(4 call sites in the main and fall-through loops) andlibkmod/libkmod-index.c(1 call site reading auint32_tfrom a potentially-unaligned address).put_unalignedis defined but currently unused.Fix
Replace both macros with
memcpy-based versions:memcpywith a compile-time-constant size is recognised by GCC, clang, and ICC and lowered to the same efficient inline sequence as the pointer cast on x86/x86-64, while remaining correct and standards-compliant on all architectures. This is the same approach used by the Linux kernel (include/linux/unaligned.h).<string.h>is already included byshared/util.h. The macro signatures are unchanged, so all call sites inhash.candlibkmod-index.care unaffected.Testing
meson setup build --buildtype=plain && ninja -C build— zero errors, zero warnings on all changed translation units.