FAILED: patch "[PATCH] s390/module: fix loading modules with a lot of relocations" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f3b7e73b2c6619884351a3a0a7468642f852b8a2 Mon Sep 17 00:00:00 2001
From: Ilya Leoshkevich <[email protected]>
Date: Wed, 19 Jan 2022 19:26:37 +0100
Subject: [PATCH] s390/module: fix loading modules with a lot of relocations
If the size of the PLT entries generated by apply_rela() exceeds 64KiB, the first ones can no longer reach __jump_r1 with brc. Fix by using brcl. An alternative solution is to add a __jump_r1 copy after every 64KiB, however, the space savings are quite small and do not justify the additional complexity.
arch/s390/kernel/module.c +18 -19
@@ -33,7 +33,7 @@#define DEBUGP (fmt , ...)#endif -#define PLT_ENTRY_SIZE 20 +#define PLT_ENTRY_SIZE 22void *module_alloc (unsigned long size) {
@@ -341,27 +341,26 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,case R_390_PLTOFF32 :/* 32 bit offset from GOT to PLT. */ case R_390_PLTOFF64 :/* 16 bit offset from GOT to PLT. */ if (info->plt_initialized ==0 ) { -unsigned int insn[5 ]; -unsigned int *ip = me->core_layout.base + - me->arch.plt_offset + - info->plt_offset; - - insn[0 ] =0x0d10e310 ;/* basr 1,0 */ - insn[1 ] =0x100a0004 ;/* lg 1,10(1) */ +unsigned char insn[PLT_ENTRY_SIZE ]; +char *plt_base; +char *ip; + + plt_base = me->core_layout.base + me->arch.plt_offset; + ip = plt_base + info->plt_offset; + *(int *)insn =0x0d10e310 ;/* basr 1,0 */ + *(int *)&insn[4 ] =0x100c0004 ;/* lg 1,12(1) */ if (IS_ENABLED (CONFIG_EXPOLINE ) && !nospec_disable) { -unsigned int *ij; - ij = me->core_layout.base + - me->arch.plt_offset + - me->arch.plt_size -PLT_ENTRY_SIZE ; - insn[2 ] =0xa7f40000 +/* j __jump_r1 */ - (unsigned int )(u16) - (((unsigned long ) ij -8 - - (unsigned long ) ip) /2 ); +char *jump_r1; + + jump_r1 = plt_base + me->arch.plt_size - +PLT_ENTRY_SIZE ; +/* brcl 0xf,__jump_r1 */ + *(short *)&insn[8 ] =0xc0f4 ; + *(int *)&insn[10 ] = (jump_r1 - (ip +8 )) /2 ; }else { - insn[2 ] =0x07f10000 ;/* br %r1 */ + *(int *)&insn[8 ] =0x07f10000 ;/* br %r1 */ } - insn[3 ] = (unsigned int ) (val >>32 ); - insn[4 ] = (unsigned int ) val; + *(long *)&insn[14 ] = val;write (ip, insn,sizeof (insn)); info->plt_initialized =1 ;