Quoting Sami Tolvanen (2020-12-11 10:46:22) > LLD always splits sections with LTO, which increases module sizes. This > change adds linker script rules to merge the split sections in the final > module. > > Suggested-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx> > Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx> > Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> > --- This patch fixes a warning I see on arm64 devices running the 5.10 LTS kernel. Can we queue this to the stable tree once it lands in Linus' tree? sysfs: cannot create duplicate filename '/module/configs/sections/__patchable_function_entries' CPU: 3 PID: 4173 Comm: modprobe Not tainted 5.10.13 #10 Hardware name: Google Lazor (rev3+) with KB Backlight (DT) Call trace: dump_backtrace+0x0/0x1c0 show_stack+0x24/0x30 dump_stack+0xc0/0x120 sysfs_warn_dup+0x74/0x90 sysfs_add_file_mode_ns+0x12c/0x178 internal_create_group+0x264/0x36c sysfs_create_group+0x24/0x30 add_sect_attrs+0x154/0x188 mod_sysfs_setup+0x208/0x284 load_module+0xff8/0x1158 __arm64_sys_finit_module+0xb4/0xf0 el0_svc_common+0xf4/0x1c0 do_el0_svc_compat+0x2c/0x40 el0_svc_compat+0x10/0x1c el0_sync_compat_handler+0xc0/0xf0 el0_sync_compat+0x178/0x180 The problem is that the section __patchable_function_entries is present twice in the kernel module I've compiled. I see that __patchable_function_entries is used on arm64 now that we have commit a1326b17ac03 ("module/ftrace: handle patchable-function-entry") combined with commit 3b23e4991fb6 ("arm64: implement ftrace with regs"). This linker script change nicely combines the section into one instead of two. Before: $ readelf -WS configs.ko There are 29 section headers, starting at offset 0xad78: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .plt NOBITS 0000000000000000 000040 000001 00 AX 0 0 16 [ 2] .init.plt NOBITS 0000000000000000 000040 000001 00 AX 0 0 1 [ 3] .text.ftrace_trampoline NOBITS 0000000000000000 000040 000001 00 AX 0 0 1 [ 4] .text PROGBITS 0000000000000000 000040 00004c 00 AX 0 0 4 [ 5] .rela.text RELA 0000000000000000 00aa10 000078 18 I 26 4 8 [ 6] __patchable_function_entries PROGBITS 0000000000000000 000090 000008 00 WAL 4 0 8 [ 7] .rela__patchable_function_entries RELA 0000000000000000 00aa88 000018 18 I 26 6 8 [ 8] .rodata PROGBITS 0000000000000000 000098 009c98 00 A 0 0 8 [ 9] .rela.rodata RELA 0000000000000000 00aaa0 000030 18 I 26 8 8 [10] .init.text PROGBITS 0000000000000000 009d30 000068 00 AX 0 0 4 [11] .rela.init.text RELA 0000000000000000 00aad0 0000f0 18 I 26 10 8 [12] __patchable_function_entries PROGBITS 0000000000000000 009d98 000008 00 WAL 10 0 8 [13] .rela__patchable_function_entries RELA 0000000000000000 00abc0 000018 18 I 26 12 8 [14] .exit.text PROGBITS 0000000000000000 009da0 000028 00 AX 0 0 4 [15] .rela.exit.text RELA 0000000000000000 00abd8 000048 18 I 26 14 8 [16] .modinfo PROGBITS 0000000000000000 009dc8 0000b1 00 A 0 0 1 [17] .rodata.str1.1 PROGBITS 0000000000000000 009e79 00000a 01 AMS 0 0 1 [18] .comment PROGBITS 0000000000000000 009e83 0000ce 01 MS 0 0 1 [19] .note.Linux NOTE 0000000000000000 009f54 000018 00 A 0 0 4 [20] .gnu.linkonce.this_module PROGBITS 0000000000000000 009f80 000380 00 WA 0 0 64 [21] .rela.gnu.linkonce.this_module RELA 0000000000000000 00ac20 000030 18 I 26 20 8 [22] .note.gnu.build-id NOTE 0000000000000000 00a300 000024 00 A 0 0 4 [23] .note.gnu.property NOTE 0000000000000000 00a328 000020 00 A 0 0 8 [24] .note.GNU-stack PROGBITS 0000000000000000 00a348 000000 00 0 0 1 [25] .gnu_debuglink PROGBITS 0000000000000000 00a348 000018 00 0 0 4 [26] .symtab SYMTAB 0000000000000000 00a360 0004f8 18 27 43 8 [27] .strtab STRTAB 0000000000000000 00a858 0001b1 00 0 0 1 [28] .shstrtab STRTAB 0000000000000000 00ac50 000128 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific) After: $ readelf -WS configs.ko There are 26 section headers, starting at offset 0xad40: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] __patchable_function_entries PROGBITS 0000000000000000 000040 000010 00 WAL 5 0 8 [ 2] .rela__patchable_function_entries RELA 0000000000000000 00a9e0 000030 18 I 23 1 8 [ 3] .rodata PROGBITS 0000000000000000 000050 009ca2 00 AMS 0 0 8 [ 4] .rela.rodata RELA 0000000000000000 00aa10 000030 18 I 23 3 8 [ 5] .text PROGBITS 0000000000000000 009cf4 00004c 00 AX 0 0 4 [ 6] .rela.text RELA 0000000000000000 00aa40 000078 18 I 23 5 8 [ 7] .plt NOBITS 0000000000000000 009d40 000001 00 AX 0 0 16 [ 8] .init.plt NOBITS 0000000000000000 009d40 000001 00 AX 0 0 1 [ 9] .text.ftrace_trampoline NOBITS 0000000000000000 009d40 000001 00 AX 0 0 1 [10] .init.text PROGBITS 0000000000000000 009d40 000068 00 AX 0 0 4 [11] .rela.init.text RELA 0000000000000000 00aab8 0000f0 18 I 23 10 8 [12] .exit.text PROGBITS 0000000000000000 009da8 000028 00 AX 0 0 4 [13] .rela.exit.text RELA 0000000000000000 00aba8 000048 18 I 23 12 8 [14] .modinfo PROGBITS 0000000000000000 009dd0 0000b1 00 A 0 0 1 [15] .comment PROGBITS 0000000000000000 009e81 0000ce 01 MS 0 0 1 [16] .note.Linux NOTE 0000000000000000 009f50 000018 00 A 0 0 4 [17] .gnu.linkonce.this_module PROGBITS 0000000000000000 009f80 000380 00 WA 0 0 64 [18] .rela.gnu.linkonce.this_module RELA 0000000000000000 00abf0 000030 18 I 23 17 8 [19] .note.gnu.build-id NOTE 0000000000000000 00a300 000024 00 A 0 0 4 [20] .note.gnu.property NOTE 0000000000000000 00a328 000020 00 A 0 0 8 [21] .note.GNU-stack PROGBITS 0000000000000000 00a348 000000 00 0 0 1 [22] .gnu_debuglink PROGBITS 0000000000000000 00a348 000018 00 0 0 4 [23] .symtab SYMTAB 0000000000000000 00a360 0004c8 18 24 41 8 [24] .strtab STRTAB 0000000000000000 00a828 0001b1 00 0 0 1 [25] .shstrtab STRTAB 0000000000000000 00ac20 000119 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific) > scripts/module.lds.S | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/scripts/module.lds.S b/scripts/module.lds.S > index 69b9b71a6a47..18d5b8423635 100644 > --- a/scripts/module.lds.S > +++ b/scripts/module.lds.S > @@ -23,6 +23,30 @@ SECTIONS { > .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } > > __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } > + > + __patchable_function_entries : { *(__patchable_function_entries) } > + > + /* > + * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and > + * -ffunction-sections, which increases the size of the final module. > + * Merge the split sections in the final binary. > + */ > + .bss : { > + *(.bss .bss.[0-9a-zA-Z_]*) > + *(.bss..L*) > + } > + > + .data : { > + *(.data .data.[0-9a-zA-Z_]*) > + *(.data..L*) > + } > + > + .rodata : { > + *(.rodata .rodata.[0-9a-zA-Z_]*) > + *(.rodata..L*) > + } > + > + .text : { *(.text .text.[0-9a-zA-Z_]*) } > } >