GNU Linux-libre 4.19.286-gnu1
[releases.git] / arch / s390 / kernel / module.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Kernel module help for s390.
4  *
5  *  S390 version
6  *    Copyright IBM Corp. 2002, 2003
7  *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
8  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
9  *
10  *  based on i386 version
11  *    Copyright (C) 2001 Rusty Russell.
12  */
13 #include <linux/module.h>
14 #include <linux/elf.h>
15 #include <linux/vmalloc.h>
16 #include <linux/fs.h>
17 #include <linux/string.h>
18 #include <linux/kernel.h>
19 #include <linux/moduleloader.h>
20 #include <linux/bug.h>
21 #include <asm/alternative.h>
22 #include <asm/nospec-branch.h>
23 #include <asm/facility.h>
24
25 #if 0
26 #define DEBUGP printk
27 #else
28 #define DEBUGP(fmt , ...)
29 #endif
30
31 #define PLT_ENTRY_SIZE 20
32
33 void *module_alloc(unsigned long size)
34 {
35         if (PAGE_ALIGN(size) > MODULES_LEN)
36                 return NULL;
37         return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
38                                     GFP_KERNEL, PAGE_KERNEL_EXEC,
39                                     0, NUMA_NO_NODE,
40                                     __builtin_return_address(0));
41 }
42
43 void module_arch_freeing_init(struct module *mod)
44 {
45         if (is_livepatch_module(mod) &&
46             mod->state == MODULE_STATE_LIVE)
47                 return;
48
49         vfree(mod->arch.syminfo);
50         mod->arch.syminfo = NULL;
51 }
52
53 static void check_rela(Elf_Rela *rela, struct module *me)
54 {
55         struct mod_arch_syminfo *info;
56
57         info = me->arch.syminfo + ELF_R_SYM (rela->r_info);
58         switch (ELF_R_TYPE (rela->r_info)) {
59         case R_390_GOT12:       /* 12 bit GOT offset.  */
60         case R_390_GOT16:       /* 16 bit GOT offset.  */
61         case R_390_GOT20:       /* 20 bit GOT offset.  */
62         case R_390_GOT32:       /* 32 bit GOT offset.  */
63         case R_390_GOT64:       /* 64 bit GOT offset.  */
64         case R_390_GOTENT:      /* 32 bit PC rel. to GOT entry shifted by 1. */
65         case R_390_GOTPLT12:    /* 12 bit offset to jump slot.  */
66         case R_390_GOTPLT16:    /* 16 bit offset to jump slot.  */
67         case R_390_GOTPLT20:    /* 20 bit offset to jump slot.  */
68         case R_390_GOTPLT32:    /* 32 bit offset to jump slot.  */
69         case R_390_GOTPLT64:    /* 64 bit offset to jump slot.  */
70         case R_390_GOTPLTENT:   /* 32 bit rel. offset to jump slot >> 1. */
71                 if (info->got_offset == -1UL) {
72                         info->got_offset = me->arch.got_size;
73                         me->arch.got_size += sizeof(void*);
74                 }
75                 break;
76         case R_390_PLT16DBL:    /* 16 bit PC rel. PLT shifted by 1.  */
77         case R_390_PLT32DBL:    /* 32 bit PC rel. PLT shifted by 1.  */
78         case R_390_PLT32:       /* 32 bit PC relative PLT address.  */
79         case R_390_PLT64:       /* 64 bit PC relative PLT address.  */
80         case R_390_PLTOFF16:    /* 16 bit offset from GOT to PLT. */
81         case R_390_PLTOFF32:    /* 32 bit offset from GOT to PLT. */
82         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
83                 if (info->plt_offset == -1UL) {
84                         info->plt_offset = me->arch.plt_size;
85                         me->arch.plt_size += PLT_ENTRY_SIZE;
86                 }
87                 break;
88         case R_390_COPY:
89         case R_390_GLOB_DAT:
90         case R_390_JMP_SLOT:
91         case R_390_RELATIVE:
92                 /* Only needed if we want to support loading of 
93                    modules linked with -shared. */
94                 break;
95         }
96 }
97
98 /*
99  * Account for GOT and PLT relocations. We can't add sections for
100  * got and plt but we can increase the core module size.
101  */
102 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
103                               char *secstrings, struct module *me)
104 {
105         Elf_Shdr *symtab;
106         Elf_Sym *symbols;
107         Elf_Rela *rela;
108         char *strings;
109         int nrela, i, j;
110
111         /* Find symbol table and string table. */
112         symtab = NULL;
113         for (i = 0; i < hdr->e_shnum; i++)
114                 switch (sechdrs[i].sh_type) {
115                 case SHT_SYMTAB:
116                         symtab = sechdrs + i;
117                         break;
118                 }
119         if (!symtab) {
120                 printk(KERN_ERR "module %s: no symbol table\n", me->name);
121                 return -ENOEXEC;
122         }
123
124         /* Allocate one syminfo structure per symbol. */
125         me->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym);
126         me->arch.syminfo = vmalloc(array_size(sizeof(struct mod_arch_syminfo),
127                                               me->arch.nsyms));
128         if (!me->arch.syminfo)
129                 return -ENOMEM;
130         symbols = (void *) hdr + symtab->sh_offset;
131         strings = (void *) hdr + sechdrs[symtab->sh_link].sh_offset;
132         for (i = 0; i < me->arch.nsyms; i++) {
133                 if (symbols[i].st_shndx == SHN_UNDEF &&
134                     strcmp(strings + symbols[i].st_name,
135                            "_GLOBAL_OFFSET_TABLE_") == 0)
136                         /* "Define" it as absolute. */
137                         symbols[i].st_shndx = SHN_ABS;
138                 me->arch.syminfo[i].got_offset = -1UL;
139                 me->arch.syminfo[i].plt_offset = -1UL;
140                 me->arch.syminfo[i].got_initialized = 0;
141                 me->arch.syminfo[i].plt_initialized = 0;
142         }
143
144         /* Search for got/plt relocations. */
145         me->arch.got_size = me->arch.plt_size = 0;
146         for (i = 0; i < hdr->e_shnum; i++) {
147                 if (sechdrs[i].sh_type != SHT_RELA)
148                         continue;
149                 nrela = sechdrs[i].sh_size / sizeof(Elf_Rela);
150                 rela = (void *) hdr + sechdrs[i].sh_offset;
151                 for (j = 0; j < nrela; j++)
152                         check_rela(rela + j, me);
153         }
154
155         /* Increase core size by size of got & plt and set start
156            offsets for got and plt. */
157         me->core_layout.size = ALIGN(me->core_layout.size, 4);
158         me->arch.got_offset = me->core_layout.size;
159         me->core_layout.size += me->arch.got_size;
160         me->arch.plt_offset = me->core_layout.size;
161         if (me->arch.plt_size) {
162                 if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
163                         me->arch.plt_size += PLT_ENTRY_SIZE;
164                 me->core_layout.size += me->arch.plt_size;
165         }
166         return 0;
167 }
168
169 static int apply_rela_bits(Elf_Addr loc, Elf_Addr val,
170                            int sign, int bits, int shift)
171 {
172         unsigned long umax;
173         long min, max;
174
175         if (val & ((1UL << shift) - 1))
176                 return -ENOEXEC;
177         if (sign) {
178                 val = (Elf_Addr)(((long) val) >> shift);
179                 min = -(1L << (bits - 1));
180                 max = (1L << (bits - 1)) - 1;
181                 if ((long) val < min || (long) val > max)
182                         return -ENOEXEC;
183         } else {
184                 val >>= shift;
185                 umax = ((1UL << (bits - 1)) << 1) - 1;
186                 if ((unsigned long) val > umax)
187                         return -ENOEXEC;
188         }
189
190         if (bits == 8)
191                 *(unsigned char *) loc = val;
192         else if (bits == 12)
193                 *(unsigned short *) loc = (val & 0xfff) |
194                         (*(unsigned short *) loc & 0xf000);
195         else if (bits == 16)
196                 *(unsigned short *) loc = val;
197         else if (bits == 20)
198                 *(unsigned int *) loc = (val & 0xfff) << 16 |
199                         (val & 0xff000) >> 4 |
200                         (*(unsigned int *) loc & 0xf00000ff);
201         else if (bits == 32)
202                 *(unsigned int *) loc = val;
203         else if (bits == 64)
204                 *(unsigned long *) loc = val;
205         return 0;
206 }
207
208 static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
209                       const char *strtab, struct module *me)
210 {
211         struct mod_arch_syminfo *info;
212         Elf_Addr loc, val;
213         int r_type, r_sym;
214         int rc = -ENOEXEC;
215
216         /* This is where to make the change */
217         loc = base + rela->r_offset;
218         /* This is the symbol it is referring to.  Note that all
219            undefined symbols have been resolved.  */
220         r_sym = ELF_R_SYM(rela->r_info);
221         r_type = ELF_R_TYPE(rela->r_info);
222         info = me->arch.syminfo + r_sym;
223         val = symtab[r_sym].st_value;
224
225         switch (r_type) {
226         case R_390_NONE:        /* No relocation.  */
227                 rc = 0;
228                 break;
229         case R_390_8:           /* Direct 8 bit.   */
230         case R_390_12:          /* Direct 12 bit.  */
231         case R_390_16:          /* Direct 16 bit.  */
232         case R_390_20:          /* Direct 20 bit.  */
233         case R_390_32:          /* Direct 32 bit.  */
234         case R_390_64:          /* Direct 64 bit.  */
235                 val += rela->r_addend;
236                 if (r_type == R_390_8)
237                         rc = apply_rela_bits(loc, val, 0, 8, 0);
238                 else if (r_type == R_390_12)
239                         rc = apply_rela_bits(loc, val, 0, 12, 0);
240                 else if (r_type == R_390_16)
241                         rc = apply_rela_bits(loc, val, 0, 16, 0);
242                 else if (r_type == R_390_20)
243                         rc = apply_rela_bits(loc, val, 1, 20, 0);
244                 else if (r_type == R_390_32)
245                         rc = apply_rela_bits(loc, val, 0, 32, 0);
246                 else if (r_type == R_390_64)
247                         rc = apply_rela_bits(loc, val, 0, 64, 0);
248                 break;
249         case R_390_PC16:        /* PC relative 16 bit.  */
250         case R_390_PC16DBL:     /* PC relative 16 bit shifted by 1.  */
251         case R_390_PC32DBL:     /* PC relative 32 bit shifted by 1.  */
252         case R_390_PC32:        /* PC relative 32 bit.  */
253         case R_390_PC64:        /* PC relative 64 bit.  */
254                 val += rela->r_addend - loc;
255                 if (r_type == R_390_PC16)
256                         rc = apply_rela_bits(loc, val, 1, 16, 0);
257                 else if (r_type == R_390_PC16DBL)
258                         rc = apply_rela_bits(loc, val, 1, 16, 1);
259                 else if (r_type == R_390_PC32DBL)
260                         rc = apply_rela_bits(loc, val, 1, 32, 1);
261                 else if (r_type == R_390_PC32)
262                         rc = apply_rela_bits(loc, val, 1, 32, 0);
263                 else if (r_type == R_390_PC64)
264                         rc = apply_rela_bits(loc, val, 1, 64, 0);
265                 break;
266         case R_390_GOT12:       /* 12 bit GOT offset.  */
267         case R_390_GOT16:       /* 16 bit GOT offset.  */
268         case R_390_GOT20:       /* 20 bit GOT offset.  */
269         case R_390_GOT32:       /* 32 bit GOT offset.  */
270         case R_390_GOT64:       /* 64 bit GOT offset.  */
271         case R_390_GOTENT:      /* 32 bit PC rel. to GOT entry shifted by 1. */
272         case R_390_GOTPLT12:    /* 12 bit offset to jump slot.  */
273         case R_390_GOTPLT20:    /* 20 bit offset to jump slot.  */
274         case R_390_GOTPLT16:    /* 16 bit offset to jump slot.  */
275         case R_390_GOTPLT32:    /* 32 bit offset to jump slot.  */
276         case R_390_GOTPLT64:    /* 64 bit offset to jump slot.  */
277         case R_390_GOTPLTENT:   /* 32 bit rel. offset to jump slot >> 1. */
278                 if (info->got_initialized == 0) {
279                         Elf_Addr *gotent;
280
281                         gotent = me->core_layout.base + me->arch.got_offset +
282                                 info->got_offset;
283                         *gotent = val;
284                         info->got_initialized = 1;
285                 }
286                 val = info->got_offset + rela->r_addend;
287                 if (r_type == R_390_GOT12 ||
288                     r_type == R_390_GOTPLT12)
289                         rc = apply_rela_bits(loc, val, 0, 12, 0);
290                 else if (r_type == R_390_GOT16 ||
291                          r_type == R_390_GOTPLT16)
292                         rc = apply_rela_bits(loc, val, 0, 16, 0);
293                 else if (r_type == R_390_GOT20 ||
294                          r_type == R_390_GOTPLT20)
295                         rc = apply_rela_bits(loc, val, 1, 20, 0);
296                 else if (r_type == R_390_GOT32 ||
297                          r_type == R_390_GOTPLT32)
298                         rc = apply_rela_bits(loc, val, 0, 32, 0);
299                 else if (r_type == R_390_GOT64 ||
300                          r_type == R_390_GOTPLT64)
301                         rc = apply_rela_bits(loc, val, 0, 64, 0);
302                 else if (r_type == R_390_GOTENT ||
303                          r_type == R_390_GOTPLTENT) {
304                         val += (Elf_Addr) me->core_layout.base - loc;
305                         rc = apply_rela_bits(loc, val, 1, 32, 1);
306                 }
307                 break;
308         case R_390_PLT16DBL:    /* 16 bit PC rel. PLT shifted by 1.  */
309         case R_390_PLT32DBL:    /* 32 bit PC rel. PLT shifted by 1.  */
310         case R_390_PLT32:       /* 32 bit PC relative PLT address.  */
311         case R_390_PLT64:       /* 64 bit PC relative PLT address.  */
312         case R_390_PLTOFF16:    /* 16 bit offset from GOT to PLT. */
313         case R_390_PLTOFF32:    /* 32 bit offset from GOT to PLT. */
314         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
315                 if (info->plt_initialized == 0) {
316                         unsigned int *ip;
317                         ip = me->core_layout.base + me->arch.plt_offset +
318                                 info->plt_offset;
319                         ip[0] = 0x0d10e310;     /* basr 1,0  */
320                         ip[1] = 0x100a0004;     /* lg   1,10(1) */
321                         if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
322                                 unsigned int *ij;
323                                 ij = me->core_layout.base +
324                                         me->arch.plt_offset +
325                                         me->arch.plt_size - PLT_ENTRY_SIZE;
326                                 ip[2] = 0xa7f40000 +    /* j __jump_r1 */
327                                         (unsigned int)(u16)
328                                         (((unsigned long) ij - 8 -
329                                           (unsigned long) ip) / 2);
330                         } else {
331                                 ip[2] = 0x07f10000;     /* br %r1 */
332                         }
333                         ip[3] = (unsigned int) (val >> 32);
334                         ip[4] = (unsigned int) val;
335                         info->plt_initialized = 1;
336                 }
337                 if (r_type == R_390_PLTOFF16 ||
338                     r_type == R_390_PLTOFF32 ||
339                     r_type == R_390_PLTOFF64)
340                         val = me->arch.plt_offset - me->arch.got_offset +
341                                 info->plt_offset + rela->r_addend;
342                 else {
343                         if (!((r_type == R_390_PLT16DBL &&
344                                val - loc + 0xffffUL < 0x1ffffeUL) ||
345                               (r_type == R_390_PLT32DBL &&
346                                val - loc + 0xffffffffULL < 0x1fffffffeULL)))
347                                 val = (Elf_Addr) me->core_layout.base +
348                                         me->arch.plt_offset +
349                                         info->plt_offset;
350                         val += rela->r_addend - loc;
351                 }
352                 if (r_type == R_390_PLT16DBL)
353                         rc = apply_rela_bits(loc, val, 1, 16, 1);
354                 else if (r_type == R_390_PLTOFF16)
355                         rc = apply_rela_bits(loc, val, 0, 16, 0);
356                 else if (r_type == R_390_PLT32DBL)
357                         rc = apply_rela_bits(loc, val, 1, 32, 1);
358                 else if (r_type == R_390_PLT32 ||
359                          r_type == R_390_PLTOFF32)
360                         rc = apply_rela_bits(loc, val, 0, 32, 0);
361                 else if (r_type == R_390_PLT64 ||
362                          r_type == R_390_PLTOFF64)
363                         rc = apply_rela_bits(loc, val, 0, 64, 0);
364                 break;
365         case R_390_GOTOFF16:    /* 16 bit offset to GOT.  */
366         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
367         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
368                 val = val + rela->r_addend -
369                         ((Elf_Addr) me->core_layout.base + me->arch.got_offset);
370                 if (r_type == R_390_GOTOFF16)
371                         rc = apply_rela_bits(loc, val, 0, 16, 0);
372                 else if (r_type == R_390_GOTOFF32)
373                         rc = apply_rela_bits(loc, val, 0, 32, 0);
374                 else if (r_type == R_390_GOTOFF64)
375                         rc = apply_rela_bits(loc, val, 0, 64, 0);
376                 break;
377         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
378         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
379                 val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
380                         rela->r_addend - loc;
381                 if (r_type == R_390_GOTPC)
382                         rc = apply_rela_bits(loc, val, 1, 32, 0);
383                 else if (r_type == R_390_GOTPCDBL)
384                         rc = apply_rela_bits(loc, val, 1, 32, 1);
385                 break;
386         case R_390_COPY:
387         case R_390_GLOB_DAT:    /* Create GOT entry.  */
388         case R_390_JMP_SLOT:    /* Create PLT entry.  */
389         case R_390_RELATIVE:    /* Adjust by program base.  */
390                 /* Only needed if we want to support loading of 
391                    modules linked with -shared. */
392                 return -ENOEXEC;
393         default:
394                 printk(KERN_ERR "module %s: unknown relocation: %u\n",
395                        me->name, r_type);
396                 return -ENOEXEC;
397         }
398         if (rc) {
399                 printk(KERN_ERR "module %s: relocation error for symbol %s "
400                        "(r_type %i, value 0x%lx)\n",
401                        me->name, strtab + symtab[r_sym].st_name,
402                        r_type, (unsigned long) val);
403                 return rc;
404         }
405         return 0;
406 }
407
408 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
409                        unsigned int symindex, unsigned int relsec,
410                        struct module *me)
411 {
412         Elf_Addr base;
413         Elf_Sym *symtab;
414         Elf_Rela *rela;
415         unsigned long i, n;
416         int rc;
417
418         DEBUGP("Applying relocate section %u to %u\n",
419                relsec, sechdrs[relsec].sh_info);
420         base = sechdrs[sechdrs[relsec].sh_info].sh_addr;
421         symtab = (Elf_Sym *) sechdrs[symindex].sh_addr;
422         rela = (Elf_Rela *) sechdrs[relsec].sh_addr;
423         n = sechdrs[relsec].sh_size / sizeof(Elf_Rela);
424
425         for (i = 0; i < n; i++, rela++) {
426                 rc = apply_rela(rela, base, symtab, strtab, me);
427                 if (rc)
428                         return rc;
429         }
430         return 0;
431 }
432
433 int module_finalize(const Elf_Ehdr *hdr,
434                     const Elf_Shdr *sechdrs,
435                     struct module *me)
436 {
437         const Elf_Shdr *s;
438         char *secstrings, *secname;
439         void *aseg;
440
441         if (IS_ENABLED(CONFIG_EXPOLINE) &&
442             !nospec_disable && me->arch.plt_size) {
443                 unsigned int *ij;
444
445                 ij = me->core_layout.base + me->arch.plt_offset +
446                         me->arch.plt_size - PLT_ENTRY_SIZE;
447                 if (test_facility(35)) {
448                         ij[0] = 0xc6000000;     /* exrl %r0,.+10        */
449                         ij[1] = 0x0005a7f4;     /* j    .               */
450                         ij[2] = 0x000007f1;     /* br   %r1             */
451                 } else {
452                         ij[0] = 0x44000000 | (unsigned int)
453                                 offsetof(struct lowcore, br_r1_trampoline);
454                         ij[1] = 0xa7f40000;     /* j    .               */
455                 }
456         }
457
458         secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
459         for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
460                 aseg = (void *) s->sh_addr;
461                 secname = secstrings + s->sh_name;
462
463                 if (!strcmp(".altinstructions", secname))
464                         /* patch .altinstructions */
465                         apply_alternatives(aseg, aseg + s->sh_size);
466
467                 if (IS_ENABLED(CONFIG_EXPOLINE) &&
468                     (!strncmp(".s390_indirect", secname, 14)))
469                         nospec_revert(aseg, aseg + s->sh_size);
470
471                 if (IS_ENABLED(CONFIG_EXPOLINE) &&
472                     (!strncmp(".s390_return", secname, 12)))
473                         nospec_revert(aseg, aseg + s->sh_size);
474         }
475
476         jump_label_apply_nops(me);
477         return 0;
478 }