Skip to content

Commit d9c1e64

Browse files
committed
Merge tag 's390-5.16-5' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Heiko Carstens: - Add missing handling of R_390_PLT32DBL relocation type in arch_kexec_apply_relocations_add(). Clang and the upcoming gcc 11.3 generate such relocation entries, which our relocation code silently ignores, and which finally will result in an endless loop within the purgatory code in case of kexec. - Add proper handling of errors and print error messages when applying relocations - Fix duplicate tracking of irq nesting level in entry code - Let recordmcount.pl also look for jgnop mnemonic. Starting with binutils 2.37 objdump emits a jgnop mnemonic instead of brcl, which breaks mcount location detection. This is only a problem if used with compilers older than gcc 9, since with gcc 9 and newer compilers recordmcount.pl is not used anymore. - Remove preempt_disable()/preempt_enable() pair in kprobe_ftrace_handler() which was done for all architectures except for s390. - Update defconfig * tag 's390-5.16-5' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: recordmcount.pl: look for jgnop instruction as well as bcrl on s390 s390/entry: fix duplicate tracking of irq nesting level s390: enable switchdev support in defconfig s390/kexec: handle R_390_PLT32DBL rela in arch_kexec_apply_relocations_add() s390/ftrace: remove preempt_disable()/preempt_enable() pair s390/kexec_file: fix error handling when applying relocations s390/kexec_file: print some more error messages
2 parents 213d9d4 + 85bf17b commit d9c1e64

6 files changed

Lines changed: 44 additions & 11 deletions

File tree

arch/s390/configs/debug_defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ CONFIG_UNIX=y
117117
CONFIG_UNIX_DIAG=m
118118
CONFIG_XFRM_USER=m
119119
CONFIG_NET_KEY=m
120+
CONFIG_NET_SWITCHDEV=y
120121
CONFIG_SMC=m
121122
CONFIG_SMC_DIAG=m
122123
CONFIG_INET=y
@@ -511,6 +512,7 @@ CONFIG_NLMON=m
511512
CONFIG_MLX4_EN=m
512513
CONFIG_MLX5_CORE=m
513514
CONFIG_MLX5_CORE_EN=y
515+
CONFIG_MLX5_ESWITCH=y
514516
# CONFIG_NET_VENDOR_MICREL is not set
515517
# CONFIG_NET_VENDOR_MICROCHIP is not set
516518
# CONFIG_NET_VENDOR_MICROSEMI is not set

arch/s390/configs/defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ CONFIG_UNIX=y
109109
CONFIG_UNIX_DIAG=m
110110
CONFIG_XFRM_USER=m
111111
CONFIG_NET_KEY=m
112+
CONFIG_NET_SWITCHDEV=y
112113
CONFIG_SMC=m
113114
CONFIG_SMC_DIAG=m
114115
CONFIG_INET=y
@@ -502,6 +503,7 @@ CONFIG_NLMON=m
502503
CONFIG_MLX4_EN=m
503504
CONFIG_MLX5_CORE=m
504505
CONFIG_MLX5_CORE_EN=y
506+
CONFIG_MLX5_ESWITCH=y
505507
# CONFIG_NET_VENDOR_MICREL is not set
506508
# CONFIG_NET_VENDOR_MICROCHIP is not set
507509
# CONFIG_NET_VENDOR_MICROSEMI is not set

arch/s390/kernel/ftrace.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
290290
return;
291291

292292
regs = ftrace_get_regs(fregs);
293-
preempt_disable_notrace();
294293
p = get_kprobe((kprobe_opcode_t *)ip);
295294
if (unlikely(!p) || kprobe_disabled(p))
296295
goto out;
@@ -318,7 +317,6 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
318317
}
319318
__this_cpu_write(current_kprobe, NULL);
320319
out:
321-
preempt_enable_notrace();
322320
ftrace_test_recursion_unlock(bit);
323321
}
324322
NOKPROBE_SYMBOL(kprobe_ftrace_handler);

arch/s390/kernel/irq.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void noinstr do_io_irq(struct pt_regs *regs)
138138
struct pt_regs *old_regs = set_irq_regs(regs);
139139
int from_idle;
140140

141-
irq_enter();
141+
irq_enter_rcu();
142142

