Skip to content

Commit 2d1b21e

Browse files
Alexander GordeevVasily Gorbik
authored andcommitted
s390/kdump: remove nodat stack restriction for calling nodat functions
To allow calling of DAT-off code from kernel the stack needs to be switched to nodat_stack (or other stack mapped as 1:1). Before call_nodat() macro was introduced that was necessary to provide the very same memory address for STNSM and STOSM instructions. If the kernel would stay on a random stack (e.g. a virtually mapped one) then a virtual address provided for STNSM instruction could differ from the physical address needed for the corresponding STOSM instruction. After call_nodat() macro is introduced the kernel stack does not need to be mapped 1:1 anymore, since the macro stores the physical memory address of return PSW in a register before entering DAT-off mode. This way the return LPSWE instruction is able to pick the correct memory location and restore the DAT-on mode. That however might fail in case the 16-byte return PSW happened to cross page boundary: PSW mask and PSW address could end up in two separate non-contiguous physical pages. Align the return PSW on 16-byte boundary so it always fits into a single physical page. As result any stack (including the virtually mapped one) could be used for calling DAT-off code and prior switching to nodat_stack becomes unnecessary. Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 82caf7a commit 2d1b21e

2 files changed

Lines changed: 5 additions & 12 deletions

File tree

arch/s390/include/asm/stacktrace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ static __always_inline unsigned long get_stack_pointer(struct task_struct *task,
210210
#define call_nodat(nr, rettype, fn, ...) \
211211
({ \
212212
rettype (*__fn)(CALL_PARM_##nr(__VA_ARGS__)) = (fn); \
213-
psw_t psw_enter, psw_leave; \
213+
/* aligned since psw_leave must not cross page boundary */ \
214+
psw_t __aligned(16) psw_leave; \
215+
psw_t psw_enter; \
214216
CALL_LARGS_##nr(__VA_ARGS__); \
215217
CALL_REGS_##nr; \
216218
\

arch/s390/kernel/machine_kexec.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,6 @@ static noinline void __machine_kdump(void *image)
112112
store_status(__do_machine_kdump, image);
113113
}
114114

115-
static int do_start_kdump(struct kimage *image)
116-
{
117-
purgatory_t purgatory = (purgatory_t)image->start;
118-
119-
return call_nodat(1, int, purgatory, int, 0);
120-
}
121-
122115
#endif /* CONFIG_CRASH_DUMP */
123116

124117
/*
@@ -127,12 +120,10 @@ static int do_start_kdump(struct kimage *image)
127120
static bool kdump_csum_valid(struct kimage *image)
128121
{
129122
#ifdef CONFIG_CRASH_DUMP
123+
purgatory_t purgatory = (purgatory_t)image->start;
130124
int rc;
131125

132-
preempt_disable();
133-
rc = call_on_stack(1, S390_lowcore.nodat_stack, int, do_start_kdump,
134-
struct kimage *, image);
135-
preempt_enable();
126+
rc = call_nodat(1, int, purgatory, int, 0);
136127
return rc == 0;
137128
#else
138129
return false;

0 commit comments

Comments
 (0)