Skip to content

Commit 7868249

Browse files
author
Vasily Gorbik
committed
s390/test_unwind: add CALL_ON_STACK tests
Add CALL_ON_STACK helper testing. Tests make sure that we can unwind from switched stack to original one up to task pt_regs (nodat -> task stack). UWM_SWITCH_STACK could not be used together with UWM_THREAD because get_stack_info explicitly restricts unwinding to task stack if task != current. Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 4ac24c0 commit 7868249

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

arch/s390/lib/test_unwind.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
4343
int ret = 0;
4444
char *bt;
4545

46-
bt = kmalloc(BT_BUF_SIZE, GFP_KERNEL);
46+
bt = kmalloc(BT_BUF_SIZE, GFP_ATOMIC);
4747
if (!bt) {
4848
pr_err("failed to allocate backtrace buffer\n");
4949
return -ENOMEM;
@@ -98,11 +98,12 @@ struct unwindme {
9898
};
9999

100100
/* Values of unwindme.flags. */
101-
#define UWM_DEFAULT 0x0
102-
#define UWM_THREAD 0x1 /* Unwind a separate task. */
103-
#define UWM_REGS 0x2 /* Pass regs to test_unwind(). */
104-
#define UWM_SP 0x4 /* Pass sp to test_unwind(). */
105-
#define UWM_CALLER 0x8 /* Unwind starting from caller. */
101+
#define UWM_DEFAULT 0x0
102+
#define UWM_THREAD 0x1 /* Unwind a separate task. */
103+
#define UWM_REGS 0x2 /* Pass regs to test_unwind(). */
104+
#define UWM_SP 0x4 /* Pass sp to test_unwind(). */
105+
#define UWM_CALLER 0x8 /* Unwind starting from caller. */
106+
#define UWM_SWITCH_STACK 0x10 /* Use CALL_ON_STACK. */
106107

107108
static __always_inline unsigned long get_psw_addr(void)
108109
{
@@ -146,7 +147,16 @@ static noinline int unwindme_func3(struct unwindme *u)
146147
/* This function must appear in the backtrace. */
147148
static noinline int unwindme_func2(struct unwindme *u)
148149
{
149-
return unwindme_func3(u);
150+
int rc;
151+
152+
if (u->flags & UWM_SWITCH_STACK) {
153+
preempt_disable();
154+
rc = CALL_ON_STACK(unwindme_func3, S390_lowcore.nodat_stack, 1, u);
155+
preempt_enable();
156+
return rc;
157+
} else {
158+
return unwindme_func3(u);
159+
}
150160
}
151161

152162
/* This function must follow unwindme_func2 in the backtrace. */
@@ -215,9 +225,11 @@ do { \
215225
TEST(UWM_DEFAULT);
216226
TEST(UWM_SP);
217227
TEST(UWM_REGS);
228+
TEST(UWM_SWITCH_STACK);
218229
TEST(UWM_SP | UWM_REGS);
219230
TEST(UWM_CALLER | UWM_SP);
220231
TEST(UWM_CALLER | UWM_SP | UWM_REGS);
232+
TEST(UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK);
221233
TEST(UWM_THREAD);
222234
TEST(UWM_THREAD | UWM_SP);
223235
TEST(UWM_THREAD | UWM_CALLER | UWM_SP);

0 commit comments

Comments
 (0)