2022-08-17 16:27:22

by Yann Sionneau

[permalink] [raw]
Subject: [RFC PATCH 0/1] Fix __kcrctab+* sections alignment

Hello,
At Kalray we have our (non-upstreamed-yet) kvx Linux port (https://github.com/kalray/linux_coolidge).

When I did the rebase on 5.19 I noticed the kernel module would not load anymore and would say

[ 10.071771] Found checksum 0 vs module B4E7D8E
[ 10.071824] libphy: disagrees about version of symbol module_layout

The CRC of module_layout in libphy.ko seems fine, but surprisingly, the CRC of module_layout in vmlinux is 0.

I dig a little bit to try and understand why.

.vmlinux.export.c contains:
SYMBOL_CRC(module_layout, 0x0b4e7d8e, "");

Dumping the section '___kcrctab+module_layout' of .vmlinux.export.o I get:
Hex dump of section '___kcrctab+module_layout':
0x00000000 8e7d4e0b .}N.

Dumping __kcrctab section of vmlinux:
Hex dump of section '__kcrctab':
0xffffff80055b7090 572828d0 00000000 b96e414c 00000000 W((......nAL....
0xffffff80055b70a0 b0179638 00000000 e3eb8db7 00000000 ...8............
0xffffff80055b70b0 7a10c1c7 00000000 3d04478a 00000000 z.......=.G.....
0xffffff80055b70c0 a5d7be15 00000000 d188008b 00000000 ................
0xffffff80055b70d0 6214323b 00000000 bba48601 00000000 b.2;............
0xffffff80055b70e0 6bfbba55 00000000 251fa090 00000000 k..U....%.......
0xffffff80055b70f0 2861bde8 00000000 81c8241d 00000000 (a........$.....
etc

You can see that in fact there is some kind of 4-bytes padding in-between each CRC32.

And indeed by looking at ___kcrctab+module_layout section alignment in .vmlinux.export.o I can see:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[...snip snip...]
[6189] ___kcrctab+module_layout PROGBITS 0000000000000000 00c188 000004 00 WA 0 0 8

So somehow, the section really contains 4 bytes of the CRC32 but even though the section contains a u32, the toolchain creates an 8-bytes aligned section.
This ends up creating 4-bytes padding with 0s once the linker collects all those ___kcrctab+* into __kcrctab for vmlinux ELF.

Do you think this is an issue in Linux kernel generic code? (See attached patch that makes our module probe again)
Or is this an issue with our toolchain?

On 5.16.20 our modules were loading fine and the __kcrctab did not contain any 4-bytes 00000000 gaps.
I think it is related to this change: https://lore.kernel.org/linux-kbuild/[email protected]/T/
In the change, we can see that the previous version was using assembly to create the sections and there was the presence of a ".balign KCRC_ALIGN" which was defined to whatever is the arch-specific way to encode a "4 bytes" alignement (be it 2 for "2^2" for m68k or directly 4 for others) for the assembler.

How to reproduce:
1/ generate the toolchain
$ git clone https://github.com/kalray/build-scripts
$ cd build-scripts
$ source last.refs
$ ./build-kvx-xgcc.sh output

2/ fetch and build our v5.19 kernel
$ git clone -b kalray-linux-v5.19 https://github.com/kalray/linux_coolidge
$ cd linux_coolidge
$ make ARCH=kvx O=build_kvx CROSS_COMPILE=kvx-elf- default_defconfig
$ make ARCH=kvx O=build_kvx CROSS_COMPILE=kvx-elf- -j$(($(nproc) + 1))

You won't have a rootfs but you will be able to observe the content of __kcrctab section of vmlinux
PS: the kalray-linux-v5.19 branch already contains the attached-patch to add __aligned(4) requirement.
PPS: Please CC me, I am not subscribed to the mailing list

Yann Sionneau (1):
Fix __kcrctab+* sections alignment

include/linux/export-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--
2.37.2






2022-08-17 16:40:13

by Yann Sionneau

[permalink] [raw]
Subject: [RFC PATCH 1/1] Fix __kcrctab+* sections alignment

Signed-off-by: Yann Sionneau <[email protected]>
---
include/linux/export-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h
index c2b1d4fd5987..d86bfbd7fa6d 100644
--- a/include/linux/export-internal.h
+++ b/include/linux/export-internal.h
@@ -12,6 +12,6 @@

/* __used is needed to keep __crc_* for LTO */
#define SYMBOL_CRC(sym, crc, sec) \
- u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc
+ u32 __section("___kcrctab" sec "+" #sym) __used __aligned(4) __crc_##sym = crc

#endif /* __LINUX_EXPORT_INTERNAL_H__ */
--
2.37.2