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

task_stack.h (3176B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _LINUX_SCHED_TASK_STACK_H
      3#define _LINUX_SCHED_TASK_STACK_H
      4
      5/*
      6 * task->stack (kernel stack) handling interfaces:
      7 */
      8
      9#include <linux/sched.h>
     10#include <linux/magic.h>
     11
     12#ifdef CONFIG_THREAD_INFO_IN_TASK
     13
     14/*
     15 * When accessing the stack of a non-current task that might exit, use
     16 * try_get_task_stack() instead.  task_stack_page will return a pointer
     17 * that could get freed out from under you.
     18 */
     19static __always_inline void *task_stack_page(const struct task_struct *task)
     20{
     21	return task->stack;
     22}
     23
     24#define setup_thread_stack(new,old)	do { } while(0)
     25
     26static inline unsigned long *end_of_stack(const struct task_struct *task)
     27{
     28#ifdef CONFIG_STACK_GROWSUP
     29	return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1;
     30#else
     31	return task->stack;
     32#endif
     33}
     34
     35#elif !defined(__HAVE_THREAD_FUNCTIONS)
     36
     37#define task_stack_page(task)	((void *)(task)->stack)
     38
     39static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
     40{
     41	*task_thread_info(p) = *task_thread_info(org);
     42	task_thread_info(p)->task = p;
     43}
     44
     45/*
     46 * Return the address of the last usable long on the stack.
     47 *
     48 * When the stack grows down, this is just above the thread
     49 * info struct. Going any lower will corrupt the threadinfo.
     50 *
     51 * When the stack grows up, this is the highest address.
     52 * Beyond that position, we corrupt data on the next page.
     53 */
     54static inline unsigned long *end_of_stack(struct task_struct *p)
     55{
     56#ifdef CONFIG_STACK_GROWSUP
     57	return (unsigned long *)((unsigned long)task_thread_info(p) + THREAD_SIZE) - 1;
     58#else
     59	return (unsigned long *)(task_thread_info(p) + 1);
     60#endif
     61}
     62
     63#endif
     64
     65#ifdef CONFIG_THREAD_INFO_IN_TASK
     66static inline void *try_get_task_stack(struct task_struct *tsk)
     67{
     68	return refcount_inc_not_zero(&tsk->stack_refcount) ?
     69		task_stack_page(tsk) : NULL;
     70}
     71
     72extern void put_task_stack(struct task_struct *tsk);
     73#else
     74static inline void *try_get_task_stack(struct task_struct *tsk)
     75{
     76	return task_stack_page(tsk);
     77}
     78
     79static inline void put_task_stack(struct task_struct *tsk) {}
     80#endif
     81
     82void exit_task_stack_account(struct task_struct *tsk);
     83
     84#define task_stack_end_corrupted(task) \
     85		(*(end_of_stack(task)) != STACK_END_MAGIC)
     86
     87static inline int object_is_on_stack(const void *obj)
     88{
     89	void *stack = task_stack_page(current);
     90
     91	return (obj >= stack) && (obj < (stack + THREAD_SIZE));
     92}
     93
     94extern void thread_stack_cache_init(void);
     95
     96#ifdef CONFIG_DEBUG_STACK_USAGE
     97static inline unsigned long stack_not_used(struct task_struct *p)
     98{
     99	unsigned long *n = end_of_stack(p);
    100
    101	do { 	/* Skip over canary */
    102# ifdef CONFIG_STACK_GROWSUP
    103		n--;
    104# else
    105		n++;
    106# endif
    107	} while (!*n);
    108
    109# ifdef CONFIG_STACK_GROWSUP
    110	return (unsigned long)end_of_stack(p) - (unsigned long)n;
    111# else
    112	return (unsigned long)n - (unsigned long)end_of_stack(p);
    113# endif
    114}
    115#endif
    116extern void set_task_stack_end_magic(struct task_struct *tsk);
    117
    118#ifndef __HAVE_ARCH_KSTACK_END
    119static inline int kstack_end(void *addr)
    120{
    121	/* Reliable end of stack detection:
    122	 * Some APM bios versions misalign the stack
    123	 */
    124	return !(((unsigned long)addr+sizeof(void*)-1) & (THREAD_SIZE-sizeof(void*)));
    125}
    126#endif
    127
    128#endif /* _LINUX_SCHED_TASK_STACK_H */