1e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#ifndef _LINUX_CONTEXT_TRACKING_STATE_H
2e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#define _LINUX_CONTEXT_TRACKING_STATE_H
3e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
4e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#include <linux/percpu.h>
5e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#include <linux/static_key.h>
6e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
7e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbeckerstruct context_tracking {
8e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	/*
9e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	 * When active is false, probes are unset in order
10e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	 * to minimize overhead: TIF flags are cleared
11e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	 * and calls to user_enter/exit are ignored. This
12e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	 * may be further optimized using static keys.
13e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	 */
14e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	bool active;
15e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	enum ctx_state {
16e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker		IN_KERNEL = 0,
17e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker		IN_USER,
18e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker	} state;
19e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker};
20e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
21e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#ifdef CONFIG_CONTEXT_TRACKING
22e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbeckerextern struct static_key context_tracking_enabled;
23e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic WeisbeckerDECLARE_PER_CPU(struct context_tracking, context_tracking);
24e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
2558135f574f1b791c926622387780ed3d090116d6Frederic Weisbeckerstatic inline bool context_tracking_is_enabled(void)
2658135f574f1b791c926622387780ed3d090116d6Frederic Weisbecker{
2758135f574f1b791c926622387780ed3d090116d6Frederic Weisbecker	return static_key_false(&context_tracking_enabled);
2858135f574f1b791c926622387780ed3d090116d6Frederic Weisbecker}
29d0df09ebfc126b23c1005f98ddecc9907f9c5d25Frederic Weisbecker
30d0df09ebfc126b23c1005f98ddecc9907f9c5d25Frederic Weisbeckerstatic inline bool context_tracking_cpu_is_enabled(void)
31e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker{
32d0df09ebfc126b23c1005f98ddecc9907f9c5d25Frederic Weisbecker	return __this_cpu_read(context_tracking.active);
33e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker}
34e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
35d0df09ebfc126b23c1005f98ddecc9907f9c5d25Frederic Weisbeckerstatic inline bool context_tracking_in_user(void)
36e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker{
37d0df09ebfc126b23c1005f98ddecc9907f9c5d25Frederic Weisbecker	return __this_cpu_read(context_tracking.state) == IN_USER;
38e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker}
39e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#else
40e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbeckerstatic inline bool context_tracking_in_user(void) { return false; }
41e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbeckerstatic inline bool context_tracking_active(void) { return false; }
42e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#endif /* CONFIG_CONTEXT_TRACKING */
43e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker
44e7358b3bc0d7fcec0e7a724477f06db2b0c68e21Frederic Weisbecker#endif
45