// 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 void posix_cpu_timer_rearm(struct k_itimer *timer);
/*
* Called after updating RLIMIT_CPU to run cpu timer and update
* tsk->signal->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.
*/
static struct task_struct *lookup_task(const pid_t pid, bool thread)
{
struct task_struct *p;
if (!pid)
return thread ? current : current->group_leader;
p = find_task_by_vpid(pid);
if (!p || p == current)
return p;
if (thread)
return same_thread_group(p, current) ? p : NULL;
if (p == current)
return p;
return has_group_leader_pid(p) ?