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.c (1836B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
      4 * Copyright (C) 2013 Richard Weinberger <richard@nod.at>
      5 * Copyright (C) 2014 Google Inc., Author: Daniel Walter <dwalter@google.com>
      6 */
      7
      8#include <linux/kallsyms.h>
      9#include <linux/kernel.h>
     10#include <linux/sched.h>
     11#include <linux/stacktrace.h>
     12#include <linux/module.h>
     13#include <linux/uaccess.h>
     14#include <asm/stacktrace.h>
     15
     16void dump_trace(struct task_struct *tsk,
     17		const struct stacktrace_ops *ops,
     18		void *data)
     19{
     20	int reliable = 0;
     21	unsigned long *sp, bp, addr;
     22	struct pt_regs *segv_regs = tsk->thread.segv_regs;
     23	struct stack_frame *frame;
     24
     25	bp = get_frame_pointer(tsk, segv_regs);
     26	sp = get_stack_pointer(tsk, segv_regs);
     27
     28	frame = (struct stack_frame *)bp;
     29	while (((long) sp & (THREAD_SIZE-1)) != 0) {
     30		addr = *sp;
     31		if (__kernel_text_address(addr)) {
     32			reliable = 0;
     33			if ((unsigned long) sp == bp + sizeof(long)) {
     34				frame = frame ? frame->next_frame : NULL;
     35				bp = (unsigned long)frame;
     36				reliable = 1;
     37			}
     38			ops->address(data, addr, reliable);
     39		}
     40		sp++;
     41	}
     42}
     43
     44static void save_addr(void *data, unsigned long address, int reliable)
     45{
     46	struct stack_trace *trace = data;
     47
     48	if (!reliable)
     49		return;
     50	if (trace->nr_entries >= trace->max_entries)
     51		return;
     52
     53	trace->entries[trace->nr_entries++] = address;
     54}
     55
     56static const struct stacktrace_ops dump_ops = {
     57	.address = save_addr
     58};
     59
     60static void __save_stack_trace(struct task_struct *tsk, struct stack_trace *trace)
     61{
     62	dump_trace(tsk, &dump_ops, trace);
     63}
     64
     65void save_stack_trace(struct stack_trace *trace)
     66{
     67	__save_stack_trace(current, trace);
     68}
     69EXPORT_SYMBOL_GPL(save_stack_trace);
     70
     71void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
     72{
     73	__save_stack_trace(tsk, trace);
     74}
     75EXPORT_SYMBOL_GPL(save_stack_trace_tsk);