Hi Linus,

please pull a couple of s390 fixes for 5.12-rc7.

Thank you,
Heiko

The following changes since commit 84d572e634e28827d105746c922d8ada425e2d8b:

  MAINTAINERS: add backups for s390 vfio drivers (2021-03-28 20:20:33 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git tags/s390-5.12-6

for you to fetch changes up to ad31a8c05196a3dc5283b193e9c74a72022d3c65:

  s390/setup: use memblock_free_late() to free old stack (2021-04-07 14:37:28 
+0200)

----------------------------------------------------------------
s390 updates for 5.12-rc7

- fix incorrect dereference of the ext_params2 external interrupt parameter,
  which leads to an instant kernel crash if a pfault interrupt occurs.

- add forgotten stack unwinder support, and fix memory leak for the new
  machine check handler stack.

- fix inline assembly register clobbering due to KASAN code instrumentation.

----------------------------------------------------------------
Alexander Gordeev (1):
      s390/cpcmd: fix inline assembly register clobbering

Heiko Carstens (2):
      s390/irq: fix reading of ext_params2 field from lowcore
      s390/setup: use memblock_free_late() to free old stack

Vasily Gorbik (1):
      s390/unwind: add machine check handler stack

 arch/s390/include/asm/stacktrace.h |  1 +
 arch/s390/kernel/cpcmd.c           |  6 ++++--
 arch/s390/kernel/dumpstack.c       | 12 +++++++++++-
 arch/s390/kernel/irq.c             |  2 +-
 arch/s390/kernel/setup.c           |  2 +-
 5 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/stacktrace.h 
b/arch/s390/include/asm/stacktrace.h
index ee056f4a4fa3..2b543163d90a 100644
--- a/arch/s390/include/asm/stacktrace.h
+++ b/arch/s390/include/asm/stacktrace.h
@@ -12,6 +12,7 @@ enum stack_type {
        STACK_TYPE_IRQ,
        STACK_TYPE_NODAT,
        STACK_TYPE_RESTART,
+       STACK_TYPE_MCCK,
 };
 
 struct stack_info {
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index af013b4244d3..2da027359798 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -37,10 +37,12 @@ static int diag8_noresponse(int cmdlen)
 
 static int diag8_response(int cmdlen, char *response, int *rlen)
 {
+       unsigned long _cmdlen = cmdlen | 0x40000000L;
+       unsigned long _rlen = *rlen;
        register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
        register unsigned long reg3 asm ("3") = (addr_t) response;
-       register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
-       register unsigned long reg5 asm ("5") = *rlen;
+       register unsigned long reg4 asm ("4") = _cmdlen;
+       register unsigned long reg5 asm ("5") = _rlen;
 
        asm volatile(
                "       diag    %2,%0,0x8\n"
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index 0dc4b258b98d..db1bc00229ca 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -79,6 +79,15 @@ static bool in_nodat_stack(unsigned long sp, struct 
stack_info *info)
        return in_stack(sp, info, STACK_TYPE_NODAT, top - THREAD_SIZE, top);
 }
 
+static bool in_mcck_stack(unsigned long sp, struct stack_info *info)
+{
+       unsigned long frame_size, top;
+
+       frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
+       top = S390_lowcore.mcck_stack + frame_size;
+       return in_stack(sp, info, STACK_TYPE_MCCK, top - THREAD_SIZE, top);
+}
+
 static bool in_restart_stack(unsigned long sp, struct stack_info *info)
 {
        unsigned long frame_size, top;
@@ -108,7 +117,8 @@ int get_stack_info(unsigned long sp, struct task_struct 
*task,
        /* Check per-cpu stacks */
        if (!in_irq_stack(sp, info) &&
            !in_nodat_stack(sp, info) &&
-           !in_restart_stack(sp, info))
+           !in_restart_stack(sp, info) &&
+           !in_mcck_stack(sp, info))
                goto unknown;
 
 recursion_check:
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 601c21791338..714269e10eec 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -174,7 +174,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
 
        memcpy(&regs->int_code, &S390_lowcore.ext_cpu_addr, 4);
        regs->int_parm = S390_lowcore.ext_params;
-       regs->int_parm_long = *(unsigned long *)S390_lowcore.ext_params2;
+       regs->int_parm_long = S390_lowcore.ext_params2;
 
        from_idle = !user_mode(regs) && regs->psw.addr == (unsigned 
long)psw_idle_exit;
        if (from_idle)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 60da976eee6f..72134f9f6ff5 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -354,7 +354,7 @@ static int __init stack_realloc(void)
        if (!new)
                panic("Couldn't allocate machine check stack");
        WRITE_ONCE(S390_lowcore.mcck_stack, new + STACK_INIT_OFFSET);
-       memblock_free(old, THREAD_SIZE);
+       memblock_free_late(old, THREAD_SIZE);
        return 0;
 }
 early_initcall(stack_realloc);

Reply via email to