Module: xenomai-forge Branch: next Commit: b43e8facdb34fa3f9509b02bb8c5e8ca13c50e64 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=b43e8facdb34fa3f9509b02bb8c5e8ca13c50e64
Author: Philippe Gerum <r...@xenomai.org> Date: Wed May 28 15:09:57 2014 +0200 cobalt/kernel: drop 'any domain' exec mode bit for syscalls This mode is wrong by design for callers issuing syscalls from secondary mode: <thread[relaxed]> <syscall[harden]> handle_head_syscall() <syscall-handler> !access-fault! <kernel-page-fault-handler> handle_exception() ...root caller, won't migrate... !secondary-only code traversed in primary mode! The access fault could be triggered by any copy_to/from_user() present in the syscall handler, which means from most of them. The only sane and safe exec mode bit for such case is 'current', which won't cause any overhead to Xenomai threads already running in primary mode when issuing the syscall. Other contexts will have to roll back from primary to secondary mode via pipeline propagation (i.e. EVENT_PROPAGATE) before the syscall handler may run. --- .../cobalt/include/asm-generic/xenomai/syscall.h | 6 +- kernel/cobalt/posix/syscall.c | 106 ++++++++++---------- kernel/cobalt/shadow.c | 35 +++---- 3 files changed, 70 insertions(+), 77 deletions(-) diff --git a/kernel/cobalt/include/asm-generic/xenomai/syscall.h b/kernel/cobalt/include/asm-generic/xenomai/syscall.h index dcf6df7..2865778 100644 --- a/kernel/cobalt/include/asm-generic/xenomai/syscall.h +++ b/kernel/cobalt/include/asm-generic/xenomai/syscall.h @@ -42,7 +42,7 @@ struct xnsyscall { #define __xn_exec_lostage 0x1 /* Syscall must run into the Xenomai domain. */ #define __xn_exec_histage 0x2 -/* Shadow syscall; caller must be mapped. */ +/* Shadow syscall: caller must be mapped. */ #define __xn_exec_shadow 0x4 /* Switch back toggle; caller must return to its original mode. */ #define __xn_exec_switchback 0x8 @@ -54,8 +54,6 @@ struct xnsyscall { #define __xn_exec_adaptive 0x40 /* Do not restart syscall upon signal receipt. */ #define __xn_exec_norestart 0x80 -/* Context-agnostic syscall. Will actually run in Xenomai domain. */ -#define __xn_exec_any 0x0 /* Shorthand for shadow init syscall. */ #define __xn_exec_init __xn_exec_lostage /* Shorthand for shadow syscall in Xenomai space. */ @@ -69,7 +67,7 @@ struct xnsyscall { /* Shorthand for domain probing syscall */ #define __xn_exec_probing (__xn_exec_current|__xn_exec_adaptive) /* Shorthand for oneway trap - does not return to call site. */ -#define __xn_exec_oneway (__xn_exec_any|__xn_exec_norestart) +#define __xn_exec_oneway __xn_exec_norestart unsigned long flags; }; diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c index 52e9f8c..4c79f01 100644 --- a/kernel/cobalt/posix/syscall.c +++ b/kernel/cobalt/posix/syscall.c @@ -89,49 +89,49 @@ static struct xnsyscall cobalt_syscalls[] = { [0 ... __NR_COBALT_SYSCALLS-1] = SKINCALL_NI, SKINCALL_DEF(sc_cobalt_thread_create, cobalt_thread_create, init), SKINCALL_DEF(sc_cobalt_thread_setschedparam_ex, cobalt_thread_setschedparam_ex, conforming), - SKINCALL_DEF(sc_cobalt_thread_getschedparam_ex, cobalt_thread_getschedparam_ex, any), - SKINCALL_DEF(sc_cobalt_sched_weightprio, cobalt_sched_weighted_prio, any), + SKINCALL_DEF(sc_cobalt_thread_getschedparam_ex, cobalt_thread_getschedparam_ex, current), + SKINCALL_DEF(sc_cobalt_sched_weightprio, cobalt_sched_weighted_prio, current), SKINCALL_DEF(sc_cobalt_sched_yield, cobalt_sched_yield, primary), SKINCALL_DEF(sc_cobalt_thread_make_periodic, cobalt_thread_make_periodic_np, conforming), SKINCALL_DEF(sc_cobalt_thread_wait, cobalt_thread_wait_np, primary), SKINCALL_DEF(sc_cobalt_thread_set_mode, cobalt_thread_set_mode_np, primary), - SKINCALL_DEF(sc_cobalt_thread_set_name, cobalt_thread_set_name_np, any), + SKINCALL_DEF(sc_cobalt_thread_set_name, cobalt_thread_set_name_np, current), SKINCALL_DEF(sc_cobalt_thread_kill, cobalt_thread_kill, conforming), - SKINCALL_DEF(sc_cobalt_thread_getstat, cobalt_thread_stat, any), + SKINCALL_DEF(sc_cobalt_thread_getstat, cobalt_thread_stat, current), SKINCALL_DEF(sc_cobalt_thread_join, cobalt_thread_join, primary), - SKINCALL_DEF(sc_cobalt_sem_init, cobalt_sem_init, any), - SKINCALL_DEF(sc_cobalt_sem_destroy, cobalt_sem_destroy, any), - SKINCALL_DEF(sc_cobalt_sem_post, cobalt_sem_post, any), + SKINCALL_DEF(sc_cobalt_sem_init, cobalt_sem_init, current), + SKINCALL_DEF(sc_cobalt_sem_destroy, cobalt_sem_destroy, current), + SKINCALL_DEF(sc_cobalt_sem_post, cobalt_sem_post, current), SKINCALL_DEF(sc_cobalt_sem_wait, cobalt_sem_wait, primary), SKINCALL_DEF(sc_cobalt_sem_timedwait, cobalt_sem_timedwait, primary), SKINCALL_DEF(sc_cobalt_sem_trywait, cobalt_sem_trywait, primary), - SKINCALL_DEF(sc_cobalt_sem_getvalue, cobalt_sem_getvalue, any), - SKINCALL_DEF(sc_cobalt_sem_open, cobalt_sem_open, any), - SKINCALL_DEF(sc_cobalt_sem_close, cobalt_sem_close, any), - SKINCALL_DEF(sc_cobalt_sem_unlink, cobalt_sem_unlink, any), - SKINCALL_DEF(sc_cobalt_sem_init_np, cobalt_sem_init_np, any), - SKINCALL_DEF(sc_cobalt_sem_broadcast_np, cobalt_sem_broadcast_np, any), - SKINCALL_DEF(sc_cobalt_sem_inquire, cobalt_sem_inquire, any), - SKINCALL_DEF(sc_cobalt_clock_getres, cobalt_clock_getres, any), - SKINCALL_DEF(sc_cobalt_clock_gettime, cobalt_clock_gettime, any), - SKINCALL_DEF(sc_cobalt_clock_settime, cobalt_clock_settime, any), + SKINCALL_DEF(sc_cobalt_sem_getvalue, cobalt_sem_getvalue, current), + SKINCALL_DEF(sc_cobalt_sem_open, cobalt_sem_open, current), + SKINCALL_DEF(sc_cobalt_sem_close, cobalt_sem_close, current), + SKINCALL_DEF(sc_cobalt_sem_unlink, cobalt_sem_unlink, current), + SKINCALL_DEF(sc_cobalt_sem_init_np, cobalt_sem_init_np, current), + SKINCALL_DEF(sc_cobalt_sem_broadcast_np, cobalt_sem_broadcast_np, current), + SKINCALL_DEF(sc_cobalt_sem_inquire, cobalt_sem_inquire, current), + SKINCALL_DEF(sc_cobalt_clock_getres, cobalt_clock_getres, current), + SKINCALL_DEF(sc_cobalt_clock_gettime, cobalt_clock_gettime, current), + SKINCALL_DEF(sc_cobalt_clock_settime, cobalt_clock_settime, current), SKINCALL_DEF(sc_cobalt_clock_nanosleep, cobalt_clock_nanosleep, nonrestartable), - SKINCALL_DEF(sc_cobalt_mutex_init, cobalt_mutex_init, any), - SKINCALL_DEF(sc_cobalt_mutex_check_init, cobalt_mutex_check_init, any), - SKINCALL_DEF(sc_cobalt_mutex_destroy, cobalt_mutex_destroy, any), + SKINCALL_DEF(sc_cobalt_mutex_init, cobalt_mutex_init, current), + SKINCALL_DEF(sc_cobalt_mutex_check_init, cobalt_mutex_check_init, current), + SKINCALL_DEF(sc_cobalt_mutex_destroy, cobalt_mutex_destroy, current), SKINCALL_DEF(sc_cobalt_mutex_lock, cobalt_mutex_lock, primary), SKINCALL_DEF(sc_cobalt_mutex_timedlock, cobalt_mutex_timedlock, primary), SKINCALL_DEF(sc_cobalt_mutex_trylock, cobalt_mutex_trylock, primary), SKINCALL_DEF(sc_cobalt_mutex_unlock, cobalt_mutex_unlock, nonrestartable), - SKINCALL_DEF(sc_cobalt_cond_init, cobalt_cond_init, any), - SKINCALL_DEF(sc_cobalt_cond_destroy, cobalt_cond_destroy, any), + SKINCALL_DEF(sc_cobalt_cond_init, cobalt_cond_init, current), + SKINCALL_DEF(sc_cobalt_cond_destroy, cobalt_cond_destroy, current), SKINCALL_DEF(sc_cobalt_cond_wait_prologue, cobalt_cond_wait_prologue, nonrestartable), SKINCALL_DEF(sc_cobalt_cond_wait_epilogue, cobalt_cond_wait_epilogue, primary), SKINCALL_DEF(sc_cobalt_mq_open, cobalt_mq_open, lostage), SKINCALL_DEF(sc_cobalt_mq_close, cobalt_mq_close, lostage), SKINCALL_DEF(sc_cobalt_mq_unlink, cobalt_mq_unlink, lostage), - SKINCALL_DEF(sc_cobalt_mq_getattr, cobalt_mq_getattr, any), - SKINCALL_DEF(sc_cobalt_mq_setattr, cobalt_mq_setattr, any), + SKINCALL_DEF(sc_cobalt_mq_getattr, cobalt_mq_getattr, current), + SKINCALL_DEF(sc_cobalt_mq_setattr, cobalt_mq_setattr, current), SKINCALL_DEF(sc_cobalt_mq_timedsend, cobalt_mq_timedsend, primary), SKINCALL_DEF(sc_cobalt_mq_timedreceive, cobalt_mq_timedreceive, primary), SKINCALL_DEF(sc_cobalt_mq_notify, cobalt_mq_notify, primary), @@ -141,44 +141,44 @@ static struct xnsyscall cobalt_syscalls[] = { SKINCALL_DEF(sc_cobalt_sigpending, cobalt_sigpending, primary), SKINCALL_DEF(sc_cobalt_kill, cobalt_kill, conforming), SKINCALL_DEF(sc_cobalt_sigqueue, cobalt_sigqueue, conforming), - SKINCALL_DEF(sc_cobalt_timer_create, cobalt_timer_create, any), - SKINCALL_DEF(sc_cobalt_timer_delete, cobalt_timer_delete, any), + SKINCALL_DEF(sc_cobalt_timer_create, cobalt_timer_create, current), + SKINCALL_DEF(sc_cobalt_timer_delete, cobalt_timer_delete, current), SKINCALL_DEF(sc_cobalt_timer_settime, cobalt_timer_settime, primary), - SKINCALL_DEF(sc_cobalt_timer_gettime, cobalt_timer_gettime, any), - SKINCALL_DEF(sc_cobalt_timer_getoverrun, cobalt_timer_getoverrun, any), + SKINCALL_DEF(sc_cobalt_timer_gettime, cobalt_timer_gettime, current), + SKINCALL_DEF(sc_cobalt_timer_getoverrun, cobalt_timer_getoverrun, current), SKINCALL_DEF(sc_cobalt_timerfd_create, cobalt_timerfd_create, lostage), - SKINCALL_DEF(sc_cobalt_timerfd_gettime, cobalt_timerfd_gettime, any), - SKINCALL_DEF(sc_cobalt_timerfd_settime, cobalt_timerfd_settime, any), - SKINCALL_DEF(sc_cobalt_mutexattr_init, cobalt_mutexattr_init, any), - SKINCALL_DEF(sc_cobalt_mutexattr_destroy, cobalt_mutexattr_destroy, any), - SKINCALL_DEF(sc_cobalt_mutexattr_gettype, cobalt_mutexattr_gettype, any), - SKINCALL_DEF(sc_cobalt_mutexattr_settype, cobalt_mutexattr_settype, any), - SKINCALL_DEF(sc_cobalt_mutexattr_getprotocol, cobalt_mutexattr_getprotocol, any), - SKINCALL_DEF(sc_cobalt_mutexattr_setprotocol, cobalt_mutexattr_setprotocol, any), - SKINCALL_DEF(sc_cobalt_mutexattr_getpshared, cobalt_mutexattr_getpshared, any), - SKINCALL_DEF(sc_cobalt_mutexattr_setpshared, cobalt_mutexattr_setpshared, any), - SKINCALL_DEF(sc_cobalt_condattr_init, cobalt_condattr_init, any), - SKINCALL_DEF(sc_cobalt_condattr_destroy, cobalt_condattr_destroy, any), - SKINCALL_DEF(sc_cobalt_condattr_getclock, cobalt_condattr_getclock, any), - SKINCALL_DEF(sc_cobalt_condattr_setclock, cobalt_condattr_setclock, any), - SKINCALL_DEF(sc_cobalt_condattr_getpshared, cobalt_condattr_getpshared, any), - SKINCALL_DEF(sc_cobalt_condattr_setpshared, cobalt_condattr_setpshared, any), + SKINCALL_DEF(sc_cobalt_timerfd_gettime, cobalt_timerfd_gettime, current), + SKINCALL_DEF(sc_cobalt_timerfd_settime, cobalt_timerfd_settime, current), + SKINCALL_DEF(sc_cobalt_mutexattr_init, cobalt_mutexattr_init, current), + SKINCALL_DEF(sc_cobalt_mutexattr_destroy, cobalt_mutexattr_destroy, current), + SKINCALL_DEF(sc_cobalt_mutexattr_gettype, cobalt_mutexattr_gettype, current), + SKINCALL_DEF(sc_cobalt_mutexattr_settype, cobalt_mutexattr_settype, current), + SKINCALL_DEF(sc_cobalt_mutexattr_getprotocol, cobalt_mutexattr_getprotocol, current), + SKINCALL_DEF(sc_cobalt_mutexattr_setprotocol, cobalt_mutexattr_setprotocol, current), + SKINCALL_DEF(sc_cobalt_mutexattr_getpshared, cobalt_mutexattr_getpshared, current), + SKINCALL_DEF(sc_cobalt_mutexattr_setpshared, cobalt_mutexattr_setpshared, current), + SKINCALL_DEF(sc_cobalt_condattr_init, cobalt_condattr_init, current), + SKINCALL_DEF(sc_cobalt_condattr_destroy, cobalt_condattr_destroy, current), + SKINCALL_DEF(sc_cobalt_condattr_getclock, cobalt_condattr_getclock, current), + SKINCALL_DEF(sc_cobalt_condattr_setclock, cobalt_condattr_setclock, current), + SKINCALL_DEF(sc_cobalt_condattr_getpshared, cobalt_condattr_getpshared, current), + SKINCALL_DEF(sc_cobalt_condattr_setpshared, cobalt_condattr_setpshared, current), SKINCALL_DEF(sc_cobalt_select, cobalt_select, nonrestartable), - SKINCALL_DEF(sc_cobalt_sched_minprio, cobalt_sched_min_prio, any), - SKINCALL_DEF(sc_cobalt_sched_maxprio, cobalt_sched_max_prio, any), - SKINCALL_DEF(sc_cobalt_monitor_init, cobalt_monitor_init, any), + SKINCALL_DEF(sc_cobalt_sched_minprio, cobalt_sched_min_prio, current), + SKINCALL_DEF(sc_cobalt_sched_maxprio, cobalt_sched_max_prio, current), + SKINCALL_DEF(sc_cobalt_monitor_init, cobalt_monitor_init, current), SKINCALL_DEF(sc_cobalt_monitor_destroy, cobalt_monitor_destroy, primary), SKINCALL_DEF(sc_cobalt_monitor_enter, cobalt_monitor_enter, primary), SKINCALL_DEF(sc_cobalt_monitor_wait, cobalt_monitor_wait, nonrestartable), SKINCALL_DEF(sc_cobalt_monitor_sync, cobalt_monitor_sync, nonrestartable), SKINCALL_DEF(sc_cobalt_monitor_exit, cobalt_monitor_exit, primary), - SKINCALL_DEF(sc_cobalt_event_init, cobalt_event_init, any), - SKINCALL_DEF(sc_cobalt_event_destroy, cobalt_event_destroy, any), + SKINCALL_DEF(sc_cobalt_event_init, cobalt_event_init, current), + SKINCALL_DEF(sc_cobalt_event_destroy, cobalt_event_destroy, current), SKINCALL_DEF(sc_cobalt_event_wait, cobalt_event_wait, primary), - SKINCALL_DEF(sc_cobalt_event_sync, cobalt_event_sync, any), - SKINCALL_DEF(sc_cobalt_event_inquire, cobalt_event_inquire, any), - SKINCALL_DEF(sc_cobalt_sched_setconfig_np, cobalt_sched_setconfig_np, any), - SKINCALL_DEF(sc_cobalt_sched_getconfig_np, cobalt_sched_getconfig_np, any), + SKINCALL_DEF(sc_cobalt_event_sync, cobalt_event_sync, current), + SKINCALL_DEF(sc_cobalt_event_inquire, cobalt_event_inquire, current), + SKINCALL_DEF(sc_cobalt_sched_setconfig_np, cobalt_sched_setconfig_np, current), + SKINCALL_DEF(sc_cobalt_sched_getconfig_np, cobalt_sched_getconfig_np, current), }; struct xnpersonality cobalt_personality = { diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c index 465715a..aea0d33 100644 --- a/kernel/cobalt/shadow.c +++ b/kernel/cobalt/shadow.c @@ -1619,15 +1619,15 @@ static void *user_process_attach(void) static struct xnsyscall user_syscalls[] = { SKINCALL_DEF(sc_nucleus_migrate, xnshadow_sys_migrate, current), - SKINCALL_DEF(sc_nucleus_arch, xnarch_local_syscall, any), + SKINCALL_DEF(sc_nucleus_arch, xnarch_local_syscall, current), SKINCALL_DEF(sc_nucleus_bind, xnshadow_sys_bind, lostage), SKINCALL_DEF(sc_nucleus_info, xnshadow_sys_info, lostage), - SKINCALL_DEF(sc_nucleus_trace, xnshadow_sys_trace, any), + SKINCALL_DEF(sc_nucleus_trace, xnshadow_sys_trace, current), SKINCALL_DEF(sc_nucleus_heap_info, xnshadow_sys_heap_info, lostage), - SKINCALL_DEF(sc_nucleus_current, xnshadow_sys_current, any), + SKINCALL_DEF(sc_nucleus_current, xnshadow_sys_current, current), SKINCALL_DEF(sc_nucleus_mayday, xnshadow_sys_mayday, oneway), SKINCALL_DEF(sc_nucleus_backtrace, xnshadow_sys_backtrace, current), - SKINCALL_DEF(sc_nucleus_serialdbg, xnshadow_sys_serialdbg, any), + SKINCALL_DEF(sc_nucleus_serialdbg, xnshadow_sys_serialdbg, current), }; static struct xnpersonality user_personality = { @@ -1935,12 +1935,14 @@ restart: * opposite domain. */ if (sysflags & __xn_exec_lostage) { - /* Syscall must run into the Linux domain. */ + /* + * The syscall must run from the Linux domain. + */ if (ipd == &xnsched_realtime_domain) { /* * Request originates from the Xenomai domain: - * just relax the caller and execute the - * syscall immediately after. + * relax the caller then invoke the syscall + * handler right after. */ xnshadow_relax(1, SIGDEBUG_MIGRATE_SYSCALL); switched = 1; @@ -1954,22 +1956,15 @@ restart: return EVENT_PROPAGATE; } else if (sysflags & (__xn_exec_histage | __xn_exec_current)) { /* - * Syscall must be processed either by Xenomai, or by - * the calling domain. + * Syscall must run either from the Xenomai domain, or + * from the calling domain. + * + * If the request originates from the Linux domain, + * hand it over to our secondary-mode dispatcher. + * Otherwise, invoke the syscall handler immediately. */ if (ipd != &xnsched_realtime_domain) - /* - * Request originates from the Linux domain: - * propagate the event to our Linux-based - * handler, so that the caller is hardened and - * the syscall is eventually executed from - * there. - */ return EVENT_PROPAGATE; - /* - * Request originates from the Xenomai domain: run the - * syscall immediately. - */ } ret = sc->svc(__xn_reg_arglist(regs)); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git