Skip to content

Commit 3fb4f97

Browse files
committed
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
2 parents e0a472f + ad31a8c commit 3fb4f97

5 files changed

Lines changed: 18 additions & 5 deletions

File tree

arch/s390/include/asm/stacktrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum stack_type {
1212
STACK_TYPE_IRQ,
1313
STACK_TYPE_NODAT,
1414
STACK_TYPE_RESTART,
15+
STACK_TYPE_MCCK,
1516
};
1617

1718
struct stack_info {

arch/s390/kernel/cpcmd.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ static int diag8_noresponse(int cmdlen)
3737

3838
static int diag8_response(int cmdlen, char *response, int *rlen)
3939
{
40+
unsigned long _cmdlen = cmdlen | 0x40000000L;
41+
unsigned long _rlen = *rlen;
4042
register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
4143
register unsigned long reg3 asm ("3") = (addr_t) response;
42-
register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
43-
register unsigned long reg5 asm ("5") = *rlen;
44+
register unsigned long reg4 asm ("4") = _cmdlen;
45+
register unsigned long reg5 asm ("5") = _rlen;
4446

4547
asm volatile(
4648
" diag %2,%0,0x8\n"

arch/s390/kernel/dumpstack.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ static bool in_nodat_stack(unsigned long sp, struct stack_info *info)
7979
return in_stack(sp, info, STACK_TYPE_NODAT, top - THREAD_SIZE, top);
8080
}
8181

82+
static bool in_mcck_stack(unsigned long sp, struct stack_info *info)
83+
{
84+
unsigned long frame_size, top;
85+
86+
frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
87+
top = S390_lowcore.mcck_stack + frame_size;
88+
return in_stack(sp, info, STACK_TYPE_MCCK, top - THREAD_SIZE, top);
89+
}
90+
8291
static bool in_restart_stack(unsigned long sp, struct stack_info *info)
8392
{
8493
unsigned long frame_size, top;
@@ -108,7 +117,8 @@ int get_stack_info(unsigned long sp, struct task_struct *task,
108117
/* Check per-cpu stacks */
109118
if (!in_irq_stack(sp, info) &&
110119
!in_nodat_stack(sp, info) &&
111-
!in_restart_stack(sp, info))
120+
!in_restart_stack(sp, info) &&
121+
!in_mcck_stack(sp, info))
112122
goto unknown;
113123

114124
recursion_check:

arch/s390/kernel/irq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
174174

175175
memcpy(&regs->int_code, &S390_lowcore.ext_cpu_addr, 4);
176176
regs->int_parm = S390_lowcore.ext_params;
177-
regs->int_parm_long = *(unsigned long *)S390_lowcore.ext_params2;
177+
regs->int_parm_long = S390_lowcore.ext_params2;
178178

179179
from_idle = !user_mode(regs) && regs->psw.addr == (unsigned long)psw_idle_exit;
180180
if (from_idle)

arch/s390/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ static int __init stack_realloc(void)
354354
if (!new)
355355
panic("Couldn't allocate machine check stack");
356356
WRITE_ONCE(S390_lowcore.mcck_stack, new + STACK_INIT_OFFSET);
357-
memblock_free(old, THREAD_SIZE);
357+
memblock_free_late(old, THREAD_SIZE);
358358
return 0;
359359
}
360360
early_initcall(stack_realloc);

0 commit comments

Comments
 (0)