[PATCH V2 3/5] dovetail/kevents: dovetail: implement handle_ptrace_cont
Philippe Gerum
rpm at xenomai.org
Sun Jan 24 18:21:20 CET 2021
hongzha1 via Xenomai <xenomai at xenomai.org> writes:
> Signed-off-by: hongzha1 <hongzhan.chen at intel.com>
>
> diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
> index 6aec170d1..0528e2938 100644
> --- a/kernel/cobalt/dovetail/kevents.c
> +++ b/kernel/cobalt/dovetail/kevents.c
> @@ -480,7 +480,75 @@ static void handle_ptrace_cont(void)
> * stopped state, which is what look for in
> * handle_schedule_event().
> */
> - TODO();
> + struct task_struct *next_task;
> + struct xnthread *next;
> + sigset_t pending;
> + spl_t s;
> +
> + cobalt_signal_yield();
> +
> + next_task = current;
> + next = xnthread_from_task(next_task);
> + if (next == NULL)
> + return;
> +
> + xnlock_get_irqsave(&nklock, s);
> +
> + /*
> + * Track tasks leaving the ptraced state. Check both SIGSTOP
> + * (NPTL) and SIGINT (LinuxThreads) to detect ptrace
> + * continuation.
> + */
> + if (xnthread_test_state(next, XNSSTEP)) {
> + if (signal_pending(next_task)) {
> + /*
> + * Do not grab the sighand lock here: it's
> + * useless, and we already own the runqueue
> + * lock, so this would expose us to deadlock
> + * situations on SMP.
> + */
> + sigorsets(&pending,
> + &next_task->pending.signal,
> + &next_task->signal->shared_pending.signal);
> + if (sigismember(&pending, SIGSTOP) ||
> + sigismember(&pending, SIGINT))
> + goto no_ptrace;
> + }
> +
> + /*
> + * Do not unregister before the thread migrated.
> + * unregister_debugged_thread will then be called by our
> + * resume_oob_task.
> + */
> + if (!xnthread_test_info(next, XNCONTHI))
> + unregister_debugged_thread(next);
> +
> + xnthread_set_localinfo(next, XNHICCUP);
> + }
> +
Since we know Dovetail just called us because 'current' is about to
resume from a stopped state, we don't need the hackish code above which
was aimed at determining whether next_task was about to do so
(i.e. resuming from ptrace stop).
> +no_ptrace:
> + xnlock_put_irqrestore(&nklock, s);
> +
> + /*
> + * Do basic sanity checks on the incoming thread state.
> + * NOTE: we allow ptraced threads to run shortly in order to
> + * properly recover from a stopped state.
> + */
> + if (!XENO_WARN(COBALT, !xnthread_test_state(next, XNRELAX),
> + "hardened thread %s[%d] running in Linux domain?! "
> + "(status=0x%x, sig=%d)",
> + next->name, task_pid_nr(next_task),
> + xnthread_get_state(next),
> + signal_pending(next_task)))
> + XENO_WARN(COBALT,
> + !(next_task->ptrace & PT_PTRACED) &&
> + !xnthread_test_state(next, XNDORMANT)
> + && xnthread_test_state(next, XNPEND),
> + "blocked thread %s[%d] rescheduled?! "
> + "(status=0x%x, sig=%d)",
> + next->name, task_pid_nr(next_task),
> + xnthread_get_state(next),
> + signal_pending(next_task));
> }
>
> void handle_inband_event(enum inband_event_type event, void *data)
On second thought, we could also drop the remaining check above, since
what is being tested is a very basic Dovetail guarantee, i.e. that
'current' must be running in-band. IOW, receiving ptrace_cont should
lead to a nop when running on top of Dovetail.
--
Philippe.
More information about the Xenomai
mailing list