From: Helge Deller <deller@xxxxxx>
While working on the 64-bit parisc kernel, I noticed that the __ksymtab[]
table was not correctly 64-bit aligned in many modules.
The following patches do fix some of those issues in the generic code.
But further investigation shows that multiple sections in the kernel and in
modules are possibly not correctly aligned, and thus may lead to performance
degregations at runtime (small on x86, huge on parisc, sparc and others which
need exception handlers). Sometimes wrong alignments may also be simply hidden
by the linker or kernel module loader which pulls in the sections by luck with
a correct alignment (e.g. because the previous section was aligned already).
An objdump on a x86 module shows e.g.:
./kernel/net/netfilter/nf_log_syslog.ko: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00001fdf 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .init.text 000000f6 0000000000000000 0000000000000000 00002020 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 .exit.text 0000005c 0000000000000000 0000000000000000 00002120 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
3 .rodata.str1.8 000000dc 0000000000000000 0000000000000000 00002180 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .rodata.str1.1 0000030a 0000000000000000 0000000000000000 0000225c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .rodata 000000b0 0000000000000000 0000000000000000 00002580 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .modinfo 0000019e 0000000000000000 0000000000000000 00002630 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .return_sites 00000034 0000000000000000 0000000000000000 000027ce 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
8 .call_sites 0000029c 0000000000000000 0000000000000000 00002802 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
In this example I believe the ".return_sites" and ".call_sites" should have
an alignment of at least 32-bit (4 bytes).
On other architectures or modules other sections like ".altinstructions" or
"__ex_table" may show up wrongly instead.
In general I think it would be beneficial to search for wrong alignments at
link time, and maybe at runtime.
The patch at the end of this cover letter
- adds compile time checks to the "modpost" tool, and
- adds a runtime check to the kernel module loader at runtime.
And it will possibly show false positives too (!!!)
I do understand that some of those sections are not performce critical
and thus any alignment is OK.
The modpost patch will emit at compile time such warnings (on x86-64 kernel build):
WARNING: modpost: vmlinux: section .initcall7.init (type 1, flags 2) has alignment of 1, expected at least 4.
Maybe you need to add ALIGN() to the modules.lds file (or fix modpost) ?
WARNING: modpost: vmlinux: section .altinstructions (type 1, flags 2) has alignment of 1, expected at least 2.
WARNING: modpost: vmlinux: section .initcall6.init (type 1, flags 2) has alignment of 1, expected at least 4.
WARNING: modpost: vmlinux: section .initcallearly.init (type 1, flags 2) has alignment of 1, expected at least 4.
WARNING: modpost: vmlinux: section .rodata.cst2 (type 1, flags 18) has alignment of 2, expected at least 64.
WARNING: modpost: vmlinux: section .static_call_tramp_key (type 1, flags 2) has alignment of 1, expected at least 8.
WARNING: modpost: vmlinux: section .con_initcall.init (type 1, flags 2) has alignment of 1, expected at least 8.
WARNING: modpost: vmlinux: section __bug_table (type 1, flags 3) has alignment of 1, expected at least 4.
...