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

instrumentation.h (2002B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __LINUX_INSTRUMENTATION_H
      3#define __LINUX_INSTRUMENTATION_H
      4
      5#ifdef CONFIG_NOINSTR_VALIDATION
      6
      7#include <linux/stringify.h>
      8
      9/* Begin/end of an instrumentation safe region */
     10#define __instrumentation_begin(c) ({					\
     11	asm volatile(__stringify(c) ": nop\n\t"				\
     12		     ".pushsection .discard.instr_begin\n\t"		\
     13		     ".long " __stringify(c) "b - .\n\t"		\
     14		     ".popsection\n\t" : : "i" (c));			\
     15})
     16#define instrumentation_begin() __instrumentation_begin(__COUNTER__)
     17
     18/*
     19 * Because instrumentation_{begin,end}() can nest, objtool validation considers
     20 * _begin() a +1 and _end() a -1 and computes a sum over the instructions.
     21 * When the value is greater than 0, we consider instrumentation allowed.
     22 *
     23 * There is a problem with code like:
     24 *
     25 * noinstr void foo()
     26 * {
     27 *	instrumentation_begin();
     28 *	...
     29 *	if (cond) {
     30 *		instrumentation_begin();
     31 *		...
     32 *		instrumentation_end();
     33 *	}
     34 *	bar();
     35 *	instrumentation_end();
     36 * }
     37 *
     38 * If instrumentation_end() would be an empty label, like all the other
     39 * annotations, the inner _end(), which is at the end of a conditional block,
     40 * would land on the instruction after the block.
     41 *
     42 * If we then consider the sum of the !cond path, we'll see that the call to
     43 * bar() is with a 0-value, even though, we meant it to happen with a positive
     44 * value.
     45 *
     46 * To avoid this, have _end() be a NOP instruction, this ensures it will be
     47 * part of the condition block and does not escape.
     48 */
     49#define __instrumentation_end(c) ({					\
     50	asm volatile(__stringify(c) ": nop\n\t"				\
     51		     ".pushsection .discard.instr_end\n\t"		\
     52		     ".long " __stringify(c) "b - .\n\t"		\
     53		     ".popsection\n\t" : : "i" (c));			\
     54})
     55#define instrumentation_end() __instrumentation_end(__COUNTER__)
     56#else /* !CONFIG_NOINSTR_VALIDATION */
     57# define instrumentation_begin()	do { } while(0)
     58# define instrumentation_end()		do { } while(0)
     59#endif /* CONFIG_NOINSTR_VALIDATION */
     60
     61#endif /* __LINUX_INSTRUMENTATION_H */