Commit 3fb4f979 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 's390-5.12-6' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Heiko Carstens:

 - 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.

* tag 's390-5.12-6' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/setup: use memblock_free_late() to free old stack
  s390/irq: fix reading of ext_params2 field from lowcore
  s390/unwind: add machine check handler stack
  s390/cpcmd: fix inline assembly register clobbering
parents e0a472ff ad31a8c0
......@@ -12,6 +12,7 @@ enum stack_type {
STACK_TYPE_IRQ,
STACK_TYPE_NODAT,
STACK_TYPE_RESTART,
STACK_TYPE_MCCK,
};
struct stack_info {
......
......@@ -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"
......
......@@ -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:
......
......@@ -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)
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment