// SPDX-License-Identifier: GPL-2.0
/*
* Implement CPU time clocks for the POSIX clock interface.
*/
#include <linux/sched/signal.h>
#include <linux/sched/cputime.h>
#include <linux/posix-timers.h>
#include <linux/errno.h>
#include <linux/math64.h>
#include <linux/uaccess.h>
#include <linux/kernel_stat.h>
#include <trace/events/timer.h>
#include <linux/tick.h>
#include <linux/workqueue.h>
#include <linux/compat.h>
#include <linux/sched/deadline.h>
#include "posix-timers.h"
static inline void temporary_check(void)
{
BUILD_BUG_ON(offsetof(struct task_cputime, stime) !=
CPUCLOCK_PROF * sizeof(u64));
BUILD_BUG_ON(offsetof(struct task_cputime, utime) !=
CPUCLOCK_VIRT * sizeof(u64));
BUILD_BUG_ON(offsetof(struct task_cputime, sum_exec_runtime) !=
CPUCLOCK_SCHED * sizeof(u64));
}
static void posix_cpu_timer_rearm(struct k_itimer *timer);
void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit)
{
posix_cputimers_init(pct);
if (cpu_limit != RLIM_INFINITY)
pct->expiries[CPUCLOCK_PROF] = cpu_limit * NSEC_PER_SEC;
}
/*
* Called after updating RLIMIT_CPU to run cpu timer and update
* tsk->signal->posix_cputimers.cputime_expires expiration cache if
* necessary. Needs siglock protection since other code may update
* expiration cache as well.
*/
void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new)
{
u64 nsecs = rlim_new * NSEC_PER_SEC;
spin_lock_irq(&task->sighand->siglock);
set_process_cpu_timer(task, CPUCLOCK_PROF, &nsecs, NULL);
spin_unlock_irq(&task->sighand->siglock);
}
/*
* Functions for validating access to tasks.