cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

posix-timers.h (7144B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _linux_POSIX_TIMERS_H
      3#define _linux_POSIX_TIMERS_H
      4
      5#include <linux/spinlock.h>
      6#include <linux/list.h>
      7#include <linux/alarmtimer.h>
      8#include <linux/timerqueue.h>
      9
     10struct kernel_siginfo;
     11struct task_struct;
     12
     13/*
     14 * Bit fields within a clockid:
     15 *
     16 * The most significant 29 bits hold either a pid or a file descriptor.
     17 *
     18 * Bit 2 indicates whether a cpu clock refers to a thread or a process.
     19 *
     20 * Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
     21 *
     22 * A clockid is invalid if bits 2, 1, and 0 are all set.
     23 */
     24#define CPUCLOCK_PID(clock)		((pid_t) ~((clock) >> 3))
     25#define CPUCLOCK_PERTHREAD(clock) \
     26	(((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
     27
     28#define CPUCLOCK_PERTHREAD_MASK	4
     29#define CPUCLOCK_WHICH(clock)	((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
     30#define CPUCLOCK_CLOCK_MASK	3
     31#define CPUCLOCK_PROF		0
     32#define CPUCLOCK_VIRT		1
     33#define CPUCLOCK_SCHED		2
     34#define CPUCLOCK_MAX		3
     35#define CLOCKFD			CPUCLOCK_MAX
     36#define CLOCKFD_MASK		(CPUCLOCK_PERTHREAD_MASK|CPUCLOCK_CLOCK_MASK)
     37
     38static inline clockid_t make_process_cpuclock(const unsigned int pid,
     39		const clockid_t clock)
     40{
     41	return ((~pid) << 3) | clock;
     42}
     43static inline clockid_t make_thread_cpuclock(const unsigned int tid,
     44		const clockid_t clock)
     45{
     46	return make_process_cpuclock(tid, clock | CPUCLOCK_PERTHREAD_MASK);
     47}
     48
     49static inline clockid_t fd_to_clockid(const int fd)
     50{
     51	return make_process_cpuclock((unsigned int) fd, CLOCKFD);
     52}
     53
     54static inline int clockid_to_fd(const clockid_t clk)
     55{
     56	return ~(clk >> 3);
     57}
     58
     59#ifdef CONFIG_POSIX_TIMERS
     60
     61/**
     62 * cpu_timer - Posix CPU timer representation for k_itimer
     63 * @node:	timerqueue node to queue in the task/sig
     64 * @head:	timerqueue head on which this timer is queued
     65 * @task:	Pointer to target task
     66 * @elist:	List head for the expiry list
     67 * @firing:	Timer is currently firing
     68 */
     69struct cpu_timer {
     70	struct timerqueue_node	node;
     71	struct timerqueue_head	*head;
     72	struct pid		*pid;
     73	struct list_head	elist;
     74	int			firing;
     75};
     76
     77static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
     78				     struct cpu_timer *ctmr)
     79{
     80	ctmr->head = head;
     81	return timerqueue_add(head, &ctmr->node);
     82}
     83
     84static inline bool cpu_timer_queued(struct cpu_timer *ctmr)
     85{
     86	return !!ctmr->head;
     87}
     88
     89static inline bool cpu_timer_dequeue(struct cpu_timer *ctmr)
     90{
     91	if (cpu_timer_queued(ctmr)) {
     92		timerqueue_del(ctmr->head, &ctmr->node);
     93		ctmr->head = NULL;
     94		return true;
     95	}
     96	return false;
     97}
     98
     99static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
    100{
    101	return ctmr->node.expires;
    102}
    103
    104static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
    105{
    106	ctmr->node.expires = exp;
    107}
    108
    109/**
    110 * posix_cputimer_base - Container per posix CPU clock
    111 * @nextevt:		Earliest-expiration cache
    112 * @tqhead:		timerqueue head for cpu_timers
    113 */
    114struct posix_cputimer_base {
    115	u64			nextevt;
    116	struct timerqueue_head	tqhead;
    117};
    118
    119/**
    120 * posix_cputimers - Container for posix CPU timer related data
    121 * @bases:		Base container for posix CPU clocks
    122 * @timers_active:	Timers are queued.
    123 * @expiry_active:	Timer expiry is active. Used for
    124 *			process wide timers to avoid multiple
    125 *			task trying to handle expiry concurrently
    126 *
    127 * Used in task_struct and signal_struct
    128 */
    129struct posix_cputimers {
    130	struct posix_cputimer_base	bases[CPUCLOCK_MAX];
    131	unsigned int			timers_active;
    132	unsigned int			expiry_active;
    133};
    134
    135/**
    136 * posix_cputimers_work - Container for task work based posix CPU timer expiry
    137 * @work:	The task work to be scheduled
    138 * @scheduled:  @work has been scheduled already, no further processing
    139 */
    140struct posix_cputimers_work {
    141	struct callback_head	work;
    142	unsigned int		scheduled;
    143};
    144
    145static inline void posix_cputimers_init(struct posix_cputimers *pct)
    146{
    147	memset(pct, 0, sizeof(*pct));
    148	pct->bases[0].nextevt = U64_MAX;
    149	pct->bases[1].nextevt = U64_MAX;
    150	pct->bases[2].nextevt = U64_MAX;
    151}
    152
    153void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
    154
    155static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
    156					       u64 runtime)
    157{
    158	pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
    159}
    160
    161/* Init task static initializer */
    162#define INIT_CPU_TIMERBASE(b) {						\
    163	.nextevt	= U64_MAX,					\
    164}
    165
    166#define INIT_CPU_TIMERBASES(b) {					\
    167	INIT_CPU_TIMERBASE(b[0]),					\
    168	INIT_CPU_TIMERBASE(b[1]),					\
    169	INIT_CPU_TIMERBASE(b[2]),					\
    170}
    171
    172#define INIT_CPU_TIMERS(s)						\
    173	.posix_cputimers = {						\
    174		.bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),	\
    175	},
    176#else
    177struct posix_cputimers { };
    178struct cpu_timer { };
    179#define INIT_CPU_TIMERS(s)
    180static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
    181static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
    182					      u64 cpu_limit) { }
    183#endif
    184
    185#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
    186void clear_posix_cputimers_work(struct task_struct *p);
    187void posix_cputimers_init_work(void);
    188#else
    189static inline void clear_posix_cputimers_work(struct task_struct *p) { }
    190static inline void posix_cputimers_init_work(void) { }
    191#endif
    192
    193#define REQUEUE_PENDING 1
    194
    195/**
    196 * struct k_itimer - POSIX.1b interval timer structure.
    197 * @list:		List head for binding the timer to signals->posix_timers
    198 * @t_hash:		Entry in the posix timer hash table
    199 * @it_lock:		Lock protecting the timer
    200 * @kclock:		Pointer to the k_clock struct handling this timer
    201 * @it_clock:		The posix timer clock id
    202 * @it_id:		The posix timer id for identifying the timer
    203 * @it_active:		Marker that timer is active
    204 * @it_overrun:		The overrun counter for pending signals
    205 * @it_overrun_last:	The overrun at the time of the last delivered signal
    206 * @it_requeue_pending:	Indicator that timer waits for being requeued on
    207 *			signal delivery
    208 * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
    209 * @it_interval:	The interval for periodic timers
    210 * @it_signal:		Pointer to the creators signal struct
    211 * @it_pid:		The pid of the process/task targeted by the signal
    212 * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
    213 * @sigq:		Pointer to preallocated sigqueue
    214 * @it:			Union representing the various posix timer type
    215 *			internals.
    216 * @rcu:		RCU head for freeing the timer.
    217 */
    218struct k_itimer {
    219	struct list_head	list;
    220	struct hlist_node	t_hash;
    221	spinlock_t		it_lock;
    222	const struct k_clock	*kclock;
    223	clockid_t		it_clock;
    224	timer_t			it_id;
    225	int			it_active;
    226	s64			it_overrun;
    227	s64			it_overrun_last;
    228	int			it_requeue_pending;
    229	int			it_sigev_notify;
    230	ktime_t			it_interval;
    231	struct signal_struct	*it_signal;
    232	union {
    233		struct pid		*it_pid;
    234		struct task_struct	*it_process;
    235	};
    236	struct sigqueue		*sigq;
    237	union {
    238		struct {
    239			struct hrtimer	timer;
    240		} real;
    241		struct cpu_timer	cpu;
    242		struct {
    243			struct alarm	alarmtimer;
    244		} alarm;
    245	} it;
    246	struct rcu_head		rcu;
    247};
    248
    249void run_posix_cpu_timers(void);
    250void posix_cpu_timers_exit(struct task_struct *task);
    251void posix_cpu_timers_exit_group(struct task_struct *task);
    252void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
    253			   u64 *newval, u64 *oldval);
    254
    255int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
    256
    257void posixtimer_rearm(struct kernel_siginfo *info);
    258#endif