Commit 7868249f authored by Vasily Gorbik's avatar Vasily Gorbik
Browse files

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: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 4ac24c09
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
	int ret = 0;
	char *bt;

	bt = kmalloc(BT_BUF_SIZE, GFP_KERNEL);
	bt = kmalloc(BT_BUF_SIZE, GFP_ATOMIC);
	if (!bt) {
		pr_err("failed to allocate backtrace buffer\n");
		return -ENOMEM;
@@ -103,6 +103,7 @@ struct unwindme {
#define UWM_REGS		0x2	/* Pass regs to test_unwind(). */
#define UWM_SP			0x4	/* Pass sp to test_unwind(). */
#define UWM_CALLER		0x8	/* Unwind starting from caller. */
#define UWM_SWITCH_STACK	0x10	/* Use CALL_ON_STACK. */

static __always_inline unsigned long get_psw_addr(void)
{
@@ -146,8 +147,17 @@ static noinline int unwindme_func3(struct unwindme *u)
/* This function must appear in the backtrace. */
static noinline int unwindme_func2(struct unwindme *u)
{
	int rc;

	if (u->flags & UWM_SWITCH_STACK) {
		preempt_disable();
		rc = CALL_ON_STACK(unwindme_func3, S390_lowcore.nodat_stack, 1, u);
		preempt_enable();
		return rc;
	} else {
		return unwindme_func3(u);
	}
}

/* This function must follow unwindme_func2 in the backtrace. */
static noinline int unwindme_func1(void *u)
@@ -215,9 +225,11 @@ do { \
	TEST(UWM_DEFAULT);
	TEST(UWM_SP);
	TEST(UWM_REGS);
	TEST(UWM_SWITCH_STACK);
	TEST(UWM_SP | UWM_REGS);
	TEST(UWM_CALLER | UWM_SP);
	TEST(UWM_CALLER | UWM_SP | UWM_REGS);
	TEST(UWM_CALLER | UWM_SP | UWM_REGS | UWM_SWITCH_STACK);
	TEST(UWM_THREAD);
	TEST(UWM_THREAD | UWM_SP);
	TEST(UWM_THREAD | UWM_CALLER | UWM_SP);