* Basic Program Check Handler.
  */
 extern void s390_base_pgm_handler(void);
-extern void (*s390_base_pgm_handler_fn)(void);
+extern void (*s390_base_pgm_handler_fn)(struct pt_regs *regs);
 
 #define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL
 
 
        GEN_BR_THUNK %r9
        GEN_BR_THUNK %r14
 
+__PT_R0 = __PT_GPRS
+__PT_R8 = __PT_GPRS + 64
+
 ENTRY(s390_base_pgm_handler)
-       stmg    %r0,%r15,__LC_SAVE_AREA_SYNC
-       basr    %r13,0
-0:     aghi    %r15,-STACK_FRAME_OVERHEAD
+       stmg    %r8,%r15,__LC_SAVE_AREA_SYNC
+       aghi    %r15,-(STACK_FRAME_OVERHEAD+__PT_SIZE)
+       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+       xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+       stmg    %r0,%r7,__PT_R0(%r11)
+       mvc     __PT_PSW(16,%r11),__LC_PGM_OLD_PSW
+       mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
+       lgr     %r2,%r11
        larl    %r1,s390_base_pgm_handler_fn
        lg      %r9,0(%r1)
        ltgr    %r9,%r9
        jz      1f
        BASR_EX %r14,%r9
-       lmg     %r0,%r15,__LC_SAVE_AREA_SYNC
-       lpswe   __LC_PGM_OLD_PSW
-1:     lpswe   disabled_wait_psw-0b(%r13)
+       mvc     __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
+       lmg     %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
+       lpswe   __LC_RETURN_PSW
+1:     larl    %r13,disabled_wait_psw
+       lpswe   0(%r13)
 ENDPROC(s390_base_pgm_handler)
 
        .align  8
 
        topology_max_mnest = max_mnest;
 }
 
-static void early_pgm_check_handler(void)
+static void early_pgm_check_handler(struct pt_regs *regs)
 {
        const struct exception_table_entry *fixup;
-       unsigned long cr0, cr0_new;
-       unsigned long addr;
 
-       addr = S390_lowcore.program_old_psw.addr;
-       fixup = s390_search_extables(addr);
+       fixup = s390_search_extables(regs->psw.addr);
        if (!fixup)
                disabled_wait();
-       /* Disable low address protection before storing into lowcore. */
-       __ctl_store(cr0, 0, 0);
-       cr0_new = cr0 & ~(1UL << 28);
-       __ctl_load(cr0_new, 0, 0);
-       S390_lowcore.program_old_psw.addr = extable_fixup(fixup);
-       __ctl_load(cr0, 0, 0);
+       regs->psw.addr = extable_fixup(fixup);
 }
 
 static noinline __init void setup_lowcore_early(void)