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

return_address.c (1133B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * arch/arm/kernel/return_address.c
      4 *
      5 * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
      6 * for Pengutronix
      7 */
      8#include <linux/export.h>
      9#include <linux/ftrace.h>
     10#include <linux/sched.h>
     11
     12#include <asm/stacktrace.h>
     13
     14struct return_address_data {
     15	unsigned int level;
     16	void *addr;
     17};
     18
     19static int save_return_addr(struct stackframe *frame, void *d)
     20{
     21	struct return_address_data *data = d;
     22
     23	if (!data->level) {
     24		data->addr = (void *)frame->pc;
     25
     26		return 1;
     27	} else {
     28		--data->level;
     29		return 0;
     30	}
     31}
     32
     33void *return_address(unsigned int level)
     34{
     35	struct return_address_data data;
     36	struct stackframe frame;
     37
     38	data.level = level + 2;
     39	data.addr = NULL;
     40
     41	frame.fp = (unsigned long)__builtin_frame_address(0);
     42	frame.sp = current_stack_pointer;
     43	frame.lr = (unsigned long)__builtin_return_address(0);
     44here:
     45	frame.pc = (unsigned long)&&here;
     46#ifdef CONFIG_KRETPROBES
     47	frame.kr_cur = NULL;
     48	frame.tsk = current;
     49#endif
     50
     51	walk_stackframe(&frame, save_return_addr, &data);
     52
     53	if (!data.level)
     54		return data.addr;
     55	else
     56		return NULL;
     57}
     58
     59EXPORT_SYMBOL_GPL(return_address);