aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGravatar Heiko Carstens <hca@linux.ibm.com> 2020-12-13 18:05:56 +0100
committerGravatar Heiko Carstens <hca@linux.ibm.com> 2020-12-16 14:55:49 +0100
commitf22b9c219a798e1bf11110a3d2733d883e6da059 (patch)
tree4bd79dff40bc248855279f6d1a5990978bd8cc5e /arch
parents390: make calls to TRACE_IRQS_OFF/TRACE_IRQS_ON balanced (diff)
downloadlinux-f22b9c219a798e1bf11110a3d2733d883e6da059.tar.gz
linux-f22b9c219a798e1bf11110a3d2733d883e6da059.tar.bz2
linux-f22b9c219a798e1bf11110a3d2733d883e6da059.zip
s390/test_unwind: fix CALL_ON_STACK tests
The CALL_ON_STACK tests use the no_dat stack to switch to a different stack for unwinding tests. If an interrupt or machine check happens while using that stack, and previously being on the async stack, the interrupt / machine check entry code (SWITCH_ASYNC) will assume that the previous context did not use the async stack and happily use the async stack again. This will lead to stack corruption of the previous context. To solve this disable both interrupts and machine checks before switching to the no_dat stack. Fixes: 7868249fbbc8 ("s390/test_unwind: add CALL_ON_STACK tests") Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/lib/test_unwind.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index 7c988994931f..6bad84c372dc 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -205,12 +205,15 @@ static noinline int unwindme_func3(struct unwindme *u)
/* This function must appear in the backtrace. */
static noinline int unwindme_func2(struct unwindme *u)
{
+ unsigned long flags;
int rc;
if (u->flags & UWM_SWITCH_STACK) {
- preempt_disable();
+ local_irq_save(flags);
+ local_mcck_disable();
rc = CALL_ON_STACK(unwindme_func3, S390_lowcore.nodat_stack, 1, u);
- preempt_enable();
+ local_mcck_enable();
+ local_irq_restore(flags);
return rc;
} else {
return unwindme_func3(u);