]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/boot: Pass pt_regs to program check handler
authorHeiko Carstens <hca@linux.ibm.com>
Mon, 24 Feb 2025 14:59:04 +0000 (15:59 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 4 Mar 2025 16:25:22 +0000 (17:25 +0100)
Setup a pt_regs structure on the stack, poplulate it in low level assembler
code, and pass it to print_pgm_check_info(). This way there is no need to
access then lowcore from print_pgm_check_info() anymore, and the function
looks like a normal program check handler function.

Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/boot/boot.h
arch/s390/boot/head.S
arch/s390/boot/pgm_check_info.c
arch/s390/kernel/asm-offsets.c

index bb6bd9d6d99111357580825ea18e6be0c406e049..bc3432fffff24f621c585872167ffc498d25947e 100644 (file)
@@ -65,7 +65,7 @@ void verify_facilities(void);
 void print_missing_facilities(void);
 void sclp_early_setup_buffer(void);
 void alt_debug_setup(char *str);
-void print_pgm_check_info(void);
+void print_pgm_check_info(struct pt_regs *regs);
 unsigned long randomize_within_range(unsigned long size, unsigned long align,
                                     unsigned long min, unsigned long max);
 void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit);
index fe68c9253ea2aebb8e8374dba818e8daf78fe46e..0a0afb91571872e9165827a780b3f14aaca1d63c 100644 (file)
@@ -312,7 +312,12 @@ SYM_CODE_START_LOCAL(startup_pgm_check_handler)
        oi      __LC_RETURN_PSW+1,0x2   # set wait state bit
        larl    %r9,.Lold_psw_disabled_wait
        stg     %r9,__LC_PGM_NEW_PSW+8
-       larl    %r15,_dump_info_stack_end-STACK_FRAME_OVERHEAD
+       larl    %r15,_dump_info_stack_end-(STACK_FRAME_OVERHEAD+__PT_SIZE)
+       la      %r2,STACK_FRAME_OVERHEAD(%r15)
+       mvc     __PT_PSW(16,%r2),__LC_PSW_SAVE_AREA-4095(%r8)
+       mvc     __PT_R0(128,%r2),__LC_GPREGS_SAVE_AREA-4095(%r8)
+       mvc     __PT_LAST_BREAK(8,%r2),__LC_PGM_LAST_BREAK
+       mvc     __PT_INT_CODE(4,%r2),__LC_PGM_INT_CODE
        brasl   %r14,print_pgm_check_info
 .Lold_psw_disabled_wait:
        la      %r8,4095
index 633f11600aab3a0d2a0ba2c54dffab2d55497ea8..e61ae4a159698a5b3e690e0dc3a611f15d78fbc1 100644 (file)
@@ -32,10 +32,10 @@ void print_stacktrace(unsigned long sp)
        }
 }
 
-void print_pgm_check_info(void)
+void print_pgm_check_info(struct pt_regs *regs)
 {
-       unsigned long *gpregs = (unsigned long *)get_lowcore()->gpregs_save_area;
-       struct psw_bits *psw = &psw_bits(get_lowcore()->psw_save_area);
+       struct psw_bits *psw = &psw_bits(regs->psw);
+       unsigned long *gpregs = regs->gprs;
 
        if (bootdebug)
                boot_rb_dump();
@@ -43,15 +43,13 @@ void print_pgm_check_info(void)
        if (!is_prot_virt_guest() && early_command_line[0])
                boot_emerg("Kernel command line: %s\n", early_command_line);
        boot_emerg("Kernel fault: interruption code %04x ilc:%d\n",
-                  get_lowcore()->pgm_code, get_lowcore()->pgm_ilc >> 1);
+                  regs->int_code & 0xffff, regs->int_code >> 17);
        if (kaslr_enabled()) {
                boot_emerg("Kernel random base: %lx\n", __kaslr_offset);
                boot_emerg("Kernel random base phys: %lx\n", __kaslr_offset_phys);
        }
        boot_emerg("PSW : %016lx %016lx (%pS)\n",
-                  get_lowcore()->psw_save_area.mask,
-                  get_lowcore()->psw_save_area.addr,
-                  (void *)get_lowcore()->psw_save_area.addr);
+                  regs->psw.mask, regs->psw.addr, (void *)regs->psw.addr);
        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",
                   psw->per, psw->dat, psw->io, psw->ext, psw->key, psw->mcheck,
                   psw->wait, psw->pstate, psw->as, psw->cc, psw->pm, psw->ri, psw->eaba);
@@ -59,8 +57,7 @@ void print_pgm_check_info(void)
        boot_emerg("      %016lx %016lx %016lx %016lx\n", gpregs[4], gpregs[5], gpregs[6], gpregs[7]);
        boot_emerg("      %016lx %016lx %016lx %016lx\n", gpregs[8], gpregs[9], gpregs[10], gpregs[11]);
        boot_emerg("      %016lx %016lx %016lx %016lx\n", gpregs[12], gpregs[13], gpregs[14], gpregs[15]);
-       print_stacktrace(get_lowcore()->gpregs_save_area[15]);
+       print_stacktrace(gpregs[15]);
        boot_emerg("Last Breaking-Event-Address:\n");
-       boot_emerg(" [<%016lx>] %pS\n", (unsigned long)get_lowcore()->pgm_last_break,
-                  (void *)get_lowcore()->pgm_last_break);
+       boot_emerg(" [<%016lx>] %pS\n", regs->last_break, (void *)regs->last_break);
 }
index c623888029fbf3aabddaa213a67b7f7fbd76137e..49bb197c8c81532f19e72423a65b9f721d5a52db 100644 (file)
@@ -49,6 +49,7 @@ int main(void)
        OFFSET(__PT_R14, pt_regs, gprs[14]);
        OFFSET(__PT_R15, pt_regs, gprs[15]);
        OFFSET(__PT_ORIG_GPR2, pt_regs, orig_gpr2);
+       OFFSET(__PT_INT_CODE, pt_regs, int_code);
        OFFSET(__PT_FLAGS, pt_regs, flags);
        OFFSET(__PT_CR1, pt_regs, cr1);
        OFFSET(__PT_LAST_BREAK, pt_regs, last_break);
@@ -77,6 +78,7 @@ int main(void)
        OFFSET(__LC_EXT_INT_CODE, lowcore, ext_int_code);
        OFFSET(__LC_PGM_ILC, lowcore, pgm_ilc);
        OFFSET(__LC_PGM_CODE, lowcore, pgm_code);
+       OFFSET(__LC_PGM_INT_CODE, lowcore, pgm_int_code);
        OFFSET(__LC_DATA_EXC_CODE, lowcore, data_exc_code);
        OFFSET(__LC_MON_CLASS_NR, lowcore, mon_class_num);
        OFFSET(__LC_PER_CODE, lowcore, per_code);