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