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