STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
+STACK_INIT  = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
 
 #define BASED(name) name-system_call(%r13)
 
        sra     %r14,\shift
        jnz     1f
        CHECK_STACK 1<<\shift,\savearea
+       ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        j       2f
 1:     l       %r15,\stack             # load target stack
-2:     ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+2:     la      %r11,STACK_FRAME_OVERHEAD(%r15)
        .endm
 
        .macro  ADD64 high,low,timer
        l       %r4,__THREAD_info(%r2)          # get thread_info of prev
        l       %r5,__THREAD_info(%r3)          # get thread_info of next
        lr      %r15,%r5
-       ahi     %r15,STACK_SIZE                 # end of kernel stack of next
+       ahi     %r15,STACK_INIT                 # end of kernel stack of next
        st      %r3,__LC_CURRENT                # store task struct of next
        st      %r5,__LC_THREAD_INFO            # store thread info of next
        st      %r15,__LC_KERNEL_STACK          # store end of kernel stack
        l       %r13,__LC_SVC_NEW_PSW+4
 sysc_per:
        l       %r15,__LC_KERNEL_STACK
-       ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        la      %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
 sysc_vtime:
        UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
        tm      __LC_PGM_ILC+3,0x80     # check for per exception
        jnz     pgm_svcper              # -> single stepped svc
 0:     CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
+       ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        j       2f
 1:     UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
        l       %r15,__LC_KERNEL_STACK
-2:     ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+2:     la      %r11,STACK_FRAME_OVERHEAD(%r15)
        stm     %r0,%r7,__PT_R0(%r11)
        mvc     __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
        stm     %r8,%r9,__PT_PSW(%r11)
 #
 io_work_user:
        l       %r1,__LC_KERNEL_STACK
-       ahi     %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        mvc     STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
        la      %r11,STACK_FRAME_OVERHEAD(%r1)
        tm      __PT_PSW+1(%r11),0x01   # returning to user ?
        jno     mcck_return
        l       %r1,__LC_KERNEL_STACK   # switch to kernel stack
-       ahi     %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        mvc     STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
        la      %r11,STACK_FRAME_OVERHEAD(%r15)
        sra     %r14,PAGE_SHIFT
        jz      0f
        l       %r15,__LC_PANIC_STACK
+       j       mcck_skip
 0:     ahi     %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        j       mcck_skip
 
  */
 stack_overflow:
        l       %r15,__LC_PANIC_STACK   # change to panic stack
-       ahi     %r15,-__PT_SIZE         # create pt_regs
-       stm     %r0,%r7,__PT_R0(%r15)
-       stm     %r8,%r9,__PT_PSW(%r15)
+       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+       stm     %r0,%r7,__PT_R0(%r11)
+       stm     %r8,%r9,__PT_PSW(%r11)
        mvc     __PT_R8(32,%r11),0(%r14)
-       lr      %r15,%r11
-       ahi     %r15,-STACK_FRAME_OVERHEAD
        l       %r1,BASED(1f)
        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
        lr      %r2,%r11                # pass pointer to pt_regs
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
        # set up saved register 11
        l       %r15,__LC_KERNEL_STACK
-       ahi     %r15,-__PT_SIZE
-       st      %r15,12(%r11)           # r11 pt_regs pointer
+       la      %r9,STACK_FRAME_OVERHEAD(%r15)
+       st      %r9,12(%r11)            # r11 pt_regs pointer
        # fill pt_regs
-       mvc     __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
-       stm     %r0,%r7,__PT_R0(%r15)
-       mvc     __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
-       mvc     __PT_INT_CODE(4,%r15),__LC_SVC_ILC
+       mvc     __PT_R8(32,%r9),__LC_SAVE_AREA_SYNC
+       stm     %r0,%r7,__PT_R0(%r9)
+       mvc     __PT_PSW(8,%r9),__LC_SVC_OLD_PSW
+       mvc     __PT_INT_CODE(4,%r9),__LC_SVC_ILC
        # setup saved register 15
-       ahi     %r15,-STACK_FRAME_OVERHEAD
        st      %r15,28(%r11)           # r15 stack pointer
        # set new psw address and exit
        l       %r9,BASED(cleanup_table+4)      # sysc_do_svc + 0x80000000
 
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
+STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
 
 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
                 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
        srag    %r14,%r14,\shift
        jnz     1f
        CHECK_STACK 1<<\shift,\savearea
+       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        j       2f
 1:     lg      %r15,\stack             # load target stack
-2:     aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+2:     la      %r11,STACK_FRAME_OVERHEAD(%r15)
        .endm
 
        .macro UPDATE_VTIME scratch,enter_timer
        lg      %r4,__THREAD_info(%r2)          # get thread_info of prev
        lg      %r5,__THREAD_info(%r3)          # get thread_info of next
        lgr     %r15,%r5
-       aghi    %r15,STACK_SIZE                 # end of kernel stack of next
+       aghi    %r15,STACK_INIT                 # end of kernel stack of next
        stg     %r3,__LC_CURRENT                # store task struct of next
        stg     %r5,__LC_THREAD_INFO            # store thread info of next
        stg     %r15,__LC_KERNEL_STACK          # store end of kernel stack
        stmg    %r8,%r15,__LC_SAVE_AREA_SYNC
        lg      %r10,__LC_LAST_BREAK
        lg      %r12,__LC_THREAD_INFO
