xref: /OK3568_Linux_fs/kernel/scripts/atomic/gen-atomic-instrumented.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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