143143
if (user_mode(regs)) {
144144
update_timer_sys();
@@ -158,7 +158,8 @@ void noinstr do_io_irq(struct pt_regs *regs)
158158
do_irq_async(regs, IO_INTERRUPT);
159159
} while (MACHINE_IS_LPAR && irq_pending(regs));
160160

161-
irq_exit();
161+
irq_exit_rcu();
162+
162163
set_irq_regs(old_regs);
163164
irqentry_exit(regs, state);
164165

@@ -172,7 +173,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
172173
struct pt_regs *old_regs = set_irq_regs(regs);
173174
int from_idle;
174175

175-
irq_enter();
176+
irq_enter_rcu();
176177

177178
if (user_mode(regs)) {
178179
update_timer_sys();
@@ -190,7 +191,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
190191

191192
do_irq_async(regs, EXT_INTERRUPT);
192193

193-
irq_exit();
194+
irq_exit_rcu();
194195
set_irq_regs(old_regs);
195196
irqentry_exit(regs, state);
196197

arch/s390/kernel/machine_kexec_file.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
88
*/
99

10+
#define pr_fmt(fmt) "kexec: " fmt
11+
1012
#include <linux/elf.h>
1113
#include <linux/errno.h>
1214
#include <linux/kexec.h>
@@ -290,8 +292,16 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
290292
const Elf_Shdr *relsec,
291293
const Elf_Shdr *symtab)
292294
{
295+
const char *strtab, *name, *shstrtab;
296+
const Elf_Shdr *sechdrs;
293297
Elf_Rela *relas;
294298
int i, r_type;
299+
int ret;
300+
301+
/* String & section header string table */
302+
sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
303+
strtab = (char *)pi->ehdr + sechdrs[symtab->sh_link].sh_offset;
304+
shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
295305

296306
relas = (void *)pi->ehdr + relsec->sh_offset;
297307

@@ -304,15 +314,27 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
304314
sym = (void *)pi->ehdr + symtab->sh_offset;
305315
sym += ELF64_R_SYM(relas[i].r_info);
306316

307-
if (sym->st_shndx == SHN_UNDEF)
317+
if (sym->st_name)
318+
name = strtab + sym->st_name;
319+
else
320+
name = shstrtab + sechdrs[sym->st_shndx].sh_name;
321+
322+
if (sym->st_shndx == SHN_UNDEF) {
323+
pr_err("Undefined symbol: %s\n", name);
308324
return -ENOEXEC;
325+
}
309326

310-
if (sym->st_shndx == SHN_COMMON)
327+
if (sym->st_shndx == SHN_COMMON) {
328+
pr_err("symbol '%s' in common section\n", name);
311329
return -ENOEXEC;
330+
}
312331

313332
if (sym->st_shndx >= pi->ehdr->e_shnum &&
314-
sym->st_shndx != SHN_ABS)
333+
sym->st_shndx != SHN_ABS) {
334+
pr_err("Invalid section %d for symbol %s\n",
335+
sym->st_shndx, name);
315336
return -ENOEXEC;
337+
}
316338

317339
loc = pi->purgatory_buf;
318340
loc += section->sh_offset;
@@ -326,7 +348,15 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
326348
addr = section->sh_addr + relas[i].r_offset;
327349

328350
r_type = ELF64_R_TYPE(relas[i].r_info);
329-
arch_kexec_do_relocs(r_type, loc, val, addr);
351+
352+
if (r_type == R_390_PLT32DBL)
353+
r_type = R_390_PC32DBL;
354+
355+
ret = arch_kexec_do_relocs(r_type, loc, val, addr);
356+
if (ret) {
357+
pr_err("Unknown rela relocation: %d\n", r_type);
358+
return -ENOEXEC;
359+
}
330360
}
331361
return 0;
332362
}

scripts/recordmcount.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@
219219

220220
} elsif ($arch eq "s390" && $bits == 64) {
221221
if ($cc =~ /-DCC_USING_HOTPATCH/) {
222-
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$";
222+
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*(bcrl\\s*0,|jgnop\\s*)[0-9a-f]+ <([^\+]*)>\$";
223223
$mcount_adjust = 0;
224224
}
225225
$alignment = 8;

0 commit comments

Comments
 (0)