kernel: allow up to 6 arguments for system calls
A quick look at "man syscall" shows that in Linux, all architectures support at least 6 argument system calls, with a few supporting 7. We can at least do 6 in Zephyr. x86 port modified to use EBP register to carry the 6th system call argument. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
83643a2266
commit
1956f09590
5 changed files with 43 additions and 14 deletions
|
@ -35,6 +35,7 @@ _id_ok:
|
|||
* for _k_syscall_handler_t functions
|
||||
*/
|
||||
push %esp /* ssf */
|
||||
push %ebp /* arg6 */
|
||||
push %edi /* arg5 */
|
||||
push %ebx /* arg4 */
|
||||
#ifndef CONFIG_X86_IAMCU
|
||||
|
@ -63,11 +64,11 @@ _id_ok:
|
|||
pop %ebx
|
||||
pop %edi
|
||||
#ifndef CONFIG_X86_IAMCU
|
||||
/* Discard ssf, no free register to pop it into so we add instead */
|
||||
add $4, %esp
|
||||
/* Discard ssf and arg6 */
|
||||
add $8, %esp
|
||||
#else
|
||||
xor %edx, %edx /* Clean EDX */
|
||||
pop %ecx /* Clean ECX and get ssf arg off the stack */
|
||||
pop %ecx /* Clean ECX and get arg6 off the stack */
|
||||
pop %edx /* Clean EDX and get ssf off the stack */
|
||||
#endif
|
||||
iret
|
||||
|
||||
|
|
|
@ -560,6 +560,26 @@ extern struct task_state_segment _main_tss;
|
|||
* the entry stub clobbers EDX and ECX on IAMCU systems
|
||||
*/
|
||||
|
||||
static inline u32_t _arch_syscall_invoke6(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5, u32_t arg6,
|
||||
u32_t call_id)
|
||||
{
|
||||
u32_t ret;
|
||||
|
||||
__asm__ volatile("push %%ebp\n\t"
|
||||
"mov %[arg6], %%ebp\n\t"
|
||||
"int $0x80\n\t"
|
||||
"pop %%ebp\n\t"
|
||||
: "=a" (ret)
|
||||
#ifdef CONFIG_X86_IAMCU
|
||||
, "=d" (arg2), "=c" (arg3)
|
||||
#endif
|
||||
: "S" (call_id), "a" (arg1), "d" (arg2),
|
||||
"c" (arg3), "b" (arg4), "D" (arg5),
|
||||
[arg6] "r" (arg6));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u32_t _arch_syscall_invoke5(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5, u32_t call_id)
|
||||
{
|
||||
|
|
|
@ -3917,6 +3917,10 @@ static inline int _is_user_context(void)
|
|||
}
|
||||
|
||||
/* Interfaces for invoking system calls */
|
||||
static inline u32_t _arch_syscall_invoke6(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5, u32_t arg6,
|
||||
u32_t call_id);
|
||||
|
||||
static inline u32_t _arch_syscall_invoke5(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5,
|
||||
u32_t call_id);
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
* - Many kernel calls do no sanity checking of parameters other than
|
||||
* assertions. The handler must check all of these conditions using
|
||||
* _SYSCALL_ASSERT()
|
||||
* - If the system call has more then 5 arguments, then arg5 will be a pointer
|
||||
* to some struct containing arguments 5+. The struct itself needs to be
|
||||
* - If the system call has more than 6 arguments, then arg6 will be a pointer
|
||||
* to some struct containing arguments 6+. The struct itself needs to be
|
||||
* validated like any other buffer passed in from userspace, and its members
|
||||
* individually validated (if necessary) and then passed to the real
|
||||
* implementation like normal arguments
|
||||
|
@ -47,6 +47,7 @@
|
|||
* @param arg3 system call argument 3
|
||||
* @param arg4 system call argument 4
|
||||
* @param arg5 system call argument 5
|
||||
* @param arg6 system call argument 6
|
||||
* @param ssf System call stack frame pointer. Used to generate kernel oops
|
||||
* via _arch_syscall_oops_at(). Contents are arch-specific.
|
||||
* @return system call return value, or 0 if the system call implementation
|
||||
|
@ -54,7 +55,8 @@
|
|||
*
|
||||
*/
|
||||
typedef u32_t (*_k_syscall_handler_t)(u32_t arg1, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5, void *ssf);
|
||||
u32_t arg4, u32_t arg5, u32_t arg6,
|
||||
void *ssf);
|
||||
|
||||
|
||||
extern const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT];
|
||||
|
@ -94,18 +96,20 @@ extern const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT];
|
|||
|
||||
/* Convenience macros for handler implementations */
|
||||
#define _SYSCALL_ARG0 ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); \
|
||||
ARG_UNUSED(arg4); ARH_UNUSED(arg5)
|
||||
ARG_UNUSED(arg4); ARH_UNUSED(arg5); ARG_UNUSED(arg6)
|
||||
|
||||
#define _SYSCALL_ARG1 ARG_UNUSED(arg2); ARG_UNUSED(arg3); ARG_UNUSED(arg4); \
|
||||
ARG_UNUSED(arg5)
|
||||
ARG_UNUSED(arg5); ARG_UNUSED(arg6)
|
||||
|
||||
#define _SYSCALL_ARG2 ARG_UNUSED(arg3); ARG_UNUSED(arg4); ARG_UNUSED(arg5)
|
||||
#define _SYSCALL_ARG2 ARG_UNUSED(arg3); ARG_UNUSED(arg4); ARG_UNUSED(arg5); \
|
||||
ARG_UNUSED(arg6)
|
||||
|
||||
#define _SYSCALL_ARG3 ARG_UNUSED(arg4); ARG_UNUSED(arg5)
|
||||
|
||||
#define _SYSCALL_ARG4 ARG_UNUSED(arg5)
|
||||
#define _SYSCALL_ARG3 ARG_UNUSED(arg4); ARG_UNUSED(arg5); ARG_UNUSED(arg6)
|
||||
|
||||
|
||||
#define _SYSCALL_ARG4 ARG_UNUSED(arg5); ARG_UNUSED(arg6)
|
||||
|
||||
#define _SYSCALL_ARG5 ARG_UNUSED(arg6)
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* _ZEPHYR_SYSCALL_H_ */
|
||||
|
|
|
@ -183,7 +183,7 @@ void _k_object_init(void *object)
|
|||
}
|
||||
|
||||
static u32_t _syscall_bad_handler(u32_t bad_id, u32_t arg2, u32_t arg3,
|
||||
u32_t arg4, u32_t arg5, void *ssf)
|
||||
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
|
||||
{
|
||||
printk("Bad system call id %u invoked\n", bad_id);
|
||||
_arch_syscall_oops(ssf);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue