Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/s390/boot/pgm_check.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/kernel.h>
3
#include <linux/stdarg.h>
4
#include <linux/string.h>
5
#include <linux/ctype.h>
6
#include <asm/stacktrace.h>
7
#include <asm/boot_data.h>
8
#include <asm/lowcore.h>
9
#include <asm/setup.h>
10
#include <asm/sclp.h>
11
#include <asm/uv.h>
12
#include "boot.h"
13
14
void print_stacktrace(unsigned long sp)
15
{
16
struct stack_info boot_stack = { STACK_TYPE_TASK, (unsigned long)_stack_start,
17
(unsigned long)_stack_end };
18
bool first = true;
19
20
boot_emerg("Call Trace:\n");
21
while (!(sp & 0x7) && on_stack(&boot_stack, sp, sizeof(struct stack_frame))) {
22
struct stack_frame *sf = (struct stack_frame *)sp;
23
24
if (first)
25
boot_emerg("(sp:%016lx [<%016lx>] %pS)\n", sp, sf->gprs[8], (void *)sf->gprs[8]);
26
else
27
boot_emerg(" sp:%016lx [<%016lx>] %pS\n", sp, sf->gprs[8], (void *)sf->gprs[8]);
28
if (sf->back_chain <= sp)
29
break;
30
sp = sf->back_chain;
31
first = false;
32
}
33
}
34
35
extern struct exception_table_entry __start___ex_table[];
36
extern struct exception_table_entry __stop___ex_table[];
37
38
static inline unsigned long extable_insn(const struct exception_table_entry *x)
39
{
40
return (unsigned long)&x->insn + x->insn;
41
}
42
43
static bool ex_handler(struct pt_regs *regs)
44
{
45
const struct exception_table_entry *ex;
46
47
for (ex = __start___ex_table; ex < __stop___ex_table; ex++) {
48
if (extable_insn(ex) != regs->psw.addr)
49
continue;
50
if (ex->type != EX_TYPE_FIXUP)
51
return false;
52
regs->psw.addr = extable_fixup(ex);
53
return true;
54
}
55
return false;
56
}
57
58
void do_pgm_check(struct pt_regs *regs)
59
{
60
struct psw_bits *psw = &psw_bits(regs->psw);
61
unsigned long *gpregs = regs->gprs;
62
63
if (ex_handler(regs))
64
return;
65
if (bootdebug)
66
boot_rb_dump();
67
boot_emerg("Linux version %s\n", kernel_version);
68
if (!is_prot_virt_guest() && early_command_line[0])
69
boot_emerg("Kernel command line: %s\n", early_command_line);
70
boot_emerg("Kernel fault: interruption code %04x ilc:%d\n",
71
regs->int_code & 0xffff, regs->int_code >> 17);
72
if (kaslr_enabled()) {
73
boot_emerg("Kernel random base: %lx\n", __kaslr_offset);
74
boot_emerg("Kernel random base phys: %lx\n", __kaslr_offset_phys);
75
}
76
boot_emerg("PSW : %016lx %016lx (%pS)\n",
77
regs->psw.mask, regs->psw.addr, (void *)regs->psw.addr);
78
boot_emerg(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x P:%x AS:%x CC:%x PM:%x RI:%x EA:%x\n",
79
psw->per, psw->dat, psw->io, psw->ext, psw->key, psw->mcheck,
80
psw->wait, psw->pstate, psw->as, psw->cc, psw->pm, psw->ri, psw->eaba);
81
boot_emerg("GPRS: %016lx %016lx %016lx %016lx\n", gpregs[0], gpregs[1], gpregs[2], gpregs[3]);
82
boot_emerg(" %016lx %016lx %016lx %016lx\n", gpregs[4], gpregs[5], gpregs[6], gpregs[7]);
83
boot_emerg(" %016lx %016lx %016lx %016lx\n", gpregs[8], gpregs[9], gpregs[10], gpregs[11]);
84
boot_emerg(" %016lx %016lx %016lx %016lx\n", gpregs[12], gpregs[13], gpregs[14], gpregs[15]);
85
print_stacktrace(gpregs[15]);
86
boot_emerg("Last Breaking-Event-Address:\n");
87
boot_emerg(" [<%016lx>] %pS\n", regs->last_break, (void *)regs->last_break);
88
/* Convert to disabled wait PSW */
89
psw->io = 0;
90
psw->ext = 0;
91
psw->wait = 1;
92
}
93
94