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

scs.h (1869B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Shadow Call Stack support.
      4 *
      5 * Copyright (C) 2019 Google LLC
      6 */
      7
      8#ifndef _LINUX_SCS_H
      9#define _LINUX_SCS_H
     10
     11#include <linux/gfp.h>
     12#include <linux/poison.h>
     13#include <linux/sched.h>
     14#include <linux/sizes.h>
     15
     16#ifdef CONFIG_SHADOW_CALL_STACK
     17
     18#define SCS_ORDER		0
     19#define SCS_SIZE		(PAGE_SIZE << SCS_ORDER)
     20#define GFP_SCS			(GFP_KERNEL | __GFP_ZERO)
     21
     22/* An illegal pointer value to mark the end of the shadow stack. */
     23#define SCS_END_MAGIC		(0x5f6UL + POISON_POINTER_DELTA)
     24
     25#define task_scs(tsk)		(task_thread_info(tsk)->scs_base)
     26#define task_scs_sp(tsk)	(task_thread_info(tsk)->scs_sp)
     27
     28void *scs_alloc(int node);
     29void scs_free(void *s);
     30void scs_init(void);
     31int scs_prepare(struct task_struct *tsk, int node);
     32void scs_release(struct task_struct *tsk);
     33
     34static inline void scs_task_reset(struct task_struct *tsk)
     35{
     36	/*
     37	 * Reset the shadow stack to the base address in case the task
     38	 * is reused.
     39	 */
     40	task_scs_sp(tsk) = task_scs(tsk);
     41}
     42
     43static inline unsigned long *__scs_magic(void *s)
     44{
     45	return (unsigned long *)(s + SCS_SIZE) - 1;
     46}
     47
     48static inline bool task_scs_end_corrupted(struct task_struct *tsk)
     49{
     50	unsigned long *magic = __scs_magic(task_scs(tsk));
     51	unsigned long sz = task_scs_sp(tsk) - task_scs(tsk);
     52
     53	return sz >= SCS_SIZE - 1 || READ_ONCE_NOCHECK(*magic) != SCS_END_MAGIC;
     54}
     55
     56#else /* CONFIG_SHADOW_CALL_STACK */
     57
     58static inline void *scs_alloc(int node) { return NULL; }
     59static inline void scs_free(void *s) {}
     60static inline void scs_init(void) {}
     61static inline void scs_task_reset(struct task_struct *tsk) {}
     62static inline int scs_prepare(struct task_struct *tsk, int node) { return 0; }
     63static inline void scs_release(struct task_struct *tsk) {}
     64static inline bool task_scs_end_corrupted(struct task_struct *tsk) { return false; }
     65
     66#endif /* CONFIG_SHADOW_CALL_STACK */
     67
     68#endif /* _LINUX_SCS_H */