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

stacktrace.h (2850B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 *  Copyright (C) 1991, 1992  Linus Torvalds
      4 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
      5 */
      6
      7#ifndef _ASM_X86_STACKTRACE_H
      8#define _ASM_X86_STACKTRACE_H
      9
     10#include <linux/uaccess.h>
     11#include <linux/ptrace.h>
     12
     13#include <asm/cpu_entry_area.h>
     14#include <asm/switch_to.h>
     15
     16enum stack_type {
     17	STACK_TYPE_UNKNOWN,
     18	STACK_TYPE_TASK,
     19	STACK_TYPE_IRQ,
     20	STACK_TYPE_SOFTIRQ,
     21	STACK_TYPE_ENTRY,
     22	STACK_TYPE_EXCEPTION,
     23	STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1,
     24};
     25
     26struct stack_info {
     27	enum stack_type type;
     28	unsigned long *begin, *end, *next_sp;
     29};
     30
     31bool in_task_stack(unsigned long *stack, struct task_struct *task,
     32		   struct stack_info *info);
     33
     34bool in_entry_stack(unsigned long *stack, struct stack_info *info);
     35
     36int get_stack_info(unsigned long *stack, struct task_struct *task,
     37		   struct stack_info *info, unsigned long *visit_mask);
     38bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task,
     39			    struct stack_info *info);
     40
     41static __always_inline
     42bool get_stack_guard_info(unsigned long *stack, struct stack_info *info)
     43{
     44	/* make sure it's not in the stack proper */
     45	if (get_stack_info_noinstr(stack, current, info))
     46		return false;
     47	/* but if it is in the page below it, we hit a guard */
     48	return get_stack_info_noinstr((void *)stack + PAGE_SIZE, current, info);
     49}
     50
     51const char *stack_type_name(enum stack_type type);
     52
     53static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
     54{
     55	void *begin = info->begin;
     56	void *end   = info->end;
     57
     58	return (info->type != STACK_TYPE_UNKNOWN &&
     59		addr >= begin && addr < end &&
     60		addr + len > begin && addr + len <= end);
     61}
     62
     63#ifdef CONFIG_X86_32
     64#define STACKSLOTS_PER_LINE 8
     65#else
     66#define STACKSLOTS_PER_LINE 4
     67#endif
     68
     69#ifdef CONFIG_FRAME_POINTER
     70static inline unsigned long *
     71get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
     72{
     73	if (regs)
     74		return (unsigned long *)regs->bp;
     75
     76	if (task == current)
     77		return __builtin_frame_address(0);
     78
     79	return &((struct inactive_task_frame *)task->thread.sp)->bp;
     80}
     81#else
     82static inline unsigned long *
     83get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
     84{
     85	return NULL;
     86}
     87#endif /* CONFIG_FRAME_POINTER */
     88
     89static inline unsigned long *
     90get_stack_pointer(struct task_struct *task, struct pt_regs *regs)
     91{
     92	if (regs)
     93		return (unsigned long *)regs->sp;
     94
     95	if (task == current)
     96		return __builtin_frame_address(0);
     97
     98	return (unsigned long *)task->thread.sp;
     99}
    100
    101/* The form of the top of the frame on the stack */
    102struct stack_frame {
    103	struct stack_frame *next_frame;
    104	unsigned long return_address;
    105};
    106
    107struct stack_frame_ia32 {
    108    u32 next_frame;
    109    u32 return_address;
    110};
    111
    112void show_opcodes(struct pt_regs *regs, const char *loglvl);
    113void show_ip(struct pt_regs *regs, const char *loglvl);
    114#endif /* _ASM_X86_STACKTRACE_H */