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

gen-atomic-instrumented.sh (4503B)


      1#!/bin/sh
      2# SPDX-License-Identifier: GPL-2.0
      3
      4ATOMICDIR=$(dirname $0)
      5
      6. ${ATOMICDIR}/atomic-tbl.sh
      7
      8#gen_param_check(meta, arg)
      9gen_param_check()
     10{
     11	local meta="$1"; shift
     12	local arg="$1"; shift
     13	local type="${arg%%:*}"
     14	local name="$(gen_param_name "${arg}")"
     15	local rw="write"
     16
     17	case "${type#c}" in
     18	i) return;;
     19	esac
     20
     21	if [ ${type#c} != ${type} ]; then
     22		# We don't write to constant parameters.
     23		rw="read"
     24	elif [ "${meta}" != "s" ]; then
     25		# An atomic RMW: if this parameter is not a constant, and this atomic is
     26		# not just a 's'tore, this parameter is both read from and written to.
     27		rw="read_write"
     28	fi
     29
     30	printf "\tinstrument_atomic_${rw}(${name}, sizeof(*${name}));\n"
     31}
     32
     33#gen_params_checks(meta, arg...)
     34gen_params_checks()
     35{
     36	local meta="$1"; shift
     37	local order="$1"; shift
     38
     39	if [ "${order}" = "_release" ]; then
     40		printf "\tkcsan_release();\n"
     41	elif [ -z "${order}" ] && ! meta_in "$meta" "slv"; then
     42		# RMW with return value is fully ordered
     43		printf "\tkcsan_mb();\n"
     44	fi
     45
     46	while [ "$#" -gt 0 ]; do
     47		gen_param_check "$meta" "$1"
     48		shift;
     49	done
     50}
     51
     52#gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, arg...)
     53gen_proto_order_variant()
     54{
     55	local meta="$1"; shift
     56	local pfx="$1"; shift
     57	local name="$1"; shift
     58	local sfx="$1"; shift
     59	local order="$1"; shift
     60	local atomic="$1"; shift
     61	local int="$1"; shift
     62
     63	local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
     64
     65	local ret="$(gen_ret_type "${meta}" "${int}")"
     66	local params="$(gen_params "${int}" "${atomic}" "$@")"
     67	local checks="$(gen_params_checks "${meta}" "${order}" "$@")"
     68	local args="$(gen_args "$@")"
     69	local retstmt="$(gen_ret_stmt "${meta}")"
     70
     71cat <<EOF
     72static __always_inline ${ret}
     73${atomicname}(${params})
     74{
     75${checks}
     76	${retstmt}arch_${atomicname}(${args});
     77}
     78EOF
     79
     80	printf "\n"
     81}
     82
     83gen_xchg()
     84{
     85	local xchg="$1"; shift
     86	local order="$1"; shift
     87	local mult="$1"; shift
     88
     89	kcsan_barrier=""
     90	if [ "${xchg%_local}" = "${xchg}" ]; then
     91		case "$order" in
     92		_release)	kcsan_barrier="kcsan_release()" ;;
     93		"")			kcsan_barrier="kcsan_mb()" ;;
     94		esac
     95	fi
     96
     97	if [ "${xchg%${xchg#try_cmpxchg}}" = "try_cmpxchg" ] ; then
     98
     99cat <<EOF
    100#define ${xchg}${order}(ptr, oldp, ...) \\
    101({ \\
    102	typeof(ptr) __ai_ptr = (ptr); \\
    103	typeof(oldp) __ai_oldp = (oldp); \\
    104EOF
    105[ -n "$kcsan_barrier" ] && printf "\t${kcsan_barrier}; \\\\\n"
    106cat <<EOF
    107	instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\
    108	instrument_atomic_write(__ai_oldp, ${mult}sizeof(*__ai_oldp)); \\
    109	arch_${xchg}${order}(__ai_ptr, __ai_oldp, __VA_ARGS__); \\
    110})
    111EOF
    112
    113	else
    114
    115cat <<EOF
    116#define ${xchg}${order}(ptr, ...) \\
    117({ \\
    118	typeof(ptr) __ai_ptr = (ptr); \\
    119EOF
    120[ -n "$kcsan_barrier" ] && printf "\t${kcsan_barrier}; \\\\\n"
    121cat <<EOF
    122	instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\
    123	arch_${xchg}${order}(__ai_ptr, __VA_ARGS__); \\
    124})
    125EOF
    126
    127	fi
    128}
    129
    130cat << EOF
    131// SPDX-License-Identifier: GPL-2.0
    132
    133// Generated by $0
    134// DO NOT MODIFY THIS FILE DIRECTLY
    135
    136/*
    137 * This file provides wrappers with KASAN instrumentation for atomic operations.
    138 * To use this functionality an arch's atomic.h file needs to define all
    139 * atomic operations with arch_ prefix (e.g. arch_atomic_read()) and include
    140 * this file at the end. This file provides atomic_read() that forwards to
    141 * arch_atomic_read() for actual atomic operation.
    142 * Note: if an arch atomic operation is implemented by means of other atomic
    143 * operations (e.g. atomic_read()/atomic_cmpxchg() loop), then it needs to use
    144 * arch_ variants (i.e. arch_atomic_read()/arch_atomic_cmpxchg()) to avoid
    145 * double instrumentation.
    146 */
    147#ifndef _LINUX_ATOMIC_INSTRUMENTED_H
    148#define _LINUX_ATOMIC_INSTRUMENTED_H
    149
    150#include <linux/build_bug.h>
    151#include <linux/compiler.h>
    152#include <linux/instrumented.h>
    153
    154EOF
    155
    156grep '^[a-z]' "$1" | while read name meta args; do
    157	gen_proto "${meta}" "${name}" "atomic" "int" ${args}
    158done
    159
    160grep '^[a-z]' "$1" | while read name meta args; do
    161	gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
    162done
    163
    164grep '^[a-z]' "$1" | while read name meta args; do
    165	gen_proto "${meta}" "${name}" "atomic_long" "long" ${args}
    166done
    167
    168
    169for xchg in "xchg" "cmpxchg" "cmpxchg64" "try_cmpxchg" "try_cmpxchg64"; do
    170	for order in "" "_acquire" "_release" "_relaxed"; do
    171		gen_xchg "${xchg}" "${order}" ""
    172		printf "\n"
    173	done
    174done
    175
    176for xchg in "cmpxchg_local" "cmpxchg64_local" "sync_cmpxchg"; do
    177	gen_xchg "${xchg}" "" ""
    178	printf "\n"
    179done
    180
    181gen_xchg "cmpxchg_double" "" "2 * "
    182
    183printf "\n\n"
    184
    185gen_xchg "cmpxchg_double_local" "" "2 * "
    186
    187cat <<EOF
    188
    189#endif /* _LINUX_ATOMIC_INSTRUMENTED_H */
    190EOF