Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  Kernel module help for s390.
0004  *
0005  *  S390 version
0006  *    Copyright IBM Corp. 2002, 2003
0007  *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
0008  *       Martin Schwidefsky (schwidefsky@de.ibm.com)
0009  *
0010  *  based on i386 version
0011  *    Copyright (C) 2001 Rusty Russell.
0012  */
0013 #include <linux/module.h>
0014 #include <linux/elf.h>
0015 #include <linux/vmalloc.h>
0016 #include <linux/fs.h>
0017 #include <linux/ftrace.h>
0018 #include <linux/string.h>
0019 #include <linux/kernel.h>
0020 #include <linux/kasan.h>
0021 #include <linux/moduleloader.h>
0022 #include <linux/bug.h>
0023 #include <linux/memory.h>
0024 #include <asm/alternative.h>
0025 #include <asm/nospec-branch.h>
0026 #include <asm/facility.h>
0027 #include <asm/ftrace.lds.h>
0028 #include <asm/set_memory.h>
0029 
0030 #if 0
0031 #define DEBUGP printk
0032 #else
0033 #define DEBUGP(fmt , ...)
0034 #endif
0035 
0036 #define PLT_ENTRY_SIZE 22
0037 
0038 void *module_alloc(unsigned long size)
0039 {
0040     gfp_t gfp_mask = GFP_KERNEL;
0041     void *p;
0042 
0043     if (PAGE_ALIGN(size) > MODULES_LEN)
0044         return NULL;
0045     p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
0046                  gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
0047                  __builtin_return_address(0));
0048     if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
0049         vfree(p);
0050         return NULL;
0051     }
0052     return p;
0053 }
0054 
0055 #ifdef CONFIG_FUNCTION_TRACER
0056 void module_arch_cleanup(struct module *mod)
0057 {
0058     module_memfree(mod->arch.trampolines_start);
0059 }
0060 #endif
0061 
0062 void module_arch_freeing_init(struct module *mod)
0063 {
0064     if (is_livepatch_module(mod) &&
0065         mod->state == MODULE_STATE_LIVE)
0066         return;
0067 
0068     vfree(mod->arch.syminfo);
0069     mod->arch.syminfo = NULL;
0070 }
0071 
0072 static void check_rela(Elf_Rela *rela, struct module *me)
0073 {
0074     struct mod_arch_syminfo *info;
0075 
0076     info = me->arch.syminfo + ELF_R_SYM (rela->r_info);
0077     switch (ELF_R_TYPE (rela->r_info)) {
0078     case R_390_GOT12:   /* 12 bit GOT offset.  */
0079     case R_390_GOT16:   /* 16 bit GOT offset.  */
0080     case R_390_GOT20:   /* 20 bit GOT offset.  */
0081     case R_390_GOT32:   /* 32 bit GOT offset.  */
0082     case R_390_GOT64:   /* 64 bit GOT offset.  */
0083     case R_390_GOTENT:  /* 32 bit PC rel. to GOT entry shifted by 1. */
0084     case R_390_GOTPLT12:    /* 12 bit offset to jump slot.  */
0085     case R_390_GOTPLT16:    /* 16 bit offset to jump slot.  */
0086     case R_390_GOTPLT20:    /* 20 bit offset to jump slot.  */
0087     case R_390_GOTPLT32:    /* 32 bit offset to jump slot.  */
0088     case R_390_GOTPLT64:    /* 64 bit offset to jump slot.  */
0089     case R_390_GOTPLTENT:   /* 32 bit rel. offset to jump slot >> 1. */
0090         if (info->got_offset == -1UL) {
0091             info->got_offset = me->arch.got_size;
0092             me->arch.got_size += sizeof(void*);
0093         }
0094         break;
0095     case R_390_PLT16DBL:    /* 16 bit PC rel. PLT shifted by 1.  */
0096     case R_390_PLT32DBL:    /* 32 bit PC rel. PLT shifted by 1.  */
0097     case R_390_PLT32:   /* 32 bit PC relative PLT address.  */
0098     case R_390_PLT64:   /* 64 bit PC relative PLT address.  */
0099     case R_390_PLTOFF16:    /* 16 bit offset from GOT to PLT. */
0100     case R_390_PLTOFF32:    /* 32 bit offset from GOT to PLT. */
0101     case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
0102         if (info->plt_offset == -1UL) {
0103             info->plt_offset = me->arch.plt_size;
0104             me->arch.plt_size += PLT_ENTRY_SIZE;
0105         }
0106         break;
0107     case R_390_COPY:
0108     case R_390_GLOB_DAT:
0109     case R_390_JMP_SLOT:
0110     case R_390_RELATIVE:
0111         /* Only needed if we want to support loading of 
0112            modules linked with -shared. */
0113         break;
0114     }
0115 }
0116 
0117 /*
0118  * Account for GOT and PLT relocations. We can't add sections for
0119  * got and plt but we can increase the core module size.
0120  */
0121 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
0122                   char *secstrings, struct module *me)
0123 {
0124     Elf_Shdr *symtab;
0125     Elf_Sym *symbols;
0126     Elf_Rela *rela;
0127     char *strings;
0128     int nrela, i, j;
0129 
0130     /* Find symbol table and string table. */
0131     symtab = NULL;
0132     for (i = 0; i < hdr->e_shnum; i++)
0133         switch (sechdrs[i].sh_type) {
0134         case SHT_SYMTAB:
0135             symtab = sechdrs + i;
0136             break;
0137         }
0138     if (!symtab) {
0139         printk(KERN_ERR "module %s: no symbol table\n", me->name);
0140         return -ENOEXEC;
0141     }
0142 
0143     /* Allocate one syminfo structure per symbol. */
0144     me->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym);
0145     me->arch.syminfo = vmalloc(array_size(sizeof(struct mod_arch_syminfo),
0146                           me->arch.nsyms));
0147     if (!me->arch.syminfo)
0148         return -ENOMEM;
0149     symbols = (void *) hdr + symtab->sh_offset;
0150     strings = (void *) hdr + sechdrs[symtab->sh_link].sh_offset;
0151     for (i = 0; i < me->arch.nsyms; i++) {
0152         if (symbols[i].st_shndx == SHN_UNDEF &&
0153             strcmp(strings + symbols[i].st_name,
0154                "_GLOBAL_OFFSET_TABLE_") == 0)
0155             /* "Define" it as absolute. */
0156             symbols[i].st_shndx = SHN_ABS;
0157         me->arch.syminfo[i].got_offset = -1UL;
0158         me->arch.syminfo[i].plt_offset = -1UL;
0159         me->arch.syminfo[i].got_initialized = 0;
0160         me->arch.syminfo[i].plt_initialized = 0;
0161     }
0162 
0163     /* Search for got/plt relocations. */
0164     me->arch.got_size = me->arch.plt_size = 0;
0165     for (i = 0; i < hdr->e_shnum; i++) {
0166         if (sechdrs[i].sh_type != SHT_RELA)
0167             continue;
0168         nrela = sechdrs[i].sh_size / sizeof(Elf_Rela);
0169         rela = (void *) hdr + sechdrs[i].sh_offset;
0170         for (j = 0; j < nrela; j++)
0171             check_rela(rela + j, me);
0172     }
0173 
0174     /* Increase core size by size of got & plt and set start
0175        offsets for got and plt. */
0176     me->core_layout.size = ALIGN(me->core_layout.size, 4);
0177     me->arch.got_offset = me->core_layout.size;
0178     me->core_layout.size += me->arch.got_size;
0179     me->arch.plt_offset = me->core_layout.size;
0180     if (me->arch.plt_size) {
0181         if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
0182             me->arch.plt_size += PLT_ENTRY_SIZE;
0183         me->core_layout.size += me->arch.plt_size;
0184     }
0185     return 0;
0186 }
0187 
0188 static int apply_rela_bits(Elf_Addr loc, Elf_Addr val,
0189                int sign, int bits, int shift,
0190                void *(*write)(void *dest, const void *src, size_t len))
0191 {
0192     unsigned long umax;
0193     long min, max;
0194     void *dest = (void *)loc;
0195 
0196     if (val & ((1UL << shift) - 1))
0197         return -ENOEXEC;
0198     if (sign) {
0199         val = (Elf_Addr)(((long) val) >> shift);
0200         min = -(1L << (bits - 1));
0201         max = (1L << (bits - 1)) - 1;
0202         if ((long) val < min || (long) val > max)
0203             return -ENOEXEC;
0204     } else {
0205         val >>= shift;
0206         umax = ((1UL << (bits - 1)) << 1) - 1;
0207         if ((unsigned long) val > umax)
0208             return -ENOEXEC;
0209     }
0210 
0211     if (bits == 8) {
0212         unsigned char tmp = val;
0213         write(dest, &tmp, 1);
0214     } else if (bits == 12) {
0215         unsigned short tmp = (val & 0xfff) |
0216             (*(unsigned short *) loc & 0xf000);
0217         write(dest, &tmp, 2);
0218     } else if (bits == 16) {
0219         unsigned short tmp = val;
0220         write(dest, &tmp, 2);
0221     } else if (bits == 20) {
0222         unsigned int tmp = (val & 0xfff) << 16 |
0223             (val & 0xff000) >> 4 | (*(unsigned int *) loc & 0xf00000ff);
0224         write(dest, &tmp, 4);
0225     } else if (bits == 32) {
0226         unsigned int tmp = val;
0227         write(dest, &tmp, 4);
0228     } else if (bits == 64) {
0229         unsigned long tmp = val;
0230         write(dest, &tmp, 8);
0231     }
0232     return 0;
0233 }
0234 
0235 static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
0236               const char *strtab, struct module *me,
0237               void *(*write)(void *dest, const void *src, size_t len))
0238 {
0239     struct mod_arch_syminfo *info;
0240     Elf_Addr loc, val;
0241     int r_type, r_sym;
0242     int rc = -ENOEXEC;
0243 
0244     /* This is where to make the change */
0245     loc = base + rela->r_offset;
0246     /* This is the symbol it is referring to.  Note that all
0247        undefined symbols have been resolved.  */
0248     r_sym = ELF_R_SYM(rela->r_info);
0249     r_type = ELF_R_TYPE(rela->r_info);
0250     info = me->arch.syminfo + r_sym;
0251     val = symtab[r_sym].st_value;
0252 
0253     switch (r_type) {
0254     case R_390_NONE:    /* No relocation.  */
0255         rc = 0;
0256         break;
0257     case R_390_8:       /* Direct 8 bit.   */
0258     case R_390_12:      /* Direct 12 bit.  */
0259     case R_390_16:      /* Direct 16 bit.  */
0260     case R_390_20:      /* Direct 20 bit.  */
0261     case R_390_32:      /* Direct 32 bit.  */
0262     case R_390_64:      /* Direct 64 bit.  */
0263         val += rela->r_addend;
0264         if (r_type == R_390_8)
0265             rc = apply_rela_bits(loc, val, 0, 8, 0, write);
0266         else if (r_type == R_390_12)
0267             rc = apply_rela_bits(loc, val, 0, 12, 0, write);
0268         else if (r_type == R_390_16)
0269             rc = apply_rela_bits(loc, val, 0, 16, 0, write);
0270         else if (r_type == R_390_20)
0271             rc = apply_rela_bits(loc, val, 1, 20, 0, write);
0272         else if (r_type == R_390_32)
0273             rc = apply_rela_bits(loc, val, 0, 32, 0, write);
0274         else if (r_type == R_390_64)
0275             rc = apply_rela_bits(loc, val, 0, 64, 0, write);
0276         break;
0277     case R_390_PC16:    /* PC relative 16 bit.  */
0278     case R_390_PC16DBL: /* PC relative 16 bit shifted by 1.  */
0279     case R_390_PC32DBL: /* PC relative 32 bit shifted by 1.  */
0280     case R_390_PC32:    /* PC relative 32 bit.  */
0281     case R_390_PC64:    /* PC relative 64 bit.  */
0282         val += rela->r_addend - loc;
0283         if (r_type == R_390_PC16)
0284             rc = apply_rela_bits(loc, val, 1, 16, 0, write);
0285         else if (r_type == R_390_PC16DBL)
0286             rc = apply_rela_bits(loc, val, 1, 16, 1, write);
0287         else if (r_type == R_390_PC32DBL)
0288             rc = apply_rela_bits(loc, val, 1, 32, 1, write);
0289         else if (r_type == R_390_PC32)
0290             rc = apply_rela_bits(loc, val, 1, 32, 0, write);
0291         else if (r_type == R_390_PC64)
0292             rc = apply_rela_bits(loc, val, 1, 64, 0, write);
0293         break;
0294     case R_390_GOT12:   /* 12 bit GOT offset.  */
0295     case R_390_GOT16:   /* 16 bit GOT offset.  */
0296     case R_390_GOT20:   /* 20 bit GOT offset.  */
0297     case R_390_GOT32:   /* 32 bit GOT offset.  */
0298     case R_390_GOT64:   /* 64 bit GOT offset.  */
0299     case R_390_GOTENT:  /* 32 bit PC rel. to GOT entry shifted by 1. */
0300     case R_390_GOTPLT12:    /* 12 bit offset to jump slot.  */
0301     case R_390_GOTPLT20:    /* 20 bit offset to jump slot.  */
0302     case R_390_GOTPLT16:    /* 16 bit offset to jump slot.  */
0303     case R_390_GOTPLT32:    /* 32 bit offset to jump slot.  */
0304     case R_390_GOTPLT64:    /* 64 bit offset to jump slot.  */
0305     case R_390_GOTPLTENT:   /* 32 bit rel. offset to jump slot >> 1. */
0306         if (info->got_initialized == 0) {
0307             Elf_Addr *gotent = me->core_layout.base +
0308                        me->arch.got_offset +
0309                        info->got_offset;
0310 
0311             write(gotent, &val, sizeof(*gotent));
0312             info->got_initialized = 1;
0313         }
0314         val = info->got_offset + rela->r_addend;
0315         if (r_type == R_390_GOT12 ||
0316             r_type == R_390_GOTPLT12)
0317             rc = apply_rela_bits(loc, val, 0, 12, 0, write);
0318         else if (r_type == R_390_GOT16 ||
0319              r_type == R_390_GOTPLT16)
0320             rc = apply_rela_bits(loc, val, 0, 16, 0, write);
0321         else if (r_type == R_390_GOT20 ||
0322              r_type == R_390_GOTPLT20)
0323             rc = apply_rela_bits(loc, val, 1, 20, 0, write);
0324         else if (r_type == R_390_GOT32 ||
0325              r_type == R_390_GOTPLT32)
0326             rc = apply_rela_bits(loc, val, 0, 32, 0, write);
0327         else if (r_type == R_390_GOT64 ||
0328              r_type == R_390_GOTPLT64)
0329             rc = apply_rela_bits(loc, val, 0, 64, 0, write);
0330         else if (r_type == R_390_GOTENT ||
0331              r_type == R_390_GOTPLTENT) {
0332             val += (Elf_Addr) me->core_layout.base - loc;
0333             rc = apply_rela_bits(loc, val, 1, 32, 1, write);
0334         }
0335         break;
0336     case R_390_PLT16DBL:    /* 16 bit PC rel. PLT shifted by 1.  */
0337     case R_390_PLT32DBL:    /* 32 bit PC rel. PLT shifted by 1.  */
0338     case R_390_PLT32:   /* 32 bit PC relative PLT address.  */
0339     case R_390_PLT64:   /* 64 bit PC relative PLT address.  */
0340     case R_390_PLTOFF16:    /* 16 bit offset from GOT to PLT. */
0341     case R_390_PLTOFF32:    /* 32 bit offset from GOT to PLT. */
0342     case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
0343         if (info->plt_initialized == 0) {
0344             unsigned char insn[PLT_ENTRY_SIZE];
0345             char *plt_base;
0346             char *ip;
0347 
0348             plt_base = me->core_layout.base + me->arch.plt_offset;
0349             ip = plt_base + info->plt_offset;
0350             *(int *)insn = 0x0d10e310;  /* basr 1,0  */
0351             *(int *)&insn[4] = 0x100c0004;  /* lg   1,12(1) */
0352             if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
0353                 char *jump_r1;
0354 
0355                 jump_r1 = plt_base + me->arch.plt_size -
0356                     PLT_ENTRY_SIZE;
0357                 /* brcl 0xf,__jump_r1 */
0358                 *(short *)&insn[8] = 0xc0f4;
0359                 *(int *)&insn[10] = (jump_r1 - (ip + 8)) / 2;
0360             } else {
0361                 *(int *)&insn[8] = 0x07f10000;  /* br %r1 */
0362             }
0363             *(long *)&insn[14] = val;
0364 
0365             write(ip, insn, sizeof(insn));
0366             info->plt_initialized = 1;
0367         }
0368         if (r_type == R_390_PLTOFF16 ||
0369             r_type == R_390_PLTOFF32 ||
0370             r_type == R_390_PLTOFF64)
0371             val = me->arch.plt_offset - me->arch.got_offset +
0372                 info->plt_offset + rela->r_addend;
0373         else {
0374             if (!((r_type == R_390_PLT16DBL &&
0375                    val - loc + 0xffffUL < 0x1ffffeUL) ||
0376                   (r_type == R_390_PLT32DBL &&
0377                    val - loc + 0xffffffffULL < 0x1fffffffeULL)))
0378                 val = (Elf_Addr) me->core_layout.base +
0379                     me->arch.plt_offset +
0380                     info->plt_offset;
0381             val += rela->r_addend - loc;
0382         }
0383         if (r_type == R_390_PLT16DBL)
0384             rc = apply_rela_bits(loc, val, 1, 16, 1, write);
0385         else if (r_type == R_390_PLTOFF16)
0386             rc = apply_rela_bits(loc, val, 0, 16, 0, write);
0387         else if (r_type == R_390_PLT32DBL)
0388             rc = apply_rela_bits(loc, val, 1, 32, 1, write);
0389         else if (r_type == R_390_PLT32 ||
0390              r_type == R_390_PLTOFF32)
0391             rc = apply_rela_bits(loc, val, 0, 32, 0, write);
0392         else if (r_type == R_390_PLT64 ||
0393              r_type == R_390_PLTOFF64)
0394             rc = apply_rela_bits(loc, val, 0, 64, 0, write);
0395         break;
0396     case R_390_GOTOFF16:    /* 16 bit offset to GOT.  */
0397     case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
0398     case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
0399         val = val + rela->r_addend -
0400             ((Elf_Addr) me->core_layout.base + me->arch.got_offset);
0401         if (r_type == R_390_GOTOFF16)
0402             rc = apply_rela_bits(loc, val, 0, 16, 0, write);
0403         else if (r_type == R_390_GOTOFF32)
0404             rc = apply_rela_bits(loc, val, 0, 32, 0, write);
0405         else if (r_type == R_390_GOTOFF64)
0406             rc = apply_rela_bits(loc, val, 0, 64, 0, write);
0407         break;
0408     case R_390_GOTPC:   /* 32 bit PC relative offset to GOT. */
0409     case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
0410         val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
0411             rela->r_addend - loc;
0412         if (r_type == R_390_GOTPC)
0413             rc = apply_rela_bits(loc, val, 1, 32, 0, write);
0414         else if (r_type == R_390_GOTPCDBL)
0415             rc = apply_rela_bits(loc, val, 1, 32, 1, write);
0416         break;
0417     case R_390_COPY:
0418     case R_390_GLOB_DAT:    /* Create GOT entry.  */
0419     case R_390_JMP_SLOT:    /* Create PLT entry.  */
0420     case R_390_RELATIVE:    /* Adjust by program base.  */
0421         /* Only needed if we want to support loading of 
0422            modules linked with -shared. */
0423         return -ENOEXEC;
0424     default:
0425         printk(KERN_ERR "module %s: unknown relocation: %u\n",
0426                me->name, r_type);
0427         return -ENOEXEC;
0428     }
0429     if (rc) {
0430         printk(KERN_ERR "module %s: relocation error for symbol %s "
0431                "(r_type %i, value 0x%lx)\n",
0432                me->name, strtab + symtab[r_sym].st_name,
0433                r_type, (unsigned long) val);
0434         return rc;
0435     }
0436     return 0;
0437 }
0438 
0439 static int __apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
0440                unsigned int symindex, unsigned int relsec,
0441                struct module *me,
0442                void *(*write)(void *dest, const void *src, size_t len))
0443 {
0444     Elf_Addr base;
0445     Elf_Sym *symtab;
0446     Elf_Rela *rela;
0447     unsigned long i, n;
0448     int rc;
0449 
0450     DEBUGP("Applying relocate section %u to %u\n",
0451            relsec, sechdrs[relsec].sh_info);
0452     base = sechdrs[sechdrs[relsec].sh_info].sh_addr;
0453     symtab = (Elf_Sym *) sechdrs[symindex].sh_addr;
0454     rela = (Elf_Rela *) sechdrs[relsec].sh_addr;
0455     n = sechdrs[relsec].sh_size / sizeof(Elf_Rela);
0456 
0457     for (i = 0; i < n; i++, rela++) {
0458         rc = apply_rela(rela, base, symtab, strtab, me, write);
0459         if (rc)
0460             return rc;
0461     }
0462     return 0;
0463 }
0464 
0465 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
0466                unsigned int symindex, unsigned int relsec,
0467                struct module *me)
0468 {
0469     bool early = me->state == MODULE_STATE_UNFORMED;
0470     void *(*write)(void *, const void *, size_t) = memcpy;
0471 
0472     if (!early)
0473         write = s390_kernel_write;
0474 
0475     return __apply_relocate_add(sechdrs, strtab, symindex, relsec, me,
0476                     write);
0477 }
0478 
0479 #ifdef CONFIG_FUNCTION_TRACER
0480 static int module_alloc_ftrace_hotpatch_trampolines(struct module *me,
0481                             const Elf_Shdr *s)
0482 {
0483     char *start, *end;
0484     int numpages;
0485     size_t size;
0486 
0487     size = FTRACE_HOTPATCH_TRAMPOLINES_SIZE(s->sh_size);
0488     numpages = DIV_ROUND_UP(size, PAGE_SIZE);
0489     start = module_alloc(numpages * PAGE_SIZE);
0490     if (!start)
0491         return -ENOMEM;
0492     set_memory_ro((unsigned long)start, numpages);
0493     end = start + size;
0494 
0495     me->arch.trampolines_start = (struct ftrace_hotpatch_trampoline *)start;
0496     me->arch.trampolines_end = (struct ftrace_hotpatch_trampoline *)end;
0497     me->arch.next_trampoline = me->arch.trampolines_start;
0498 
0499     return 0;
0500 }
0501 #endif /* CONFIG_FUNCTION_TRACER */
0502 
0503 int module_finalize(const Elf_Ehdr *hdr,
0504             const Elf_Shdr *sechdrs,
0505             struct module *me)
0506 {
0507     const Elf_Shdr *s;
0508     char *secstrings, *secname;
0509     void *aseg;
0510 #ifdef CONFIG_FUNCTION_TRACER
0511     int ret;
0512 #endif
0513 
0514     if (IS_ENABLED(CONFIG_EXPOLINE) &&
0515         !nospec_disable && me->arch.plt_size) {
0516         unsigned int *ij;
0517 
0518         ij = me->core_layout.base + me->arch.plt_offset +
0519             me->arch.plt_size - PLT_ENTRY_SIZE;
0520         ij[0] = 0xc6000000; /* exrl %r0,.+10    */
0521         ij[1] = 0x0005a7f4; /* j    .       */
0522         ij[2] = 0x000007f1; /* br   %r1     */
0523     }
0524 
0525     secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
0526     for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
0527         aseg = (void *) s->sh_addr;
0528         secname = secstrings + s->sh_name;
0529 
0530         if (!strcmp(".altinstructions", secname))
0531             /* patch .altinstructions */
0532             apply_alternatives(aseg, aseg + s->sh_size);
0533 
0534         if (IS_ENABLED(CONFIG_EXPOLINE) &&
0535             (str_has_prefix(secname, ".s390_indirect")))
0536             nospec_revert(aseg, aseg + s->sh_size);
0537 
0538         if (IS_ENABLED(CONFIG_EXPOLINE) &&
0539             (str_has_prefix(secname, ".s390_return")))
0540             nospec_revert(aseg, aseg + s->sh_size);
0541 
0542 #ifdef CONFIG_FUNCTION_TRACER
0543         if (!strcmp(FTRACE_CALLSITE_SECTION, secname)) {
0544             ret = module_alloc_ftrace_hotpatch_trampolines(me, s);
0545             if (ret < 0)
0546                 return ret;
0547         }
0548 #endif /* CONFIG_FUNCTION_TRACER */
0549     }
0550 
0551     return 0;
0552 }