-       larl    %r13,system_call
 sysc_per:
        lg      %r15,__LC_KERNEL_STACK
-       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        la      %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
 sysc_vtime:
        UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
        tm      __LC_PGM_ILC+3,0x80     # check for per exception
        jnz     pgm_svcper              # -> single stepped svc
 0:     CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
+       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        j       2f
 1:     UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
        LAST_BREAK %r14
        tm      __LC_PGM_ILC+2,0x02     # check for transaction abort
        jz      2f
        mvc     __THREAD_trap_tdb(256,%r14),0(%r13)
-2:     aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
+2:     la      %r11,STACK_FRAME_OVERHEAD(%r15)
        stmg    %r0,%r7,__PT_R0(%r11)
        mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
        stmg    %r8,%r9,__PT_PSW(%r11)
 #
 io_work_user:
        lg      %r1,__LC_KERNEL_STACK
-       aghi    %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        mvc     STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
        la      %r11,STACK_FRAME_OVERHEAD(%r1)
        tm      __PT_PSW+1(%r11),0x01   # returning to user ?
        jno     mcck_return
        lg      %r1,__LC_KERNEL_STACK   # switch to kernel stack
-       aghi    %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        mvc     STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
        la      %r11,STACK_FRAME_OVERHEAD(%r1)
  * Setup a pt_regs so that show_trace can provide a good call trace.
  */
 stack_overflow:
-       lg      %r11,__LC_PANIC_STACK   # change to panic stack
-       aghi    %r11,-__PT_SIZE         # create pt_regs
+       lg      %r15,__LC_PANIC_STACK   # change to panic stack
+       la      %r11,STACK_FRAME_OVERHEAD(%r15)
        stmg    %r0,%r7,__PT_R0(%r11)
        stmg    %r8,%r9,__PT_PSW(%r11)
        mvc     __PT_R8(64,%r11),0(%r14)
        stg     %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
-       lgr     %r15,%r11
-       aghi    %r15,-STACK_FRAME_OVERHEAD
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
        lgr     %r2,%r11                # pass pointer to pt_regs
        jg      kernel_stack_overflow
        mvc     __TI_last_break(8,%r12),16(%r11)
 0:     # set up saved register r11
        lg      %r15,__LC_KERNEL_STACK
-       aghi    %r15,-__PT_SIZE
-       stg     %r15,24(%r11)           # r11 pt_regs pointer
+       la      %r9,STACK_FRAME_OVERHEAD(%r15)
+       stg     %r9,24(%r11)            # r11 pt_regs pointer
        # fill pt_regs
-       mvc     __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
-       stmg    %r0,%r7,__PT_R0(%r15)
-       mvc     __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
-       mvc     __PT_INT_CODE(4,%r15),__LC_SVC_ILC
+       mvc     __PT_R8(64,%r9),__LC_SAVE_AREA_SYNC
+       stmg    %r0,%r7,__PT_R0(%r9)
+       mvc     __PT_PSW(16,%r9),__LC_SVC_OLD_PSW
+       mvc     __PT_INT_CODE(4,%r9),__LC_SVC_ILC
        # setup saved register r15
-       aghi    %r15,-STACK_FRAME_OVERHEAD
        stg     %r15,56(%r11)           # r15 stack pointer
        # set new psw address and exit
        larl    %r9,sysc_do_svc
 
                PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
        lc->clock_comparator = -1ULL;
-       lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
+       lc->kernel_stack = ((unsigned long) &init_thread_union)
+               + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
        lc->async_stack = (unsigned long)
-               __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
+               __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0)
+               + ASYNC_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
        lc->panic_stack = (unsigned long)
-               __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
+               __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0)
+               + PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
        lc->current_task = (unsigned long) init_thread_union.thread_info.task;
        lc->thread_info = (unsigned long) &init_thread_union;
        lc->machine_flags = S390_lowcore.machine_flags;
 
        lc = pcpu->lowcore;
        memcpy(lc, &S390_lowcore, 512);
        memset((char *) lc + 512, 0, sizeof(*lc) - 512);
-       lc->async_stack = pcpu->async_stack + ASYNC_SIZE;
-       lc->panic_stack = pcpu->panic_stack + PAGE_SIZE;
+       lc->async_stack = pcpu->async_stack + ASYNC_SIZE
+               - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
+       lc->panic_stack = pcpu->panic_stack + PAGE_SIZE
+               - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
        lc->cpu_nr = cpu;
 #ifndef CONFIG_64BIT
        if (MACHINE_HAS_IEEE) {
        struct _lowcore *lc = pcpu->lowcore;
        struct thread_info *ti = task_thread_info(tsk);
 
-       lc->kernel_stack = (unsigned long) task_stack_page(tsk) + THREAD_SIZE;
+       lc->kernel_stack = (unsigned long) task_stack_page(tsk)
+               + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
        lc->thread_info = (unsigned long) task_thread_info(tsk);
        lc->current_task = (unsigned long) tsk;
        lc->user_timer = ti->user_timer;
        pcpu->state = CPU_STATE_CONFIGURED;
        pcpu->address = boot_cpu_address;
        pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();
-       pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE;
-       pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE;
+       pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE
+               + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
+       pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE
+               + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
        S390_lowcore.percpu_offset = __per_cpu_offset[0];
        smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
        set_cpu_present(0, true);