Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backport v1.14] push ssf to thread privileged stack to complete stack frame #29536

Merged
merged 2 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions arch/arm/core/userspace.S
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,9 @@ SECTION_FUNC(TEXT, z_arm_do_syscall)
b dispatch_syscall

valid_syscall:
mov ip, sp
/* push args to complete stack frame */
push {r4,r5}
push {r4,r5,ip}

dispatch_syscall:
ldr ip, =_k_syscall_table
Expand All @@ -244,7 +245,7 @@ dispatch_syscall:
blx ip

/* restore LR */
ldr lr, [sp,#12]
ldr lr, [sp,#16]

#if defined(CONFIG_BUILTIN_STACK_GUARD)
/* clear stack limit (stack protection not required in user mode) */
Expand All @@ -253,7 +254,7 @@ dispatch_syscall:
#endif

/* set stack back to unprivileged stack */
ldr ip, [sp,#8]
ldr ip, [sp,#12]
msr PSP, ip

push {r0, r1}
Expand Down
33 changes: 33 additions & 0 deletions tests/kernel/mem_protect/syscalls/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,31 @@ Z_SYSCALL_HANDLER(to_copy, dest)
return z_user_to_copy((char *)dest, user_string, BUF_SIZE);
}

unsigned int z_impl_more_args(unsigned int arg1, unsigned int arg2,
unsigned int arg3, unsigned int arg4,
unsigned int arg5, unsigned int arg6,
unsigned int arg7)
{
unsigned int ret = 0x4ef464cc;
unsigned int args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };

for (int i = 0; i < ARRAY_SIZE(args); i++) {
ret += args[i];
ret = (ret << 11) | (ret >> 5);
}

return ret;
}

Z_SYSCALL_HANDLER(more_args, arg1, arg2, arg3, arg4, arg5, more_args_ptr)
{
struct _syscall_7_args *margs =
(struct _syscall_7_args *)more_args_ptr;

return z_impl_more_args(arg1, arg2, arg3, arg4,
arg5, margs->arg6, margs->arg7);
}

/**
* @brief Test to demonstrate usage of z_user_string_nlen()
*
Expand Down Expand Up @@ -199,6 +224,13 @@ void test_to_copy(void)
zassert_equal(ret, 0, "string should have matched");
}

void test_more_args(void)
{
zassert_equal(more_args(1, 2, 3, 4, 5, 6, 7),
z_impl_more_args(1, 2, 3, 4, 5, 6, 7),
"syscall didn't match impl");
}

K_MEM_POOL_DEFINE(test_pool, BUF_SIZE, BUF_SIZE, 4, 4);

void test_main(void)
Expand All @@ -211,6 +243,7 @@ void test_main(void)
ztest_unit_test(test_string_nlen),
ztest_user_unit_test(test_string_nlen),
ztest_user_unit_test(test_to_copy),
ztest_user_unit_test(test_more_args),
ztest_user_unit_test(test_user_string_copy),
ztest_user_unit_test(test_user_string_alloc_copy));
ztest_run_test_suite(syscalls);
Expand Down
5 changes: 5 additions & 0 deletions tests/kernel/mem_protect/syscalls/src/test_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ __syscall int to_copy(char *dest);

__syscall size_t string_nlen(char *src, size_t maxlen, int *err);

__syscall unsigned int more_args(unsigned int arg1, unsigned int arg2,
unsigned int arg3, unsigned int arg4,
unsigned int arg5, unsigned int arg6,
unsigned int arg7);

#include <syscalls/test_syscalls.h>

#endif /* _TEST_SYSCALLS_H_ */