kernel: greatly simplify syscall handlers

We now have macros which should significantly reduce the amount of
boilerplate involved with defining system call handlers.

- Macros which define the proper prototype based on number of arguments
- "SIMPLE" variants which create handlers that don't need anything
  other than object verification

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-10-12 09:54:26 -07:00 committed by Anas Nashif
commit 225e4c0e76
15 changed files with 245 additions and 396 deletions

View file

@ -92,16 +92,7 @@ void _impl_k_alert_send(struct k_alert *alert)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_alert_send(u32_t alert, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(alert, K_OBJ_ALERT, ssf);
_impl_k_alert_send((struct k_alert *)alert);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_alert_send, K_OBJ_ALERT, struct k_alert *);
#endif
int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
@ -110,12 +101,9 @@ int _impl_k_alert_recv(struct k_alert *alert, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_alert_recv(u32_t alert, u32_t timeout, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER2(k_alert_recv, alert, timeout)
{
_SYSCALL_ARG2;
_SYSCALL_OBJ(alert, K_OBJ_ALERT, ssf);
_SYSCALL_OBJ(alert, K_OBJ_ALERT);
return _impl_k_alert_recv((struct k_alert *)alert, timeout);
}
#endif

View file

@ -87,11 +87,10 @@ extern void _thread_perms_all_set(struct _k_object *ko);
*
* @param expr Boolean expression to verify, a false result will trigger an
* oops
* @param ssf Syscall stack frame argument passed to the handler function
* @param fmt Printf-style format string (followed by appropriate variadic
* arguments) to print on verification failure
*/
#define _SYSCALL_VERIFY_MSG(expr, ssf, fmt, ...) \
#define _SYSCALL_VERIFY_MSG(expr, fmt, ...) \
do { \
if (!(expr)) { \
printk("FATAL: syscall %s failed check: " fmt "\n", \
@ -108,14 +107,12 @@ extern void _thread_perms_all_set(struct _k_object *ko);
*
* @param expr Boolean expression to verify, a false result will trigger an
* oops. A stringified version of this expression will be printed.
* @param ssf Syscall stack frame argument passed to the handler function
* arguments) to print on verification failure
*/
#define _SYSCALL_VERIFY(expr, ssf) _SYSCALL_VERIFY_MSG(expr, ssf, #expr)
#define _SYSCALL_VERIFY(expr) _SYSCALL_VERIFY_MSG(expr, #expr)
#define _SYSCALL_MEMORY(ptr, size, write, ssf) \
#define _SYSCALL_MEMORY(ptr, size, write) \
_SYSCALL_VERIFY_MSG(!_arch_buffer_validate((void *)ptr, size, write), \
ssf, "Memory region %p (size %u) %s access denied", \
"Memory region %p (size %u) %s access denied", \
(void *)(ptr), (u32_t)(size), \
write ? "write" : "read")
@ -132,10 +129,9 @@ extern void _thread_perms_all_set(struct _k_object *ko);
* @param size Size of the memory area
* @param write If the thread should be able to write to this memory, not just
* read it
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_MEMORY_READ(ptr, size, ssf) \
_SYSCALL_MEMORY(ptr, size, 0, ssf)
#define _SYSCALL_MEMORY_READ(ptr, size) \
_SYSCALL_MEMORY(ptr, size, 0)
/**
* @brief Runtime check that a user thread has write permission to a memory area
@ -150,20 +146,19 @@ extern void _thread_perms_all_set(struct _k_object *ko);
* @param size Size of the memory area
* @param write If the thread should be able to write to this memory, not just
* read it
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_MEMORY_WRITE(ptr, size, ssf) \
_SYSCALL_MEMORY(ptr, size, 1, ssf)
#define _SYSCALL_MEMORY_WRITE(ptr, size) \
_SYSCALL_MEMORY(ptr, size, 1)
#define _SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write, ssf) \
#define _SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \
do { \
u32_t product; \
_SYSCALL_VERIFY_MSG(!__builtin_umul_overflow((u32_t)(nmemb), \
(u32_t)(size), \
&product), ssf, \
&product), \
"%ux%u array is too large", \
(u32_t)(nmemb), (u32_t)(size)); \
_SYSCALL_MEMORY(ptr, product, write, ssf); \
_SYSCALL_MEMORY(ptr, product, write); \
} while (0)
/**
@ -176,10 +171,9 @@ extern void _thread_perms_all_set(struct _k_object *ko);
* @param ptr Memory area to examine
* @param nmemb Number of elements in the array
* @param size Size of each array element
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size, ssf) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0, ssf)
#define _SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0)
/**
* @brief Validate user thread has read/write permission for sized array
@ -191,10 +185,9 @@ extern void _thread_perms_all_set(struct _k_object *ko);
* @param ptr Memory area to examine
* @param nmemb Number of elements in the array
* @param size Size of each array element
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size, ssf) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1, ssf)
#define _SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \
_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1)
static inline int _obj_validation_check(void *obj, enum k_objects otype,
int init)
@ -214,10 +207,9 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
return ret;
}
#define _SYSCALL_IS_OBJ(ptr, type, init, ssf) \
#define _SYSCALL_IS_OBJ(ptr, type, init) \
_SYSCALL_VERIFY_MSG(!_obj_validation_check((void *)ptr, type, init), \
ssf, "object %p access denied", (void *)(ptr))
"object %p access denied", (void *)(ptr))
/**
* @brief Runtime check kernel object pointer for non-init functions
@ -228,10 +220,9 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
*
* @param ptr Untrusted kernel object pointer
* @param type Expected kernel object type
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_OBJ(ptr, type, ssf) \
_SYSCALL_IS_OBJ(ptr, type, 0, ssf)
#define _SYSCALL_OBJ(ptr, type) \
_SYSCALL_IS_OBJ(ptr, type, 0)
/**
* @brief Runtime check kernel object pointer for non-init functions
@ -242,28 +233,120 @@ static inline int _obj_validation_check(void *obj, enum k_objects otype,
*
* @param ptr Untrusted kernel object pointer
* @param type Expected kernel object type
* @param ssf Syscall stack frame argument passed to the handler function
*/
#define _SYSCALL_OBJ_INIT(ptr, type, ssf) \
_SYSCALL_IS_OBJ(ptr, type, 1, ssf)
#define _SYSCALL_OBJ_INIT(ptr, type) \
_SYSCALL_IS_OBJ(ptr, type, 1)
/* Convenience macros for handler implementations */
#define _SYSCALL_ARG0 ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); \
ARG_UNUSED(arg4); ARG_UNUSED(arg5); ARG_UNUSED(arg6)
/*
* Handler definition macros
*
* All handlers have the same prototype:
*
* u32_t _handler_APINAME(u32_t arg1, u32_t arg2, u32_t arg3,
* u32_t arg4, u32_t arg5, u32_t arg6, void *ssf);
*
* These make it much simpler to define handlers instead of typing out
* the bolierplate. The macros ensure that the seventh argument is named
* "ssf" as this is now referenced by various other _SYSCALL macros.
*
* The different variants here simply depend on how many of the 6 arguments
* passed in are really used.
*/
#define _SYSCALL_ARG1 ARG_UNUSED(arg2); ARG_UNUSED(arg3); ARG_UNUSED(arg4); \
ARG_UNUSED(arg5); ARG_UNUSED(arg6)
#define _SYSCALL_HANDLER0(name_) \
u32_t _handler_ ## name_(u32_t arg1 __unused, \
u32_t arg2 __unused, \
u32_t arg3 __unused, \
u32_t arg4 __unused, \
u32_t arg5 __unused, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_ARG2 ARG_UNUSED(arg3); ARG_UNUSED(arg4); ARG_UNUSED(arg5); \
ARG_UNUSED(arg6)
#define _SYSCALL_HANDLER1(name_, arg1_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2 __unused, \
u32_t arg3 __unused, \
u32_t arg4 __unused, \
u32_t arg5 __unused, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_ARG3 ARG_UNUSED(arg4); ARG_UNUSED(arg5); ARG_UNUSED(arg6)
#define _SYSCALL_HANDLER2(name_, arg1_, arg2_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3 __unused, \
u32_t arg4 __unused, \
u32_t arg5 __unused, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER3(name_, arg1_, arg2_, arg3_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
u32_t arg4 __unused, \
u32_t arg5 __unused, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_ARG4 ARG_UNUSED(arg5); ARG_UNUSED(arg6)
#define _SYSCALL_HANDLER4(name_, arg1_, arg2_, arg3_, arg4_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
u32_t arg4_, \
u32_t arg5 __unused, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER5(name_, arg1_, arg2_, arg3_, arg4_, arg5_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
u32_t arg4_, \
u32_t arg5_, \
u32_t arg6 __unused, \
void *ssf)
#define _SYSCALL_HANDLER6(name_, arg1_, arg2_, arg3_, arg4_, arg5_, arg6_) \
u32_t _handler_ ## name_(u32_t arg1_, \
u32_t arg2_, \
u32_t arg3_, \
u32_t arg4_, \
u32_t arg5_, \
u32_t arg6_, \
void *ssf)
/*
* Helper macros for a very common case: calls which just take one argument
* which is an initialized kernel object of a specific type. Verify the object
* and call the implementation.
*/
#define _SYSCALL_HANDLER1_SIMPLE(name_, obj_enum_, obj_type_) \
_SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \
return (u32_t)_impl_ ## name_((obj_type_)arg1); \
}
#define _SYSCALL_HANDLER1_SIMPLE_VOID(name_, obj_enum_, obj_type_) \
_SYSCALL_HANDLER1(name_, arg1) { \
_SYSCALL_OBJ(arg1, obj_enum_); \
_impl_ ## name_((obj_type_)arg1); \
return 0; \
}
#define _SYSCALL_HANDLER0_SIMPLE(name_) \
_SYSCALL_HANDLER0(name_) { \
return (u32_t)_impl_ ## name_(); \
}
#define _SYSCALL_HANDLER0_SIMPLE_VOID(name_) \
_SYSCALL_HANDLER0(name_) { \
_impl_ ## name_(); \
return 0; \
}
#define _SYSCALL_ARG5 ARG_UNUSED(arg6)
#endif /* _ASMLANGUAGE */
#endif /* CONFIG_USERSPACE */

View file

@ -64,13 +64,10 @@ void _impl_k_msgq_init(struct k_msgq *q, char *buffer,
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_msgq_init(u32_t q, u32_t buffer, u32_t msg_size,
u32_t max_msgs, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER4(k_msgq_init, q, buffer, msg_size, max_msgs)
{
_SYSCALL_ARG4;
_SYSCALL_OBJ_INIT(q, K_OBJ_MSGQ, ssf);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, max_msgs, msg_size, ssf);
_SYSCALL_OBJ_INIT(q, K_OBJ_MSGQ);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, max_msgs, msg_size);
_impl_k_msgq_init((struct k_msgq *)q, (char *)buffer, msg_size,
max_msgs);
@ -127,14 +124,12 @@ int _impl_k_msgq_put(struct k_msgq *q, void *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_msgq_put(u32_t msgq_p, u32_t data, u32_t timeout,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_msgq_put, msgq_p, data, timeout)
{
struct k_msgq *q = (struct k_msgq *)msgq_p;
_SYSCALL_ARG3;
_SYSCALL_OBJ(q, K_OBJ_MSGQ, ssf);
_SYSCALL_MEMORY_READ(data, q->msg_size, ssf);
_SYSCALL_OBJ(q, K_OBJ_MSGQ);
_SYSCALL_MEMORY_READ(data, q->msg_size);
return _impl_k_msgq_put(q, (void *)data, timeout);
}
@ -195,14 +190,12 @@ int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_msgq_get(u32_t msgq_p, u32_t data, u32_t timeout,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_msgq_get, msgq_p, data, timeout)
{
struct k_msgq *q = (struct k_msgq *)msgq_p;
_SYSCALL_ARG3;
_SYSCALL_OBJ(q, K_OBJ_MSGQ, ssf);
_SYSCALL_MEMORY_WRITE(data, q->msg_size, ssf);
_SYSCALL_OBJ(q, K_OBJ_MSGQ);
_SYSCALL_MEMORY_WRITE(data, q->msg_size);
return _impl_k_msgq_get(q, (void *)data, timeout);
}
@ -227,34 +220,7 @@ void _impl_k_msgq_purge(struct k_msgq *q)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_msgq_purge(u32_t q, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(q, K_OBJ_MSGQ, ssf);
_impl_k_msgq_purge((struct k_msgq *)q);
return 0;
}
u32_t _handler_k_msgq_num_free_get(u32_t q, u32_t arg2, u32_t arg3, u32_t arg4,
u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(q, K_OBJ_MSGQ, ssf);
return _impl_k_msgq_num_free_get((struct k_msgq *)q);
}
u32_t _handler_k_msgq_num_used_get(u32_t q, u32_t arg2, u32_t arg3, u32_t arg4,
u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(q, K_OBJ_MSGQ, ssf);
return _impl_k_msgq_num_used_get((struct k_msgq *)q);
}
#endif /* CONFIG_USERSPACE */
_SYSCALL_HANDLER1_SIMPLE_VOID(k_msgq_purge, K_OBJ_MSGQ, struct k_msgq *);
_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_free_get, K_OBJ_MSGQ, struct k_msgq *);
_SYSCALL_HANDLER1_SIMPLE(k_msgq_num_used_get, K_OBJ_MSGQ, struct k_msgq *);
#endif

View file

@ -82,12 +82,9 @@ void _impl_k_mutex_init(struct k_mutex *mutex)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_mutex_init(u32_t mutex, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER1(k_mutex_init, mutex)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX, ssf);
_SYSCALL_OBJ_INIT(mutex, K_OBJ_MUTEX);
_impl_k_mutex_init((struct k_mutex *)mutex);
return 0;
@ -203,12 +200,9 @@ int _impl_k_mutex_lock(struct k_mutex *mutex, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_mutex_lock(u32_t mutex, u32_t timeout, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER2(k_mutex_lock, mutex, timeout)
{
_SYSCALL_ARG2;
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX, ssf);
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX);
return _impl_k_mutex_lock((struct k_mutex *)mutex, (s32_t)timeout);
}
#endif
@ -267,13 +261,5 @@ void _impl_k_mutex_unlock(struct k_mutex *mutex)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_mutex_unlock(u32_t mutex, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(mutex, K_OBJ_MUTEX, ssf);
_impl_k_mutex_unlock((struct k_mutex *)mutex);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_mutex_unlock, K_OBJ_MUTEX, struct k_mutex *);
#endif

View file

@ -141,13 +141,10 @@ void _impl_k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_pipe_init(u32_t pipe, u32_t buffer, u32_t size,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_pipe_init, pipe, buffer, size)
{
_SYSCALL_ARG3;
_SYSCALL_OBJ_INIT(pipe, K_OBJ_PIPE, ssf);
_SYSCALL_MEMORY_WRITE(buffer, size, ssf);
_SYSCALL_OBJ_INIT(pipe, K_OBJ_PIPE);
_SYSCALL_MEMORY_WRITE(buffer, size);
_impl_k_pipe_init((struct k_pipe *)pipe, (unsigned char *)buffer,
size);
@ -687,17 +684,16 @@ int _impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_pipe_get(u32_t pipe, u32_t data, u32_t bytes_to_read,
u32_t bytes_read_p, u32_t min_xfer_p,
u32_t timeout, void *ssf)
_SYSCALL_HANDLER6(k_pipe_get,
pipe, data, bytes_to_read, bytes_read_p, min_xfer_p, timeout)
{
size_t *bytes_read = (size_t *)bytes_read_p;
size_t min_xfer = (size_t)min_xfer_p;
_SYSCALL_OBJ(pipe, K_OBJ_PIPE, ssf);
_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read), ssf);
_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read, ssf);
_SYSCALL_VERIFY(min_xfer <= bytes_to_read, ssf);
_SYSCALL_OBJ(pipe, K_OBJ_PIPE);
_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read));
_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read);
_SYSCALL_VERIFY(min_xfer <= bytes_to_read);
return _impl_k_pipe_get((struct k_pipe *)pipe, (void *)data,
bytes_to_read, bytes_read, min_xfer,
@ -717,17 +713,16 @@ int _impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_pipe_put(u32_t pipe, u32_t data, u32_t bytes_to_write,
u32_t bytes_written_p, u32_t min_xfer_p,
u32_t timeout, void *ssf)
_SYSCALL_HANDLER6(k_pipe_put, pipe, data, bytes_to_write, bytes_written_p,
min_xfer_p, timeout)
{
size_t *bytes_written = (size_t *)bytes_written_p;
size_t min_xfer = (size_t)min_xfer_p;
_SYSCALL_OBJ(pipe, K_OBJ_PIPE, ssf);
_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written), ssf);
_SYSCALL_MEMORY_READ((void *)data, bytes_to_write, ssf);
_SYSCALL_VERIFY(min_xfer <= bytes_to_write, ssf);
_SYSCALL_OBJ(pipe, K_OBJ_PIPE);
_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written));
_SYSCALL_MEMORY_READ((void *)data, bytes_to_write);
_SYSCALL_VERIFY(min_xfer <= bytes_to_write);
return _impl_k_pipe_put((struct k_pipe *)pipe, (void *)data,
bytes_to_write, bytes_written, min_xfer,

View file

@ -264,18 +264,8 @@ int _impl_k_thread_priority_get(k_tid_t thread)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_priority_get(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
struct k_thread *thread;
_SYSCALL_ARG1;
thread = (struct k_thread *)arg1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
return (u32_t)_impl_k_thread_priority_get(thread);
}
_SYSCALL_HANDLER1_SIMPLE(k_thread_priority_get, K_OBJ_THREAD,
struct k_thread *);
#endif
void _impl_k_thread_priority_set(k_tid_t tid, int prio)
@ -295,14 +285,10 @@ void _impl_k_thread_priority_set(k_tid_t tid, int prio)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_priority_set(u32_t thread, u32_t prio, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER2(k_thread_priority_set, thread, prio)
{
_SYSCALL_ARG2;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_SYSCALL_VERIFY_MSG(_VALID_PRIO(prio, NULL), ssf,
_SYSCALL_OBJ(thread, K_OBJ_THREAD);
_SYSCALL_VERIFY_MSG(_VALID_PRIO(prio, NULL),
"invalid thread priority %d", (int)prio);
_impl_k_thread_priority_set((k_tid_t)thread, prio);
return 0;
@ -354,14 +340,7 @@ void _impl_k_yield(void)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_yield(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG0;
_impl_k_yield();
return 0;
}
_SYSCALL_HANDLER0_SIMPLE_VOID(k_yield);
#endif
void _impl_k_sleep(s32_t duration)
@ -395,14 +374,14 @@ void _impl_k_sleep(s32_t duration)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_sleep(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER1(k_sleep, duration)
{
_SYSCALL_ARG1;
_SYSCALL_VERIFY_MSG(arg1 != K_FOREVER, ssf,
/* FIXME there were some discussions recently on whether we should
* relax this, thread would be unscheduled until k_wakeup issued
*/
_SYSCALL_VERIFY_MSG(duration != K_FOREVER,
"sleeping forever not allowed");
_impl_k_sleep(arg1);
_impl_k_sleep(duration);
return 0;
}
@ -433,15 +412,7 @@ void _impl_k_wakeup(k_tid_t thread)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_wakeup(u32_t thread, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_impl_k_wakeup((k_tid_t)thread);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_wakeup, K_OBJ_THREAD, k_tid_t);
#endif
k_tid_t _impl_k_current_get(void)
@ -450,13 +421,7 @@ k_tid_t _impl_k_current_get(void)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_current_get(u32_t arg1, u32_t arg2, u32_t arg3, u32_t arg4,
u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG0;
return (u32_t)_impl_k_current_get();
}
_SYSCALL_HANDLER0_SIMPLE(k_current_get);
#endif
#ifdef CONFIG_TIMESLICING
@ -528,12 +493,5 @@ int _impl_k_is_preempt_thread(void)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_is_preempt_thread(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
_SYSCALL_ARG0;
return _impl_k_is_preempt_thread();
}
_SYSCALL_HANDLER0_SIMPLE(k_is_preempt_thread);
#endif

View file

@ -71,14 +71,11 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_sem_init(u32_t sem_ptr, u32_t initial_count, u32_t limit,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_sem_init, sem, initial_count, limit)
{
_SYSCALL_ARG3;
_SYSCALL_OBJ_INIT(sem_ptr, K_OBJ_SEM, ssf);
_SYSCALL_VERIFY(limit != 0, ssf);
_impl_k_sem_init((struct k_sem *)sem_ptr, initial_count, limit);
_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM);
_SYSCALL_VERIFY(limit != 0);
_impl_k_sem_init((struct k_sem *)sem, initial_count, limit);
return 0;
}
#endif
@ -156,17 +153,8 @@ void _impl_k_sem_give(struct k_sem *sem)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_sem_give(u32_t sem_ptr, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(sem_ptr, K_OBJ_SEM, ssf);
_impl_k_sem_give((struct k_sem *)sem_ptr);
return 0;
}
#endif /* CONFIG_USERSPACE */
_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_give, K_OBJ_SEM, struct k_sem *);
#endif
int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
{
@ -191,32 +179,12 @@ int _impl_k_sem_take(struct k_sem *sem, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_sem_take(u32_t sem_ptr, u32_t timeout, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER2(k_sem_take, sem, timeout)
{
_SYSCALL_ARG2;
_SYSCALL_OBJ(sem_ptr, K_OBJ_SEM, ssf);
return _impl_k_sem_take((struct k_sem *)sem_ptr, timeout);
_SYSCALL_OBJ(sem, K_OBJ_SEM);
return _impl_k_sem_take((struct k_sem *)sem, timeout);
}
u32_t _handler_k_sem_reset(u32_t sem_ptr, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(sem_ptr, K_OBJ_SEM, ssf);
_impl_k_sem_reset((struct k_sem *)sem_ptr);
return 0;
}
u32_t _handler_k_sem_count_get(u32_t sem_ptr, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(sem_ptr, K_OBJ_SEM, ssf);
return _impl_k_sem_count_get((struct k_sem *)sem_ptr);
}
#endif /* CONFIG_USERSPACE */
_SYSCALL_HANDLER1_SIMPLE_VOID(k_sem_reset, K_OBJ_SEM, struct k_sem *);
_SYSCALL_HANDLER1_SIMPLE(k_sem_count_get, K_OBJ_SEM, struct k_sem *);
#endif

View file

@ -56,15 +56,14 @@ void _impl_k_stack_init(struct k_stack *stack, u32_t *buffer, int num_entries)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_stack_init(u32_t stack, u32_t buffer, u32_t num_entries_p,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_stack_init, stack, buffer, num_entries_p)
{
int num_entries = (int)num_entries_p;
/* FIXME why is 'num_entries' signed?? */
_SYSCALL_VERIFY(num_entries > 0, ssf);
_SYSCALL_OBJ_INIT(stack, K_OBJ_STACK, ssf);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, num_entries, sizeof(u32_t), ssf);
_SYSCALL_VERIFY(num_entries > 0);
_SYSCALL_OBJ_INIT(stack, K_OBJ_STACK);
_SYSCALL_MEMORY_ARRAY_WRITE(buffer, num_entries, sizeof(u32_t));
_impl_k_stack_init((struct k_stack *)stack, (u32_t *)buffer,
num_entries);
@ -103,14 +102,12 @@ void _impl_k_stack_push(struct k_stack *stack, u32_t data)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_stack_push(u32_t stack_p, u32_t data, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER2(k_stack_push, stack_p, data)
{
struct k_stack *stack = (struct k_stack *)stack_p;
_SYSCALL_ARG2;
_SYSCALL_OBJ(stack, K_OBJ_STACK, ssf);
_SYSCALL_VERIFY_MSG(stack->next != stack->top, ssf, "stack is full");
_SYSCALL_OBJ(stack, K_OBJ_STACK);
_SYSCALL_VERIFY_MSG(stack->next != stack->top, "stack is full");
_impl_k_stack_push(stack, data);
return 0;
@ -146,16 +143,12 @@ int _impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_stack_pop(u32_t stack, u32_t data, u32_t timeout,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_stack_pop, stack, data, timeout)
{
_SYSCALL_ARG3;
_SYSCALL_OBJ(stack, K_OBJ_STACK, ssf);
_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t), ssf);
_SYSCALL_OBJ(stack, K_OBJ_STACK);
_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t));
return _impl_k_stack_pop((struct k_stack *)stack, (u32_t *)data,
timeout);
}
#endif

View file

@ -79,13 +79,10 @@ u32_t _impl_k_uptime_get_32(void)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_uptime_get_32(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER0(k_uptime_get_32)
{
_SYSCALL_ARG0;
#ifdef CONFIG_TICKLESS_KERNEL
_SYSCALL_VERIFY(_sys_clock_always_on, ssf);
_SYSCALL_VERIFY(_sys_clock_always_on);
#endif
return _impl_k_uptime_get_32();
}

View file

@ -119,13 +119,9 @@ void _impl_k_thread_custom_data_set(void *value)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_custom_data_set(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER1(k_thread_custom_data_set, data)
{
_SYSCALL_ARG1;
_impl_k_thread_custom_data_set((void *)arg1);
_impl_k_thread_custom_data_set((void *)data);
return 0;
}
#endif
@ -136,14 +132,7 @@ void *_impl_k_thread_custom_data_get(void)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_custom_data_get(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
_SYSCALL_ARG0;
return (u32_t)_impl_k_thread_custom_data_get();
}
_SYSCALL_HANDLER0_SIMPLE(k_thread_custom_data_get);
#endif /* CONFIG_USERSPACE */
#endif /* CONFIG_THREAD_CUSTOM_DATA */
@ -259,15 +248,7 @@ void _impl_k_thread_start(struct k_thread *thread)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_start(u32_t thread, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_impl_k_thread_start((struct k_thread *)thread);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_start, K_OBJ_THREAD, struct k_thread *);
#endif
#endif
@ -347,14 +328,7 @@ int _impl_k_thread_cancel(k_tid_t tid)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_cancel(u32_t thread, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
return _impl_k_thread_cancel((struct k_thread *)thread);
}
_SYSCALL_HANDLER1_SIMPLE(k_thread_cancel, K_OBJ_THREAD, struct k_thread *);
#endif
static inline int is_in_any_group(struct _static_thread_data *thread_data,
@ -428,15 +402,7 @@ void _impl_k_thread_suspend(struct k_thread *thread)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_suspend(u32_t thread, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_impl_k_thread_suspend((k_tid_t)thread);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_suspend, K_OBJ_THREAD, k_tid_t);
#endif
void _k_thread_single_resume(struct k_thread *thread)
@ -458,15 +424,7 @@ void _impl_k_thread_resume(struct k_thread *thread)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_resume(u32_t thread, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_impl_k_thread_resume((k_tid_t)thread);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_thread_resume, K_OBJ_THREAD, k_tid_t);
#endif
void _k_thread_single_abort(struct k_thread *thread)

View file

@ -47,12 +47,11 @@ void _impl_k_thread_abort(k_tid_t thread)
#endif
#ifdef CONFIG_USERSPACE
u32_t _handler_k_thread_abort(u32_t thread_p, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER1(k_thread_abort, thread_p)
{
struct k_thread *thread = (struct k_thread *)thread_p;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL), ssf,
_SYSCALL_OBJ(thread, K_OBJ_THREAD);
_SYSCALL_VERIFY_MSG(!(thread->base.user_options & K_ESSENTIAL),
"aborting essential thread %p", thread);
_impl_k_thread_abort((struct k_thread *)thread);

View file

@ -132,18 +132,16 @@ void _impl_k_timer_start(struct k_timer *timer, s32_t duration, s32_t period)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_timer_start(u32_t timer, u32_t duration_p, u32_t period_p,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER3(k_timer_start, timer, duration_p, period_p)
{
s32_t duration, period;
_SYSCALL_ARG3;
duration = (s32_t)duration_p;
period = (s32_t)period_p;
_SYSCALL_VERIFY(duration >= 0 && period >= 0 &&
(duration != 0 || period != 0), ssf);
_SYSCALL_OBJ(timer, K_OBJ_TIMER, ssf);
(duration != 0 || period != 0));
_SYSCALL_OBJ(timer, K_OBJ_TIMER);
_impl_k_timer_start((struct k_timer *)timer, duration, period);
return 0;
}
@ -179,15 +177,7 @@ void _impl_k_timer_stop(struct k_timer *timer)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_timer_stop(u32_t timer, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(timer, K_OBJ_TIMER, ssf);
_impl_k_timer_stop((struct k_timer *)timer);
return 0;
}
_SYSCALL_HANDLER1_SIMPLE_VOID(k_timer_stop, K_OBJ_TIMER, struct k_timer *);
#endif
u32_t _impl_k_timer_status_get(struct k_timer *timer)
@ -202,15 +192,7 @@ u32_t _impl_k_timer_status_get(struct k_timer *timer)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_timer_status_get(u32_t timer, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(timer, K_OBJ_TIMER, ssf);
return _impl_k_timer_status_get((struct k_timer *)timer);
}
_SYSCALL_HANDLER1_SIMPLE(k_timer_status_get, K_OBJ_TIMER, struct k_timer *);
#endif
u32_t _impl_k_timer_status_sync(struct k_timer *timer)
@ -243,15 +225,7 @@ u32_t _impl_k_timer_status_sync(struct k_timer *timer)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_timer_status_sync(u32_t timer, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(timer, K_OBJ_TIMER, ssf);
return _impl_k_timer_status_sync((struct k_timer *)timer);
}
_SYSCALL_HANDLER1_SIMPLE(k_timer_status_sync, K_OBJ_TIMER, struct k_timer *);
#endif
s32_t _timeout_remaining_get(struct _timeout *timeout)
@ -280,3 +254,15 @@ s32_t _timeout_remaining_get(struct _timeout *timeout)
irq_unlock(key);
return __ticks_to_ms(remaining_ticks);
}
#ifdef CONFIG_USERSPACE
_SYSCALL_HANDLER1_SIMPLE(k_timer_remaining_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER1_SIMPLE(k_timer_user_data_get, K_OBJ_TIMER, struct k_timer *);
_SYSCALL_HANDLER2(k_timer_user_data_set, timer, user_data)
{
_SYSCALL_OBJ(timer, K_OBJ_TIMER);
_impl_k_timer_user_data_set((struct k_timer *)timer, (void *)user_data);
return 0;
}
#endif

View file

@ -35,31 +35,24 @@ static struct _k_object *validate_any_object(void *obj)
* To avoid double _k_object_find() lookups, we don't call the implementation
* function, but call a level deeper.
*/
u32_t _handler_k_object_access_grant(u32_t object, u32_t thread, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER2(k_object_access_grant, object, thread)
{
_SYSCALL_ARG2;
struct _k_object *ko;
_SYSCALL_OBJ(thread, K_OBJ_THREAD, ssf);
_SYSCALL_OBJ(thread, K_OBJ_THREAD);
ko = validate_any_object((void *)object);
_SYSCALL_VERIFY_MSG(ko, ssf, "object %p access denied", (void *)object);
_SYSCALL_VERIFY_MSG(ko, "object %p access denied", (void *)object);
_thread_perms_set(ko, (struct k_thread *)thread);
return 0;
}
u32_t _handler_k_object_access_all_grant(u32_t object, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER1(k_object_access_all_grant, object)
{
_SYSCALL_ARG1;
struct _k_object *ko;
ko = validate_any_object((void *)object);
_SYSCALL_VERIFY_MSG(ko, ssf, "object %p access denied", (void *)object);
_SYSCALL_VERIFY_MSG(ko, "object %p access denied", (void *)object);
_thread_perms_all_set(ko);
return 0;

View file

@ -276,12 +276,9 @@ void _impl_k_str_out(char *c, size_t n)
}
#ifdef CONFIG_USERSPACE
u32_t _handler_k_str_out(u32_t c, u32_t n, u32_t arg3, u32_t arg4,
u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER2(k_str_out, c, n)
{
_SYSCALL_ARG2;
_SYSCALL_MEMORY(c, n, 0, ssf);
_SYSCALL_MEMORY_READ(c, n);
_impl_k_str_out((char *)c, n);
return 0;

View file

@ -7,47 +7,29 @@
#include <sensor.h>
#include <syscall_handler.h>
u32_t _handler_sensor_attr_set(u32_t dev, u32_t chan, u32_t attr,
u32_t val, u32_t arg5, u32_t arg6, void *ssf)
_SYSCALL_HANDLER4(sensor_attr_set, dev, chan, attr, val)
{
_SYSCALL_ARG4;
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR, ssf);
_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value), ssf);
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
_SYSCALL_MEMORY_READ(val, sizeof(struct sensor_value));
return _impl_sensor_attr_set((struct device *)dev, chan, attr,
(const struct sensor_value *)val);
}
u32_t _handler_sensor_sample_fetch(u32_t dev, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER1_SIMPLE(sensor_sample_fetch, K_OBJ_DRIVER_SENSOR,
struct device *);
_SYSCALL_HANDLER2(sensor_semple_fetch_chan, dev, type)
{
_SYSCALL_ARG1;
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR, ssf);
return _impl_sensor_sample_fetch((struct device *)dev);
}
u32_t _handler_sensor_sample_fetch_chan(u32_t dev, u32_t type, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
{
_SYSCALL_ARG2;
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR, ssf);
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
return _impl_sensor_sample_fetch_chan((struct device *)dev, type);
}
u32_t _handler_sensor_channel_get(u32_t dev, u32_t chan, u32_t val,
u32_t arg4, u32_t arg5, u32_t arg6,
void *ssf)
_SYSCALL_HANDLER3(sensor_channel_get, dev, chan, val)
{
_SYSCALL_ARG3;
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR, ssf);
_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value), ssf);
_SYSCALL_OBJ(dev, K_OBJ_DRIVER_SENSOR);
_SYSCALL_MEMORY_WRITE(val, sizeof(struct sensor_value));
return _impl_sensor_channel_get((struct device *)dev, chan,
(struct sensor_value *)val);
}