xref: /openbmc/linux/scripts/atomic/gen-atomic-instrumented.sh (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1ace9bad4SMark Rutland#!/bin/sh
2ace9bad4SMark Rutland# SPDX-License-Identifier: GPL-2.0
3ace9bad4SMark Rutland
4ace9bad4SMark RutlandATOMICDIR=$(dirname $0)
5ace9bad4SMark Rutland
6ace9bad4SMark Rutland. ${ATOMICDIR}/atomic-tbl.sh
7ace9bad4SMark Rutland
83570a1bcSMarco Elver#gen_param_check(meta, arg)
9ace9bad4SMark Rutlandgen_param_check()
10ace9bad4SMark Rutland{
113570a1bcSMarco Elver	local meta="$1"; shift
12ace9bad4SMark Rutland	local arg="$1"; shift
13ace9bad4SMark Rutland	local type="${arg%%:*}"
14ace9bad4SMark Rutland	local name="$(gen_param_name "${arg}")"
15ace9bad4SMark Rutland	local rw="write"
16ace9bad4SMark Rutland
17ace9bad4SMark Rutland	case "${type#c}" in
18ace9bad4SMark Rutland	i) return;;
19ace9bad4SMark Rutland	esac
20ace9bad4SMark Rutland
213570a1bcSMarco Elver	if [ ${type#c} != ${type} ]; then
223570a1bcSMarco Elver		# We don't write to constant parameters.
233570a1bcSMarco Elver		rw="read"
243570a1bcSMarco Elver	elif [ "${meta}" != "s" ]; then
253570a1bcSMarco Elver		# An atomic RMW: if this parameter is not a constant, and this atomic is
263570a1bcSMarco Elver		# not just a 's'tore, this parameter is both read from and written to.
273570a1bcSMarco Elver		rw="read_write"
283570a1bcSMarco Elver	fi
29ace9bad4SMark Rutland
30ed8af2e4SMarco Elver	printf "\tinstrument_atomic_${rw}(${name}, sizeof(*${name}));\n"
31ace9bad4SMark Rutland}
32ace9bad4SMark Rutland
333570a1bcSMarco Elver#gen_params_checks(meta, arg...)
34ace9bad4SMark Rutlandgen_params_checks()
35ace9bad4SMark Rutland{
363570a1bcSMarco Elver	local meta="$1"; shift
37e87c4f66SMarco Elver	local order="$1"; shift
38e87c4f66SMarco Elver
39e87c4f66SMarco Elver	if [ "${order}" = "_release" ]; then
40e87c4f66SMarco Elver		printf "\tkcsan_release();\n"
41e87c4f66SMarco Elver	elif [ -z "${order}" ] && ! meta_in "$meta" "slv"; then
42e87c4f66SMarco Elver		# RMW with return value is fully ordered
43e87c4f66SMarco Elver		printf "\tkcsan_mb();\n"
44e87c4f66SMarco Elver	fi
453570a1bcSMarco Elver
46ace9bad4SMark Rutland	while [ "$#" -gt 0 ]; do
473570a1bcSMarco Elver		gen_param_check "$meta" "$1"
48ace9bad4SMark Rutland		shift;
49ace9bad4SMark Rutland	done
50ace9bad4SMark Rutland}
51ace9bad4SMark Rutland
52ace9bad4SMark Rutland#gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, arg...)
53ace9bad4SMark Rutlandgen_proto_order_variant()
54ace9bad4SMark Rutland{
55ace9bad4SMark Rutland	local meta="$1"; shift
56ace9bad4SMark Rutland	local pfx="$1"; shift
57ace9bad4SMark Rutland	local name="$1"; shift
58ace9bad4SMark Rutland	local sfx="$1"; shift
59ace9bad4SMark Rutland	local order="$1"; shift
60ace9bad4SMark Rutland	local atomic="$1"; shift
61ace9bad4SMark Rutland	local int="$1"; shift
62ace9bad4SMark Rutland
63ace9bad4SMark Rutland	local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
64ace9bad4SMark Rutland
65ace9bad4SMark Rutland	local ret="$(gen_ret_type "${meta}" "${int}")"
66ace9bad4SMark Rutland	local params="$(gen_params "${int}" "${atomic}" "$@")"
67e87c4f66SMarco Elver	local checks="$(gen_params_checks "${meta}" "${order}" "$@")"
68ace9bad4SMark Rutland	local args="$(gen_args "$@")"
69ace9bad4SMark Rutland	local retstmt="$(gen_ret_stmt "${meta}")"
70ace9bad4SMark Rutland
71ace9bad4SMark Rutland	gen_kerneldoc "" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "${atomic}" "${int}" "$@"
72c020395bSMarco Elver
73ace9bad4SMark Rutlandcat <<EOF
74ace9bad4SMark Rutlandstatic __always_inline ${ret}
75ace9bad4SMark Rutland${atomicname}(${params})
76ace9bad4SMark Rutland{
77ace9bad4SMark Rutland${checks}
78ace9bad4SMark Rutland	${retstmt}raw_${atomicname}(${args});
79ace9bad4SMark Rutland}
80ace9bad4SMark RutlandEOF
81ace9bad4SMark Rutland
82ace9bad4SMark Rutland	printf "\n"
83ace9bad4SMark Rutland}
84ace9bad4SMark Rutland
85ace9bad4SMark Rutlandgen_xchg()
86e87c4f66SMarco Elver{
87ace9bad4SMark Rutland	local xchg="$1"; shift
88ace9bad4SMark Rutland	local order="$1"; shift
89e87c4f66SMarco Elver
90e87c4f66SMarco Elver	kcsan_barrier=""
91e87c4f66SMarco Elver	if [ "${xchg%_local}" = "${xchg}" ]; then
92e87c4f66SMarco Elver		case "$order" in
93e87c4f66SMarco Elver		_release)	kcsan_barrier="kcsan_release()" ;;
94e87c4f66SMarco Elver		"")			kcsan_barrier="kcsan_mb()" ;;
95e87c4f66SMarco Elver		esac
96e87c4f66SMarco Elver	fi
9729f006fdSPeter Zijlstra
9829f006fdSPeter Zijlstra	if [ "${xchg%${xchg#try_cmpxchg}}" = "try_cmpxchg" ] ; then
9929f006fdSPeter Zijlstra
100e87c4f66SMarco Elvercat <<EOF
10129f006fdSPeter Zijlstra#define ${xchg}${order}(ptr, oldp, ...) \\
10229f006fdSPeter Zijlstra({ \\
10329f006fdSPeter Zijlstra	typeof(ptr) __ai_ptr = (ptr); \\
104e87c4f66SMarco Elver	typeof(oldp) __ai_oldp = (oldp); \\
105e87c4f66SMarco ElverEOF
106e87c4f66SMarco Elver[ -n "$kcsan_barrier" ] && printf "\t${kcsan_barrier}; \\\\\n"
107*ec570320SMark Rutlandcat <<EOF
108*ec570320SMark Rutland	instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \\
109e87c4f66SMarco Elver	instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \\
11029f006fdSPeter Zijlstra	raw_${xchg}${order}(__ai_ptr, __ai_oldp, __VA_ARGS__); \\
11129f006fdSPeter Zijlstra})
11229f006fdSPeter ZijlstraEOF
11329f006fdSPeter Zijlstra
11429f006fdSPeter Zijlstra	else
115ace9bad4SMark Rutland
116e87c4f66SMarco Elvercat <<EOF
117ace9bad4SMark Rutland#define ${xchg}${order}(ptr, ...) \\
118ace9bad4SMark Rutland({ \\
119e87c4f66SMarco Elver	typeof(ptr) __ai_ptr = (ptr); \\
120e87c4f66SMarco ElverEOF
121e87c4f66SMarco Elver[ -n "$kcsan_barrier" ] && printf "\t${kcsan_barrier}; \\\\\n"
122*ec570320SMark Rutlandcat <<EOF
123e87c4f66SMarco Elver	instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \\
124ace9bad4SMark Rutland	raw_${xchg}${order}(__ai_ptr, __VA_ARGS__); \\
125ace9bad4SMark Rutland})
12629f006fdSPeter ZijlstraEOF
12729f006fdSPeter Zijlstra
128ace9bad4SMark Rutland	fi
129ace9bad4SMark Rutland}
130ace9bad4SMark Rutland
131ace9bad4SMark Rutlandcat << EOF
132ace9bad4SMark Rutland// SPDX-License-Identifier: GPL-2.0
133ace9bad4SMark Rutland
134ace9bad4SMark Rutland// Generated by $0
135ace9bad4SMark Rutland// DO NOT MODIFY THIS FILE DIRECTLY
136ace9bad4SMark Rutland
137ace9bad4SMark Rutland/*
138ace9bad4SMark Rutland * This file provoides atomic operations with explicit instrumentation (e.g.
139ace9bad4SMark Rutland * KASAN, KCSAN), which should be used unless it is necessary to avoid
140ace9bad4SMark Rutland * instrumentation. Where it is necessary to aovid instrumenation, the
141ace9bad4SMark Rutland * raw_atomic*() operations should be used.
142ace9bad4SMark Rutland */
143ace9bad4SMark Rutland#ifndef _LINUX_ATOMIC_INSTRUMENTED_H
144ace9bad4SMark Rutland#define _LINUX_ATOMIC_INSTRUMENTED_H
145ace9bad4SMark Rutland
146ace9bad4SMark Rutland#include <linux/build_bug.h>
147e3d18ceeSMark Rutland#include <linux/compiler.h>
148e3d18ceeSMark Rutland#include <linux/instrumented.h>
149ace9bad4SMark Rutland
150ace9bad4SMark RutlandEOF
151c020395bSMarco Elver
152ed8af2e4SMarco Elvergrep '^[a-z]' "$1" | while read name meta args; do
153ace9bad4SMark Rutland	gen_proto "${meta}" "${name}" "atomic" "int" ${args}
154ace9bad4SMark Rutlanddone
155ace9bad4SMark Rutland
156ace9bad4SMark Rutlandgrep '^[a-z]' "$1" | while read name meta args; do
157ace9bad4SMark Rutland	gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
158ace9bad4SMark Rutlanddone
159ace9bad4SMark Rutland
160ace9bad4SMark Rutlandgrep '^[a-z]' "$1" | while read name meta args; do
161ace9bad4SMark Rutland	gen_proto "${meta}" "${name}" "atomic_long" "long" ${args}
162ace9bad4SMark Rutlanddone
163ace9bad4SMark Rutland
16467d1b0deSMark Rutland
16567d1b0deSMark Rutlandfor xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128" "try_cmpxchg" "try_cmpxchg64" "try_cmpxchg128"; do
16667d1b0deSMark Rutland	for order in "" "_acquire" "_release" "_relaxed"; do
16767d1b0deSMark Rutland		gen_xchg "${xchg}" "${order}"
16867d1b0deSMark Rutland		printf "\n"
1690aa7be05SUros Bizjak	done
170ace9bad4SMark Rutlanddone
171e87c4f66SMarco Elver
172bccf1ec3SMark Rutlandfor xchg in "cmpxchg_local" "cmpxchg64_local" "cmpxchg128_local" "sync_cmpxchg" "try_cmpxchg_local" "try_cmpxchg64_local" "try_cmpxchg128_local"; do
173ace9bad4SMark Rutland	gen_xchg "${xchg}" ""
174ace9bad4SMark Rutland	printf "\n"
175ace9bad4SMark Rutlanddone
176e6ce9d74SUros Bizjak
177e87c4f66SMarco Elvercat <<EOF
178ace9bad4SMark Rutland
179ace9bad4SMark Rutland#endif /* _LINUX_ATOMIC_INSTRUMENTED_H */
180ace9bad4SMark RutlandEOF
181e87c4f66SMarco Elver