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

tick.h (9975B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Tick related global functions
      4 */
      5#ifndef _LINUX_TICK_H
      6#define _LINUX_TICK_H
      7
      8#include <linux/clockchips.h>
      9#include <linux/irqflags.h>
     10#include <linux/percpu.h>
     11#include <linux/context_tracking_state.h>
     12#include <linux/cpumask.h>
     13#include <linux/sched.h>
     14#include <linux/rcupdate.h>
     15
     16#ifdef CONFIG_GENERIC_CLOCKEVENTS
     17extern void __init tick_init(void);
     18/* Should be core only, but ARM BL switcher requires it */
     19extern void tick_suspend_local(void);
     20/* Should be core only, but XEN resume magic and ARM BL switcher require it */
     21extern void tick_resume_local(void);
     22extern void tick_handover_do_timer(void);
     23extern void tick_cleanup_dead_cpu(int cpu);
     24#else /* CONFIG_GENERIC_CLOCKEVENTS */
     25static inline void tick_init(void) { }
     26static inline void tick_suspend_local(void) { }
     27static inline void tick_resume_local(void) { }
     28static inline void tick_handover_do_timer(void) { }
     29static inline void tick_cleanup_dead_cpu(int cpu) { }
     30#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
     31
     32#if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_SUSPEND)
     33extern void tick_freeze(void);
     34extern void tick_unfreeze(void);
     35#else
     36static inline void tick_freeze(void) { }
     37static inline void tick_unfreeze(void) { }
     38#endif
     39
     40#ifdef CONFIG_TICK_ONESHOT
     41extern void tick_irq_enter(void);
     42#  ifndef arch_needs_cpu
     43#   define arch_needs_cpu() (0)
     44#  endif
     45# else
     46static inline void tick_irq_enter(void) { }
     47#endif
     48
     49#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
     50extern void hotplug_cpu__broadcast_tick_pull(int dead_cpu);
     51#else
     52static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
     53#endif
     54
     55enum tick_broadcast_mode {
     56	TICK_BROADCAST_OFF,
     57	TICK_BROADCAST_ON,
     58	TICK_BROADCAST_FORCE,
     59};
     60
     61enum tick_broadcast_state {
     62	TICK_BROADCAST_EXIT,
     63	TICK_BROADCAST_ENTER,
     64};
     65
     66#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
     67extern void tick_broadcast_control(enum tick_broadcast_mode mode);
     68#else
     69static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
     70#endif /* BROADCAST */
     71
     72#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_HOTPLUG_CPU)
     73extern void tick_offline_cpu(unsigned int cpu);
     74#else
     75static inline void tick_offline_cpu(unsigned int cpu) { }
     76#endif
     77
     78#ifdef CONFIG_GENERIC_CLOCKEVENTS
     79extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
     80#else
     81static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
     82{
     83	return 0;
     84}
     85#endif
     86
     87static inline void tick_broadcast_enable(void)
     88{
     89	tick_broadcast_control(TICK_BROADCAST_ON);
     90}
     91static inline void tick_broadcast_disable(void)
     92{
     93	tick_broadcast_control(TICK_BROADCAST_OFF);
     94}
     95static inline void tick_broadcast_force(void)
     96{
     97	tick_broadcast_control(TICK_BROADCAST_FORCE);
     98}
     99static inline int tick_broadcast_enter(void)
    100{
    101	return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
    102}
    103static inline void tick_broadcast_exit(void)
    104{
    105	tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
    106}
    107
    108enum tick_dep_bits {
    109	TICK_DEP_BIT_POSIX_TIMER	= 0,
    110	TICK_DEP_BIT_PERF_EVENTS	= 1,
    111	TICK_DEP_BIT_SCHED		= 2,
    112	TICK_DEP_BIT_CLOCK_UNSTABLE	= 3,
    113	TICK_DEP_BIT_RCU		= 4,
    114	TICK_DEP_BIT_RCU_EXP		= 5
    115};
    116#define TICK_DEP_BIT_MAX TICK_DEP_BIT_RCU_EXP
    117
    118#define TICK_DEP_MASK_NONE		0
    119#define TICK_DEP_MASK_POSIX_TIMER	(1 << TICK_DEP_BIT_POSIX_TIMER)
    120#define TICK_DEP_MASK_PERF_EVENTS	(1 << TICK_DEP_BIT_PERF_EVENTS)
    121#define TICK_DEP_MASK_SCHED		(1 << TICK_DEP_BIT_SCHED)
    122#define TICK_DEP_MASK_CLOCK_UNSTABLE	(1 << TICK_DEP_BIT_CLOCK_UNSTABLE)
    123#define TICK_DEP_MASK_RCU		(1 << TICK_DEP_BIT_RCU)
    124#define TICK_DEP_MASK_RCU_EXP		(1 << TICK_DEP_BIT_RCU_EXP)
    125
    126#ifdef CONFIG_NO_HZ_COMMON
    127extern bool tick_nohz_enabled;
    128extern bool tick_nohz_tick_stopped(void);
    129extern bool tick_nohz_tick_stopped_cpu(int cpu);
    130extern void tick_nohz_idle_stop_tick(void);
    131extern void tick_nohz_idle_retain_tick(void);
    132extern void tick_nohz_idle_restart_tick(void);
    133extern void tick_nohz_idle_enter(void);
    134extern void tick_nohz_idle_exit(void);
    135extern void tick_nohz_irq_exit(void);
    136extern bool tick_nohz_idle_got_tick(void);
    137extern ktime_t tick_nohz_get_next_hrtimer(void);
    138extern ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next);
    139extern unsigned long tick_nohz_get_idle_calls(void);
    140extern unsigned long tick_nohz_get_idle_calls_cpu(int cpu);
    141extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
    142extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
    143
    144static inline void tick_nohz_idle_stop_tick_protected(void)
    145{
    146	local_irq_disable();
    147	tick_nohz_idle_stop_tick();
    148	local_irq_enable();
    149}
    150
    151#else /* !CONFIG_NO_HZ_COMMON */
    152#define tick_nohz_enabled (0)
    153static inline int tick_nohz_tick_stopped(void) { return 0; }
    154static inline int tick_nohz_tick_stopped_cpu(int cpu) { return 0; }
    155static inline void tick_nohz_idle_stop_tick(void) { }
    156static inline void tick_nohz_idle_retain_tick(void) { }
    157static inline void tick_nohz_idle_restart_tick(void) { }
    158static inline void tick_nohz_idle_enter(void) { }
    159static inline void tick_nohz_idle_exit(void) { }
    160static inline bool tick_nohz_idle_got_tick(void) { return false; }
    161static inline ktime_t tick_nohz_get_next_hrtimer(void)
    162{
    163	/* Next wake up is the tick period, assume it starts now */
    164	return ktime_add(ktime_get(), TICK_NSEC);
    165}
    166static inline ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next)
    167{
    168	*delta_next = TICK_NSEC;
    169	return *delta_next;
    170}
    171static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
    172static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
    173
    174static inline void tick_nohz_idle_stop_tick_protected(void) { }
    175#endif /* !CONFIG_NO_HZ_COMMON */
    176
    177#ifdef CONFIG_NO_HZ_FULL
    178extern bool tick_nohz_full_running;
    179extern cpumask_var_t tick_nohz_full_mask;
    180
    181static inline bool tick_nohz_full_enabled(void)
    182{
    183	if (!context_tracking_enabled())
    184		return false;
    185
    186	return tick_nohz_full_running;
    187}
    188
    189/*
    190 * Check if a CPU is part of the nohz_full subset. Arrange for evaluating
    191 * the cpu expression (typically smp_processor_id()) _after_ the static
    192 * key.
    193 */
    194#define tick_nohz_full_cpu(_cpu) ({					\
    195	bool __ret = false;						\
    196	if (tick_nohz_full_enabled())					\
    197		__ret = cpumask_test_cpu((_cpu), tick_nohz_full_mask);	\
    198	__ret;								\
    199})
    200
    201static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
    202{
    203	if (tick_nohz_full_enabled())
    204		cpumask_or(mask, mask, tick_nohz_full_mask);
    205}
    206
    207extern void tick_nohz_dep_set(enum tick_dep_bits bit);
    208extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
    209extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
    210extern void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit);
    211extern void tick_nohz_dep_set_task(struct task_struct *tsk,
    212				   enum tick_dep_bits bit);
    213extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
    214				     enum tick_dep_bits bit);
    215extern void tick_nohz_dep_set_signal(struct task_struct *tsk,
    216				     enum tick_dep_bits bit);
    217extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
    218				       enum tick_dep_bits bit);
    219
    220/*
    221 * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
    222 * on top of static keys.
    223 */
    224static inline void tick_dep_set(enum tick_dep_bits bit)
    225{
    226	if (tick_nohz_full_enabled())
    227		tick_nohz_dep_set(bit);
    228}
    229
    230static inline void tick_dep_clear(enum tick_dep_bits bit)
    231{
    232	if (tick_nohz_full_enabled())
    233		tick_nohz_dep_clear(bit);
    234}
    235
    236static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit)
    237{
    238	if (tick_nohz_full_cpu(cpu))
    239		tick_nohz_dep_set_cpu(cpu, bit);
    240}
    241
    242static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
    243{
    244	if (tick_nohz_full_cpu(cpu))
    245		tick_nohz_dep_clear_cpu(cpu, bit);
    246}
    247
    248static inline void tick_dep_set_task(struct task_struct *tsk,
    249				     enum tick_dep_bits bit)
    250{
    251	if (tick_nohz_full_enabled())
    252		tick_nohz_dep_set_task(tsk, bit);
    253}
    254static inline void tick_dep_clear_task(struct task_struct *tsk,
    255				       enum tick_dep_bits bit)
    256{
    257	if (tick_nohz_full_enabled())
    258		tick_nohz_dep_clear_task(tsk, bit);
    259}
    260static inline void tick_dep_set_signal(struct task_struct *tsk,
    261				       enum tick_dep_bits bit)
    262{
    263	if (tick_nohz_full_enabled())
    264		tick_nohz_dep_set_signal(tsk, bit);
    265}
    266static inline void tick_dep_clear_signal(struct signal_struct *signal,
    267					 enum tick_dep_bits bit)
    268{
    269	if (tick_nohz_full_enabled())
    270		tick_nohz_dep_clear_signal(signal, bit);
    271}
    272
    273extern void tick_nohz_full_kick_cpu(int cpu);
    274extern void __tick_nohz_task_switch(void);
    275extern void __init tick_nohz_full_setup(cpumask_var_t cpumask);
    276#else
    277static inline bool tick_nohz_full_enabled(void) { return false; }
    278static inline bool tick_nohz_full_cpu(int cpu) { return false; }
    279static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
    280
    281static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
    282static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
    283
    284static inline void tick_dep_set(enum tick_dep_bits bit) { }
    285static inline void tick_dep_clear(enum tick_dep_bits bit) { }
    286static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
    287static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
    288static inline void tick_dep_set_task(struct task_struct *tsk,
    289				     enum tick_dep_bits bit) { }
    290static inline void tick_dep_clear_task(struct task_struct *tsk,
    291				       enum tick_dep_bits bit) { }
    292static inline void tick_dep_set_signal(struct task_struct *tsk,
    293				       enum tick_dep_bits bit) { }
    294static inline void tick_dep_clear_signal(struct signal_struct *signal,
    295					 enum tick_dep_bits bit) { }
    296
    297static inline void tick_nohz_full_kick_cpu(int cpu) { }
    298static inline void __tick_nohz_task_switch(void) { }
    299static inline void tick_nohz_full_setup(cpumask_var_t cpumask) { }
    300#endif
    301
    302static inline void tick_nohz_task_switch(void)
    303{
    304	if (tick_nohz_full_enabled())
    305		__tick_nohz_task_switch();
    306}
    307
    308static inline void tick_nohz_user_enter_prepare(void)
    309{
    310	if (tick_nohz_full_cpu(smp_processor_id()))
    311		rcu_nocb_flush_deferred_wakeup();
    312}
    313
    314#endif