Commit 9b11a9f0 authored by Jan Kiszka's avatar Jan Kiszka

ipipe: Introduce infrastructure for userspace return notifier

A little bit inspired by the kernel's user return notifier, this
introduces an I-pipe hook before the kernel jumps back to a userspace
context from the root domain. The hook is design to allow a switch back
to the head domain, thus will not run through signal/preemption checks
when returning from the callback over head. It is guaranteed to fire on
return from interrupts and exceptions but may also fire on certain
syscall-return paths.

The first use case for the hook is resumption of ptraced tasks over
head if they were stopped in that domain.

This provides just the generic infrastructure, the invocation of
__ipipe_notify_user_intreturn as well as the definition of
TIP_USERINTRET are architecture-specific.
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 2424f4ae
......@@ -417,6 +417,18 @@ extern void __ipipe_uaccess_might_fault(void);
#define __ipipe_uaccess_might_fault() might_fault()
#endif
#define ipipe_enable_user_intret_notifier() \
do { \
ipipe_set_thread_flag(TIP_USERINTRET); \
set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); \
} while (0)
#define ipipe_disable_user_intret_notifier() \
ipipe_clear_thread_flag(TIP_USERINTRET)
#define ipipe_user_intret_notifier_enabled(ti) \
ipipe_test_ti_thread_flag(ti, TIP_USERINTRET)
#ifdef CONFIG_IPIPE_TRACE
void __ipipe_tracer_hrclock_initialized(void);
#else /* !CONFIG_IPIPE_TRACE */
......@@ -465,6 +477,8 @@ static inline int ipipe_handle_syscall(struct thread_info *ti,
return 0;
}
#define ipipe_user_intret_notifier_enabled(ti) 0
#endif /* !CONFIG_IPIPE */
#endif /* !__LINUX_IPIPE_H */
......@@ -110,6 +110,7 @@ struct ipipe_trap_data {
#define IPIPE_KEVT_CLEANUP 5
#define IPIPE_KEVT_HOSTRT 6
#define IPIPE_KEVT_CLOCKFREQ 7
#define IPIPE_KEVT_USERINTRET 8
struct ipipe_vm_notifier {
void (*handler)(struct ipipe_vm_notifier *nfy);
......@@ -281,6 +282,8 @@ static inline void __ipipe_init_taskinfo(struct task_struct *p) { }
#endif /* !CONFIG_IPIPE_LEGACY */
int __ipipe_notify_user_intreturn(void);
#define __ipipe_serial_debug(__fmt, __args...) raw_printk(__fmt, ##__args)
#else /* !CONFIG_IPIPE */
......@@ -331,6 +334,8 @@ static inline void __ipipe_exit_vm(void) { }
static inline void __ipipe_notify_vm_preemption(void) { }
#define __ipipe_notify_user_intreturn() 0
static inline void ipipe_root_only(void) { }
#define __ipipe_serial_debug(__fmt, __args...) do { } while (0)
......
......@@ -1072,6 +1072,13 @@ out:
return ret;
}
int __ipipe_notify_user_intreturn(void)
{
__ipipe_notify_kevent(IPIPE_KEVT_USERINTRET, current);
return !ipipe_root_p;
}
int __weak ipipe_kevent_hook(int kevent, void *data)
{
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment