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

Reply via email to