diff options
Diffstat (limited to 'scripts')
31 files changed, 1052 insertions, 5 deletions
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 25c259df8ffa..6deabedc67fc 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan | |||
| @@ -26,7 +26,7 @@ else | |||
| 26 | CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ | 26 | CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ |
| 27 | $(call cc-param,asan-globals=1) \ | 27 | $(call cc-param,asan-globals=1) \ |
| 28 | $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ | 28 | $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ |
| 29 | $(call cc-param,asan-stack=1) \ | 29 | $(call cc-param,asan-stack=$(CONFIG_KASAN_STACK)) \ |
| 30 | $(call cc-param,asan-use-after-scope=1) \ | 30 | $(call cc-param,asan-use-after-scope=1) \ |
| 31 | $(call cc-param,asan-instrument-allocas=1) | 31 | $(call cc-param,asan-instrument-allocas=1) |
| 32 | endif | 32 | endif |
diff --git a/scripts/atomic/atomic-tbl.sh b/scripts/atomic/atomic-tbl.sh new file mode 100755 index 000000000000..81d5c32039dd --- /dev/null +++ b/scripts/atomic/atomic-tbl.sh | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # helpers for dealing with atomics.tbl | ||
| 4 | |||
| 5 | #meta_in(meta, match) | ||
| 6 | meta_in() | ||
| 7 | { | ||
| 8 | case "$1" in | ||
| 9 | [$2]) return 0;; | ||
| 10 | esac | ||
| 11 | |||
| 12 | return 1 | ||
| 13 | } | ||
| 14 | |||
| 15 | #meta_has_ret(meta) | ||
| 16 | meta_has_ret() | ||
| 17 | { | ||
| 18 | meta_in "$1" "bBiIfFlR" | ||
| 19 | } | ||
| 20 | |||
| 21 | #meta_has_acquire(meta) | ||
| 22 | meta_has_acquire() | ||
| 23 | { | ||
| 24 | meta_in "$1" "BFIlR" | ||
| 25 | } | ||
| 26 | |||
| 27 | #meta_has_release(meta) | ||
| 28 | meta_has_release() | ||
| 29 | { | ||
| 30 | meta_in "$1" "BFIRs" | ||
| 31 | } | ||
| 32 | |||
| 33 | #meta_has_relaxed(meta) | ||
| 34 | meta_has_relaxed() | ||
| 35 | { | ||
| 36 | meta_in "$1" "BFIR" | ||
| 37 | } | ||
| 38 | |||
| 39 | #find_fallback_template(pfx, name, sfx, order) | ||
| 40 | find_fallback_template() | ||
| 41 | { | ||
| 42 | local pfx="$1"; shift | ||
| 43 | local name="$1"; shift | ||
| 44 | local sfx="$1"; shift | ||
| 45 | local order="$1"; shift | ||
| 46 | |||
| 47 | local base="" | ||
| 48 | local file="" | ||
| 49 | |||
| 50 | # We may have fallbacks for a specific case (e.g. read_acquire()), or | ||
| 51 | # an entire class, e.g. *inc*(). | ||
| 52 | # | ||
| 53 | # Start at the most specific, and fall back to the most general. Once | ||
| 54 | # we find a specific fallback, don't bother looking for more. | ||
| 55 | for base in "${pfx}${name}${sfx}${order}" "${name}"; do | ||
| 56 | file="${ATOMICDIR}/fallbacks/${base}" | ||
| 57 | |||
| 58 | if [ -f "${file}" ]; then | ||
| 59 | printf "${file}" | ||
| 60 | break | ||
| 61 | fi | ||
| 62 | done | ||
| 63 | } | ||
| 64 | |||
| 65 | #gen_ret_type(meta, int) | ||
| 66 | gen_ret_type() { | ||
| 67 | local meta="$1"; shift | ||
| 68 | local int="$1"; shift | ||
| 69 | |||
| 70 | case "${meta}" in | ||
| 71 | [sv]) printf "void";; | ||
| 72 | [bB]) printf "bool";; | ||
| 73 | [aiIfFlR]) printf "${int}";; | ||
| 74 | esac | ||
| 75 | } | ||
| 76 | |||
| 77 | #gen_ret_stmt(meta) | ||
| 78 | gen_ret_stmt() | ||
| 79 | { | ||
| 80 | if meta_has_ret "${meta}"; then | ||
| 81 | printf "return "; | ||
| 82 | fi | ||
| 83 | } | ||
| 84 | |||
| 85 | # gen_param_name(arg) | ||
| 86 | gen_param_name() | ||
| 87 | { | ||
| 88 | # strip off the leading 'c' for 'cv' | ||
| 89 | local name="${1#c}" | ||
| 90 | printf "${name#*:}" | ||
| 91 | } | ||
| 92 | |||
| 93 | # gen_param_type(arg, int, atomic) | ||
| 94 | gen_param_type() | ||
| 95 | { | ||
| 96 | local type="${1%%:*}"; shift | ||
| 97 | local int="$1"; shift | ||
| 98 | local atomic="$1"; shift | ||
| 99 | |||
| 100 | case "${type}" in | ||
| 101 | i) type="${int} ";; | ||
| 102 | p) type="${int} *";; | ||
| 103 | v) type="${atomic}_t *";; | ||
| 104 | cv) type="const ${atomic}_t *";; | ||
| 105 | esac | ||
| 106 | |||
| 107 | printf "${type}" | ||
| 108 | } | ||
| 109 | |||
| 110 | #gen_param(arg, int, atomic) | ||
| 111 | gen_param() | ||
| 112 | { | ||
| 113 | local arg="$1"; shift | ||
| 114 | local int="$1"; shift | ||
| 115 | local atomic="$1"; shift | ||
| 116 | local name="$(gen_param_name "${arg}")" | ||
| 117 | local type="$(gen_param_type "${arg}" "${int}" "${atomic}")" | ||
| 118 | |||
| 119 | printf "${type}${name}" | ||
| 120 | } | ||
| 121 | |||
| 122 | #gen_params(int, atomic, arg...) | ||
| 123 | gen_params() | ||
| 124 | { | ||
| 125 | local int="$1"; shift | ||
| 126 | local atomic="$1"; shift | ||
| 127 | |||
| 128 | while [ "$#" -gt 0 ]; do | ||
| 129 | gen_param "$1" "${int}" "${atomic}" | ||
| 130 | [ "$#" -gt 1 ] && printf ", " | ||
| 131 | shift; | ||
| 132 | done | ||
| 133 | } | ||
| 134 | |||
| 135 | #gen_args(arg...) | ||
| 136 | gen_args() | ||
| 137 | { | ||
| 138 | while [ "$#" -gt 0 ]; do | ||
| 139 | printf "$(gen_param_name "$1")" | ||
| 140 | [ "$#" -gt 1 ] && printf ", " | ||
| 141 | shift; | ||
| 142 | done | ||
| 143 | } | ||
| 144 | |||
| 145 | #gen_proto_order_variants(meta, pfx, name, sfx, ...) | ||
| 146 | gen_proto_order_variants() | ||
| 147 | { | ||
| 148 | local meta="$1"; shift | ||
| 149 | local pfx="$1"; shift | ||
| 150 | local name="$1"; shift | ||
| 151 | local sfx="$1"; shift | ||
| 152 | |||
| 153 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" | ||
| 154 | |||
| 155 | if meta_has_acquire "${meta}"; then | ||
| 156 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" | ||
| 157 | fi | ||
| 158 | if meta_has_release "${meta}"; then | ||
| 159 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" | ||
| 160 | fi | ||
| 161 | if meta_has_relaxed "${meta}"; then | ||
| 162 | gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" | ||
| 163 | fi | ||
| 164 | } | ||
| 165 | |||
| 166 | #gen_proto_variants(meta, name, ...) | ||
| 167 | gen_proto_variants() | ||
| 168 | { | ||
| 169 | local meta="$1"; shift | ||
| 170 | local name="$1"; shift | ||
| 171 | local pfx="" | ||
| 172 | local sfx="" | ||
| 173 | |||
| 174 | meta_in "${meta}" "fF" && pfx="fetch_" | ||
| 175 | meta_in "${meta}" "R" && sfx="_return" | ||
| 176 | |||
| 177 | gen_proto_order_variants "${meta}" "${pfx}" "${name}" "${sfx}" "$@" | ||
| 178 | } | ||
| 179 | |||
| 180 | #gen_proto(meta, ...) | ||
| 181 | gen_proto() { | ||
| 182 | local meta="$1"; shift | ||
| 183 | for m in $(echo "${meta}" | grep -o .); do | ||
| 184 | gen_proto_variants "${m}" "$@" | ||
| 185 | done | ||
| 186 | } | ||
diff --git a/scripts/atomic/atomics.tbl b/scripts/atomic/atomics.tbl new file mode 100755 index 000000000000..fbee2f6190d9 --- /dev/null +++ b/scripts/atomic/atomics.tbl | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | # name meta args... | ||
| 2 | # | ||
| 3 | # Where meta contains a string of variants to generate. | ||
| 4 | # Upper-case implies _{acquire,release,relaxed} variants. | ||
| 5 | # Valid meta values are: | ||
| 6 | # * B/b - bool: returns bool | ||
| 7 | # * v - void: returns void | ||
| 8 | # * I/i - int: returns base type | ||
| 9 | # * R - return: returns base type (has _return variants) | ||
| 10 | # * F/f - fetch: returns base type (has fetch_ variants) | ||
| 11 | # * l - load: returns base type (has _acquire order variant) | ||
| 12 | # * s - store: returns void (has _release order variant) | ||
| 13 | # | ||
| 14 | # Where args contains list of type[:name], where type is: | ||
| 15 | # * cv - const pointer to atomic base type (atomic_t/atomic64_t/atomic_long_t) | ||
| 16 | # * v - pointer to atomic base type (atomic_t/atomic64_t/atomic_long_t) | ||
| 17 | # * i - base type (int/s64/long) | ||
| 18 | # * p - pointer to base type (int/s64/long) | ||
| 19 | # | ||
| 20 | read l cv | ||
| 21 | set s v i | ||
| 22 | add vRF i v | ||
| 23 | sub vRF i v | ||
| 24 | inc vRF v | ||
| 25 | dec vRF v | ||
| 26 | and vF i v | ||
| 27 | andnot vF i v | ||
| 28 | or vF i v | ||
| 29 | xor vF i v | ||
| 30 | xchg I v i | ||
| 31 | cmpxchg I v i:old i:new | ||
| 32 | try_cmpxchg B v p:old i:new | ||
| 33 | sub_and_test b i v | ||
| 34 | dec_and_test b v | ||
| 35 | inc_and_test b v | ||
| 36 | add_negative b i v | ||
| 37 | add_unless fb v i:a i:u | ||
| 38 | inc_not_zero b v | ||
| 39 | inc_unless_negative b v | ||
| 40 | dec_unless_positive b v | ||
| 41 | dec_if_positive i v | ||
diff --git a/scripts/atomic/check-atomics.sh b/scripts/atomic/check-atomics.sh new file mode 100755 index 000000000000..cfa0c2f71c84 --- /dev/null +++ b/scripts/atomic/check-atomics.sh | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # | ||
| 4 | # Check if atomic headers are up-to-date | ||
| 5 | |||
| 6 | ATOMICDIR=$(dirname $0) | ||
| 7 | ATOMICTBL=${ATOMICDIR}/atomics.tbl | ||
| 8 | LINUXDIR=${ATOMICDIR}/../.. | ||
| 9 | |||
| 10 | echo '' | sha1sum - > /dev/null 2>&1 | ||
| 11 | if [ $? -ne 0 ]; then | ||
| 12 | printf "sha1sum not available, skipping atomic header checks.\n" | ||
| 13 | exit 0 | ||
| 14 | fi | ||
| 15 | |||
| 16 | cat <<EOF | | ||
| 17 | asm-generic/atomic-instrumented.h | ||
| 18 | asm-generic/atomic-long.h | ||
| 19 | linux/atomic-fallback.h | ||
| 20 | EOF | ||
| 21 | while read header; do | ||
| 22 | OLDSUM="$(tail -n 1 ${LINUXDIR}/include/${header})" | ||
| 23 | OLDSUM="${OLDSUM#// }" | ||
| 24 | |||
| 25 | NEWSUM="$(head -n -1 ${LINUXDIR}/include/${header} | sha1sum)" | ||
| 26 | NEWSUM="${NEWSUM%% *}" | ||
| 27 | |||
| 28 | if [ "${OLDSUM}" != "${NEWSUM}" ]; then | ||
| 29 | printf "warning: generated include/${header} has been modified.\n" | ||
| 30 | fi | ||
| 31 | done | ||
| 32 | |||
| 33 | exit 0 | ||
diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire new file mode 100755 index 000000000000..e38871e64db6 --- /dev/null +++ b/scripts/atomic/fallbacks/acquire | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}${name}${sfx}_acquire(${params}) | ||
| 4 | { | ||
| 5 | ${ret} ret = ${atomic}_${pfx}${name}${sfx}_relaxed(${args}); | ||
| 6 | __atomic_acquire_fence(); | ||
| 7 | return ret; | ||
| 8 | } | ||
| 9 | EOF | ||
diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative new file mode 100755 index 000000000000..e6f4815637de --- /dev/null +++ b/scripts/atomic/fallbacks/add_negative | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | cat <<EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_add_negative - add and test if negative | ||
| 4 | * @i: integer value to add | ||
| 5 | * @v: pointer of type ${atomic}_t | ||
| 6 | * | ||
| 7 | * Atomically adds @i to @v and returns true | ||
| 8 | * if the result is negative, or false when | ||
| 9 | * result is greater than or equal to zero. | ||
| 10 | */ | ||
| 11 | static inline bool | ||
| 12 | ${atomic}_add_negative(${int} i, ${atomic}_t *v) | ||
| 13 | { | ||
| 14 | return ${atomic}_add_return(i, v) < 0; | ||
| 15 | } | ||
| 16 | EOF | ||
diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless new file mode 100755 index 000000000000..792533885fbf --- /dev/null +++ b/scripts/atomic/fallbacks/add_unless | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | cat << EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_add_unless - add unless the number is already a given value | ||
| 4 | * @v: pointer of type ${atomic}_t | ||
| 5 | * @a: the amount to add to v... | ||
| 6 | * @u: ...unless v is equal to u. | ||
| 7 | * | ||
| 8 | * Atomically adds @a to @v, if @v was not already @u. | ||
| 9 | * Returns true if the addition was done. | ||
| 10 | */ | ||
| 11 | static inline bool | ||
| 12 | ${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u) | ||
| 13 | { | ||
| 14 | return ${atomic}_fetch_add_unless(v, a, u) != u; | ||
| 15 | } | ||
| 16 | EOF | ||
diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot new file mode 100755 index 000000000000..9f3a3216b5e3 --- /dev/null +++ b/scripts/atomic/fallbacks/andnot | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${retstmt}${atomic}_${pfx}and${sfx}${order}(~i, v); | ||
| 6 | } | ||
| 7 | EOF | ||
diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec new file mode 100755 index 000000000000..10bbc82be31d --- /dev/null +++ b/scripts/atomic/fallbacks/dec | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${retstmt}${atomic}_${pfx}sub${sfx}${order}(1, v); | ||
| 6 | } | ||
| 7 | EOF | ||
diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test new file mode 100755 index 000000000000..0ce7103b3df2 --- /dev/null +++ b/scripts/atomic/fallbacks/dec_and_test | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | cat <<EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_dec_and_test - decrement and test | ||
| 4 | * @v: pointer of type ${atomic}_t | ||
| 5 | * | ||
| 6 | * Atomically decrements @v by 1 and | ||
| 7 | * returns true if the result is 0, or false for all other | ||
| 8 | * cases. | ||
| 9 | */ | ||
| 10 | static inline bool | ||
| 11 | ${atomic}_dec_and_test(${atomic}_t *v) | ||
| 12 | { | ||
| 13 | return ${atomic}_dec_return(v) == 0; | ||
| 14 | } | ||
| 15 | EOF | ||
diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive new file mode 100755 index 000000000000..c52eacec43c8 --- /dev/null +++ b/scripts/atomic/fallbacks/dec_if_positive | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_dec_if_positive(${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${int} dec, c = ${atomic}_read(v); | ||
| 6 | |||
| 7 | do { | ||
| 8 | dec = c - 1; | ||
| 9 | if (unlikely(dec < 0)) | ||
| 10 | break; | ||
| 11 | } while (!${atomic}_try_cmpxchg(v, &c, dec)); | ||
| 12 | |||
| 13 | return dec; | ||
| 14 | } | ||
| 15 | EOF | ||
diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive new file mode 100755 index 000000000000..8a2578f14268 --- /dev/null +++ b/scripts/atomic/fallbacks/dec_unless_positive | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline bool | ||
| 3 | ${atomic}_dec_unless_positive(${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${int} c = ${atomic}_read(v); | ||
| 6 | |||
| 7 | do { | ||
| 8 | if (unlikely(c > 0)) | ||
| 9 | return false; | ||
| 10 | } while (!${atomic}_try_cmpxchg(v, &c, c - 1)); | ||
| 11 | |||
| 12 | return true; | ||
| 13 | } | ||
| 14 | EOF | ||
diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence new file mode 100755 index 000000000000..82f68fa6931a --- /dev/null +++ b/scripts/atomic/fallbacks/fence | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}${name}${sfx}(${params}) | ||
| 4 | { | ||
| 5 | ${ret} ret; | ||
| 6 | __atomic_pre_full_fence(); | ||
| 7 | ret = ${atomic}_${pfx}${name}${sfx}_relaxed(${args}); | ||
| 8 | __atomic_post_full_fence(); | ||
| 9 | return ret; | ||
| 10 | } | ||
| 11 | EOF | ||
diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless new file mode 100755 index 000000000000..d2c091db7eae --- /dev/null +++ b/scripts/atomic/fallbacks/fetch_add_unless | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | cat << EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_fetch_add_unless - add unless the number is already a given value | ||
| 4 | * @v: pointer of type ${atomic}_t | ||
| 5 | * @a: the amount to add to v... | ||
| 6 | * @u: ...unless v is equal to u. | ||
| 7 | * | ||
| 8 | * Atomically adds @a to @v, so long as @v was not already @u. | ||
| 9 | * Returns original value of @v | ||
| 10 | */ | ||
| 11 | static inline ${int} | ||
| 12 | ${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u) | ||
| 13 | { | ||
| 14 | ${int} c = ${atomic}_read(v); | ||
| 15 | |||
| 16 | do { | ||
| 17 | if (unlikely(c == u)) | ||
| 18 | break; | ||
| 19 | } while (!${atomic}_try_cmpxchg(v, &c, c + a)); | ||
| 20 | |||
| 21 | return c; | ||
| 22 | } | ||
| 23 | EOF | ||
diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc new file mode 100755 index 000000000000..f866b3ad2353 --- /dev/null +++ b/scripts/atomic/fallbacks/inc | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${retstmt}${atomic}_${pfx}add${sfx}${order}(1, v); | ||
| 6 | } | ||
| 7 | EOF | ||
diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test new file mode 100755 index 000000000000..4e2068869f7e --- /dev/null +++ b/scripts/atomic/fallbacks/inc_and_test | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | cat <<EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_inc_and_test - increment and test | ||
| 4 | * @v: pointer of type ${atomic}_t | ||
| 5 | * | ||
| 6 | * Atomically increments @v by 1 | ||
| 7 | * and returns true if the result is zero, or false for all | ||
| 8 | * other cases. | ||
| 9 | */ | ||
| 10 | static inline bool | ||
| 11 | ${atomic}_inc_and_test(${atomic}_t *v) | ||
| 12 | { | ||
| 13 | return ${atomic}_inc_return(v) == 0; | ||
| 14 | } | ||
| 15 | EOF | ||
diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero new file mode 100755 index 000000000000..a7c45c8d107c --- /dev/null +++ b/scripts/atomic/fallbacks/inc_not_zero | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | cat <<EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_inc_not_zero - increment unless the number is zero | ||
| 4 | * @v: pointer of type ${atomic}_t | ||
| 5 | * | ||
| 6 | * Atomically increments @v by 1, if @v is non-zero. | ||
| 7 | * Returns true if the increment was done. | ||
| 8 | */ | ||
| 9 | static inline bool | ||
| 10 | ${atomic}_inc_not_zero(${atomic}_t *v) | ||
| 11 | { | ||
| 12 | return ${atomic}_add_unless(v, 1, 0); | ||
| 13 | } | ||
| 14 | EOF | ||
diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative new file mode 100755 index 000000000000..0c266e71dbd4 --- /dev/null +++ b/scripts/atomic/fallbacks/inc_unless_negative | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline bool | ||
| 3 | ${atomic}_inc_unless_negative(${atomic}_t *v) | ||
| 4 | { | ||
| 5 | ${int} c = ${atomic}_read(v); | ||
| 6 | |||
| 7 | do { | ||
| 8 | if (unlikely(c < 0)) | ||
| 9 | return false; | ||
| 10 | } while (!${atomic}_try_cmpxchg(v, &c, c + 1)); | ||
| 11 | |||
| 12 | return true; | ||
| 13 | } | ||
| 14 | EOF | ||
diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire new file mode 100755 index 000000000000..75863b5203f7 --- /dev/null +++ b/scripts/atomic/fallbacks/read_acquire | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_read_acquire(const ${atomic}_t *v) | ||
| 4 | { | ||
| 5 | return smp_load_acquire(&(v)->counter); | ||
| 6 | } | ||
| 7 | EOF | ||
diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release new file mode 100755 index 000000000000..3f628a3802d9 --- /dev/null +++ b/scripts/atomic/fallbacks/release | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline ${ret} | ||
| 3 | ${atomic}_${pfx}${name}${sfx}_release(${params}) | ||
| 4 | { | ||
| 5 | __atomic_release_fence(); | ||
| 6 | ${retstmt}${atomic}_${pfx}${name}${sfx}_relaxed(${args}); | ||
| 7 | } | ||
| 8 | EOF | ||
diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release new file mode 100755 index 000000000000..45bb5e0cfc08 --- /dev/null +++ b/scripts/atomic/fallbacks/set_release | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline void | ||
| 3 | ${atomic}_set_release(${atomic}_t *v, ${int} i) | ||
| 4 | { | ||
| 5 | smp_store_release(&(v)->counter, i); | ||
| 6 | } | ||
| 7 | EOF | ||
diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test new file mode 100755 index 000000000000..289ef17a2d7a --- /dev/null +++ b/scripts/atomic/fallbacks/sub_and_test | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | cat <<EOF | ||
| 2 | /** | ||
| 3 | * ${atomic}_sub_and_test - subtract value from variable and test result | ||
| 4 | * @i: integer value to subtract | ||
| 5 | * @v: pointer of type ${atomic}_t | ||
| 6 | * | ||
| 7 | * Atomically subtracts @i from @v and returns | ||
| 8 | * true if the result is zero, or false for all | ||
| 9 | * other cases. | ||
| 10 | */ | ||
| 11 | static inline bool | ||
| 12 | ${atomic}_sub_and_test(${int} i, ${atomic}_t *v) | ||
| 13 | { | ||
| 14 | return ${atomic}_sub_return(i, v) == 0; | ||
| 15 | } | ||
| 16 | EOF | ||
diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg new file mode 100755 index 000000000000..4ed85e2f5378 --- /dev/null +++ b/scripts/atomic/fallbacks/try_cmpxchg | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | cat <<EOF | ||
| 2 | static inline bool | ||
| 3 | ${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new) | ||
| 4 | { | ||
| 5 | ${int} r, o = *old; | ||
| 6 | r = ${atomic}_cmpxchg${order}(v, o, new); | ||
| 7 | if (unlikely(r != o)) | ||
| 8 | *old = r; | ||
| 9 | return likely(r == o); | ||
| 10 | } | ||
| 11 | EOF | ||
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh new file mode 100755 index 000000000000..1bd7c1707633 --- /dev/null +++ b/scripts/atomic/gen-atomic-fallback.sh | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | |||
| 4 | ATOMICDIR=$(dirname $0) | ||
| 5 | |||
| 6 | . ${ATOMICDIR}/atomic-tbl.sh | ||
| 7 | |||
| 8 | #gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...) | ||
| 9 | gen_template_fallback() | ||
| 10 | { | ||
| 11 | local template="$1"; shift | ||
| 12 | local meta="$1"; shift | ||
| 13 | local pfx="$1"; shift | ||
| 14 | local name="$1"; shift | ||
| 15 | local sfx="$1"; shift | ||
| 16 | local order="$1"; shift | ||
| 17 | local atomic="$1"; shift | ||
| 18 | local int="$1"; shift | ||
| 19 | |||
| 20 | local atomicname="${atomic}_${pfx}${name}${sfx}${order}" | ||
| 21 | |||
| 22 | local ret="$(gen_ret_type "${meta}" "${int}")" | ||
| 23 | local retstmt="$(gen_ret_stmt "${meta}")" | ||
| 24 | local params="$(gen_params "${int}" "${atomic}" "$@")" | ||
| 25 | local args="$(gen_args "$@")" | ||
| 26 | |||
| 27 | if [ ! -z "${template}" ]; then | ||
| 28 | printf "#ifndef ${atomicname}\n" | ||
| 29 | . ${template} | ||
| 30 | printf "#define ${atomicname} ${atomicname}\n" | ||
| 31 | printf "#endif\n\n" | ||
| 32 | fi | ||
| 33 | } | ||
| 34 | |||
| 35 | #gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...) | ||
| 36 | gen_proto_fallback() | ||
| 37 | { | ||
| 38 | local meta="$1"; shift | ||
| 39 | local pfx="$1"; shift | ||
| 40 | local name="$1"; shift | ||
| 41 | local sfx="$1"; shift | ||
| 42 | local order="$1"; shift | ||
| 43 | |||
| 44 | local tmpl="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" | ||
| 45 | gen_template_fallback "${tmpl}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" | ||
| 46 | } | ||
| 47 | |||
| 48 | #gen_basic_fallbacks(basename) | ||
| 49 | gen_basic_fallbacks() | ||
| 50 | { | ||
| 51 | local basename="$1"; shift | ||
| 52 | cat << EOF | ||
| 53 | #define ${basename}_acquire ${basename} | ||
| 54 | #define ${basename}_release ${basename} | ||
| 55 | #define ${basename}_relaxed ${basename} | ||
| 56 | EOF | ||
| 57 | } | ||
| 58 | |||
| 59 | #gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...) | ||
| 60 | gen_proto_order_variants() | ||
| 61 | { | ||
| 62 | local meta="$1"; shift | ||
| 63 | local pfx="$1"; shift | ||
| 64 | local name="$1"; shift | ||
| 65 | local sfx="$1"; shift | ||
| 66 | local atomic="$1" | ||
| 67 | |||
| 68 | local basename="${atomic}_${pfx}${name}${sfx}" | ||
| 69 | |||
| 70 | local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" | ||
| 71 | |||
| 72 | # If we don't have relaxed atomics, then we don't bother with ordering fallbacks | ||
| 73 | # read_acquire and set_release need to be templated, though | ||
| 74 | if ! meta_has_relaxed "${meta}"; then | ||
| 75 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" | ||
| 76 | |||
| 77 | if meta_has_acquire "${meta}"; then | ||
| 78 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" | ||
| 79 | fi | ||
| 80 | |||
| 81 | if meta_has_release "${meta}"; then | ||
| 82 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" | ||
| 83 | fi | ||
| 84 | |||
| 85 | return | ||
| 86 | fi | ||
| 87 | |||
| 88 | printf "#ifndef ${basename}_relaxed\n" | ||
| 89 | |||
| 90 | if [ ! -z "${template}" ]; then | ||
| 91 | printf "#ifdef ${basename}\n" | ||
| 92 | fi | ||
| 93 | |||
| 94 | gen_basic_fallbacks "${basename}" | ||
| 95 | |||
| 96 | if [ ! -z "${template}" ]; then | ||
| 97 | printf "#endif /* ${atomic}_${pfx}${name}${sfx} */\n\n" | ||
| 98 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" | ||
| 99 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" | ||
| 100 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" | ||
| 101 | gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" | ||
| 102 | fi | ||
| 103 | |||
| 104 | printf "#else /* ${basename}_relaxed */\n\n" | ||
| 105 | |||
| 106 | gen_template_fallback "${ATOMICDIR}/fallbacks/acquire" "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" | ||
| 107 | gen_template_fallback "${ATOMICDIR}/fallbacks/release" "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" | ||
| 108 | gen_template_fallback "${ATOMICDIR}/fallbacks/fence" "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" | ||
| 109 | |||
| 110 | printf "#endif /* ${basename}_relaxed */\n\n" | ||
| 111 | } | ||
| 112 | |||
| 113 | gen_xchg_fallbacks() | ||
| 114 | { | ||
| 115 | local xchg="$1"; shift | ||
| 116 | cat <<EOF | ||
| 117 | #ifndef ${xchg}_relaxed | ||
| 118 | #define ${xchg}_relaxed ${xchg} | ||
| 119 | #define ${xchg}_acquire ${xchg} | ||
| 120 | #define ${xchg}_release ${xchg} | ||
| 121 | #else /* ${xchg}_relaxed */ | ||
| 122 | |||
| 123 | #ifndef ${xchg}_acquire | ||
| 124 | #define ${xchg}_acquire(...) \\ | ||
| 125 | __atomic_op_acquire(${xchg}, __VA_ARGS__) | ||
| 126 | #endif | ||
| 127 | |||
| 128 | #ifndef ${xchg}_release | ||
| 129 | #define ${xchg}_release(...) \\ | ||
| 130 | __atomic_op_release(${xchg}, __VA_ARGS__) | ||
| 131 | #endif | ||
| 132 | |||
| 133 | #ifndef ${xchg} | ||
| 134 | #define ${xchg}(...) \\ | ||
| 135 | __atomic_op_fence(${xchg}, __VA_ARGS__) | ||
| 136 | #endif | ||
| 137 | |||
| 138 | #endif /* ${xchg}_relaxed */ | ||
| 139 | |||
| 140 | EOF | ||
| 141 | } | ||
| 142 | |||
| 143 | cat << EOF | ||
| 144 | // SPDX-License-Identifier: GPL-2.0 | ||
| 145 | |||
| 146 | // Generated by $0 | ||
| 147 | // DO NOT MODIFY THIS FILE DIRECTLY | ||
| 148 | |||
| 149 | #ifndef _LINUX_ATOMIC_FALLBACK_H | ||
| 150 | #define _LINUX_ATOMIC_FALLBACK_H | ||
| 151 | |||
| 152 | EOF | ||
| 153 | |||
| 154 | for xchg in "xchg" "cmpxchg" "cmpxchg64"; do | ||
| 155 | gen_xchg_fallbacks "${xchg}" | ||
| 156 | done | ||
| 157 | |||
| 158 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 159 | gen_proto "${meta}" "${name}" "atomic" "int" ${args} | ||
| 160 | done | ||
| 161 | |||
| 162 | cat <<EOF | ||
| 163 | #define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) | ||
| 164 | #define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) | ||
| 165 | |||
| 166 | #ifdef CONFIG_GENERIC_ATOMIC64 | ||
| 167 | #include <asm-generic/atomic64.h> | ||
| 168 | #endif | ||
| 169 | |||
| 170 | EOF | ||
| 171 | |||
| 172 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 173 | gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} | ||
| 174 | done | ||
| 175 | |||
| 176 | cat <<EOF | ||
| 177 | #define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) | ||
| 178 | #define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) | ||
| 179 | |||
| 180 | #endif /* _LINUX_ATOMIC_FALLBACK_H */ | ||
| 181 | EOF | ||
diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh new file mode 100755 index 000000000000..e09812372b17 --- /dev/null +++ b/scripts/atomic/gen-atomic-instrumented.sh | |||
| @@ -0,0 +1,182 @@ | |||
| 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(arg) | ||
| 9 | gen_param_check() | ||
| 10 | { | ||
| 11 | local arg="$1"; shift | ||
| 12 | local type="${arg%%:*}" | ||
| 13 | local name="$(gen_param_name "${arg}")" | ||
| 14 | local rw="write" | ||
| 15 | |||
| 16 | case "${type#c}" in | ||
| 17 | i) return;; | ||
| 18 | esac | ||
| 19 | |||
| 20 | # We don't write to constant parameters | ||
| 21 | [ ${type#c} != ${type} ] && rw="read" | ||
| 22 | |||
| 23 | printf "\tkasan_check_${rw}(${name}, sizeof(*${name}));\n" | ||
| 24 | } | ||
| 25 | |||
| 26 | #gen_param_check(arg...) | ||
| 27 | gen_params_checks() | ||
| 28 | { | ||
| 29 | while [ "$#" -gt 0 ]; do | ||
| 30 | gen_param_check "$1" | ||
| 31 | shift; | ||
| 32 | done | ||
| 33 | } | ||
| 34 | |||
| 35 | # gen_guard(meta, atomic, pfx, name, sfx, order) | ||
| 36 | gen_guard() | ||
| 37 | { | ||
| 38 | local meta="$1"; shift | ||
| 39 | local atomic="$1"; shift | ||
| 40 | local pfx="$1"; shift | ||
| 41 | local name="$1"; shift | ||
| 42 | local sfx="$1"; shift | ||
| 43 | local order="$1"; shift | ||
| 44 | |||
| 45 | local atomicname="arch_${atomic}_${pfx}${name}${sfx}${order}" | ||
| 46 | |||
| 47 | local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")" | ||
| 48 | |||
| 49 | # We definitely need a preprocessor symbol for this atomic if it is an | ||
| 50 | # ordering variant, or if there's a generic fallback. | ||
| 51 | if [ ! -z "${order}" ] || [ ! -z "${template}" ]; then | ||
| 52 | printf "defined(${atomicname})" | ||
| 53 | return | ||
| 54 | fi | ||
| 55 | |||
| 56 | # If this is a base variant, but a relaxed variant *may* exist, then we | ||
| 57 | # only have a preprocessor symbol if the relaxed variant isn't defined | ||
| 58 | if meta_has_relaxed "${meta}"; then | ||
| 59 | printf "!defined(${atomicname}_relaxed) || defined(${atomicname})" | ||
| 60 | fi | ||
| 61 | } | ||
| 62 | |||
| 63 | #gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, arg...) | ||
| 64 | gen_proto_order_variant() | ||
| 65 | { | ||
| 66 | local meta="$1"; shift | ||
| 67 | local pfx="$1"; shift | ||
| 68 | local name="$1"; shift | ||
| 69 | local sfx="$1"; shift | ||
| 70 | local order="$1"; shift | ||
| 71 | local atomic="$1"; shift | ||
| 72 | local int="$1"; shift | ||
| 73 | |||
| 74 | local atomicname="${atomic}_${pfx}${name}${sfx}${order}" | ||
| 75 | |||
| 76 | local guard="$(gen_guard "${meta}" "${atomic}" "${pfx}" "${name}" "${sfx}" "${order}")" | ||
| 77 | |||
| 78 | local ret="$(gen_ret_type "${meta}" "${int}")" | ||
| 79 | local params="$(gen_params "${int}" "${atomic}" "$@")" | ||
| 80 | local checks="$(gen_params_checks "$@")" | ||
| 81 | local args="$(gen_args "$@")" | ||
| 82 | local retstmt="$(gen_ret_stmt "${meta}")" | ||
| 83 | |||
| 84 | [ ! -z "${guard}" ] && printf "#if ${guard}\n" | ||
| 85 | |||
| 86 | cat <<EOF | ||
| 87 | static inline ${ret} | ||
| 88 | ${atomicname}(${params}) | ||
| 89 | { | ||
| 90 | ${checks} | ||
| 91 | ${retstmt}arch_${atomicname}(${args}); | ||
| 92 | } | ||
| 93 | #define ${atomicname} ${atomicname} | ||
| 94 | EOF | ||
| 95 | |||
| 96 | [ ! -z "${guard}" ] && printf "#endif\n" | ||
| 97 | |||
| 98 | printf "\n" | ||
| 99 | } | ||
| 100 | |||
| 101 | gen_xchg() | ||
| 102 | { | ||
| 103 | local xchg="$1"; shift | ||
| 104 | local mult="$1"; shift | ||
| 105 | |||
| 106 | cat <<EOF | ||
| 107 | #define ${xchg}(ptr, ...) \\ | ||
| 108 | ({ \\ | ||
| 109 | typeof(ptr) __ai_ptr = (ptr); \\ | ||
| 110 | kasan_check_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\ | ||
| 111 | arch_${xchg}(__ai_ptr, __VA_ARGS__); \\ | ||
| 112 | }) | ||
| 113 | EOF | ||
| 114 | } | ||
| 115 | |||
| 116 | gen_optional_xchg() | ||
| 117 | { | ||
| 118 | local name="$1"; shift | ||
| 119 | local sfx="$1"; shift | ||
| 120 | local guard="defined(arch_${name}${sfx})" | ||
| 121 | |||
| 122 | [ -z "${sfx}" ] && guard="!defined(arch_${name}_relaxed) || defined(arch_${name})" | ||
| 123 | |||
| 124 | printf "#if ${guard}\n" | ||
| 125 | gen_xchg "${name}${sfx}" "" | ||
| 126 | printf "#endif\n\n" | ||
| 127 | } | ||
| 128 | |||
| 129 | cat << EOF | ||
| 130 | // SPDX-License-Identifier: GPL-2.0 | ||
| 131 | |||
| 132 | // Generated by $0 | ||
| 133 | // DO NOT MODIFY THIS FILE DIRECTLY | ||
| 134 | |||
| 135 | /* | ||
| 136 | * This file provides wrappers with KASAN instrumentation for atomic operations. | ||
| 137 | * To use this functionality an arch's atomic.h file needs to define all | ||
| 138 | * atomic operations with arch_ prefix (e.g. arch_atomic_read()) and include | ||
| 139 | * this file at the end. This file provides atomic_read() that forwards to | ||
| 140 | * arch_atomic_read() for actual atomic operation. | ||
| 141 | * Note: if an arch atomic operation is implemented by means of other atomic | ||
| 142 | * operations (e.g. atomic_read()/atomic_cmpxchg() loop), then it needs to use | ||
| 143 | * arch_ variants (i.e. arch_atomic_read()/arch_atomic_cmpxchg()) to avoid | ||
| 144 | * double instrumentation. | ||
| 145 | */ | ||
| 146 | #ifndef _ASM_GENERIC_ATOMIC_INSTRUMENTED_H | ||
| 147 | #define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H | ||
| 148 | |||
| 149 | #include <linux/build_bug.h> | ||
| 150 | #include <linux/kasan-checks.h> | ||
| 151 | |||
| 152 | EOF | ||
| 153 | |||
| 154 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 155 | gen_proto "${meta}" "${name}" "atomic" "int" ${args} | ||
| 156 | done | ||
| 157 | |||
| 158 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 159 | gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} | ||
| 160 | done | ||
| 161 | |||
| 162 | for xchg in "xchg" "cmpxchg" "cmpxchg64"; do | ||
| 163 | for order in "" "_acquire" "_release" "_relaxed"; do | ||
| 164 | gen_optional_xchg "${xchg}" "${order}" | ||
| 165 | done | ||
| 166 | done | ||
| 167 | |||
| 168 | for xchg in "cmpxchg_local" "cmpxchg64_local" "sync_cmpxchg"; do | ||
| 169 | gen_xchg "${xchg}" "" | ||
| 170 | printf "\n" | ||
| 171 | done | ||
| 172 | |||
| 173 | gen_xchg "cmpxchg_double" "2 * " | ||
| 174 | |||
| 175 | printf "\n\n" | ||
| 176 | |||
| 177 | gen_xchg "cmpxchg_double_local" "2 * " | ||
| 178 | |||
| 179 | cat <<EOF | ||
| 180 | |||
| 181 | #endif /* _ASM_GENERIC_ATOMIC_INSTRUMENTED_H */ | ||
| 182 | EOF | ||
diff --git a/scripts/atomic/gen-atomic-long.sh b/scripts/atomic/gen-atomic-long.sh new file mode 100755 index 000000000000..c240a7231b2e --- /dev/null +++ b/scripts/atomic/gen-atomic-long.sh | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | |||
| 4 | ATOMICDIR=$(dirname $0) | ||
| 5 | |||
| 6 | . ${ATOMICDIR}/atomic-tbl.sh | ||
| 7 | |||
| 8 | #gen_cast(arg, int, atomic) | ||
| 9 | gen_cast() | ||
| 10 | { | ||
| 11 | local arg="$1"; shift | ||
| 12 | local int="$1"; shift | ||
| 13 | local atomic="$1"; shift | ||
| 14 | |||
| 15 | [ "${arg%%:*}" = "p" ] || return | ||
| 16 | |||
| 17 | printf "($(gen_param_type "${arg}" "${int}" "${atomic}"))" | ||
| 18 | } | ||
| 19 | |||
| 20 | #gen_args_cast(int, atomic, arg...) | ||
| 21 | gen_args_cast() | ||
| 22 | { | ||
| 23 | local int="$1"; shift | ||
| 24 | local atomic="$1"; shift | ||
| 25 | |||
| 26 | while [ "$#" -gt 0 ]; do | ||
| 27 | local cast="$(gen_cast "$1" "${int}" "${atomic}")" | ||
| 28 | local arg="$(gen_param_name "$1")" | ||
| 29 | printf "${cast}${arg}" | ||
| 30 | [ "$#" -gt 1 ] && printf ", " | ||
| 31 | shift; | ||
| 32 | done | ||
| 33 | } | ||
| 34 | |||
| 35 | #gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, arg...) | ||
| 36 | gen_proto_order_variant() | ||
| 37 | { | ||
| 38 | local meta="$1"; shift | ||
| 39 | local name="$1$2$3$4"; shift; shift; shift; shift | ||
| 40 | local atomic="$1"; shift | ||
| 41 | local int="$1"; shift | ||
| 42 | |||
| 43 | local ret="$(gen_ret_type "${meta}" "long")" | ||
| 44 | local params="$(gen_params "long" "atomic_long" "$@")" | ||
| 45 | local argscast="$(gen_args_cast "${int}" "${atomic}" "$@")" | ||
| 46 | local retstmt="$(gen_ret_stmt "${meta}")" | ||
| 47 | |||
| 48 | cat <<EOF | ||
| 49 | static inline ${ret} | ||
| 50 | atomic_long_${name}(${params}) | ||
| 51 | { | ||
| 52 | ${retstmt}${atomic}_${name}(${argscast}); | ||
| 53 | } | ||
| 54 | |||
| 55 | EOF | ||
| 56 | } | ||
| 57 | |||
| 58 | cat << EOF | ||
| 59 | // SPDX-License-Identifier: GPL-2.0 | ||
| 60 | |||
| 61 | // Generated by $0 | ||
| 62 | // DO NOT MODIFY THIS FILE DIRECTLY | ||
| 63 | |||
| 64 | #ifndef _ASM_GENERIC_ATOMIC_LONG_H | ||
| 65 | #define _ASM_GENERIC_ATOMIC_LONG_H | ||
| 66 | |||
| 67 | #include <asm/types.h> | ||
| 68 | |||
| 69 | #ifdef CONFIG_64BIT | ||
| 70 | typedef atomic64_t atomic_long_t; | ||
| 71 | #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i) | ||
| 72 | #define atomic_long_cond_read_acquire atomic64_cond_read_acquire | ||
| 73 | #define atomic_long_cond_read_relaxed atomic64_cond_read_relaxed | ||
| 74 | #else | ||
| 75 | typedef atomic_t atomic_long_t; | ||
| 76 | #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i) | ||
| 77 | #define atomic_long_cond_read_acquire atomic_cond_read_acquire | ||
| 78 | #define atomic_long_cond_read_relaxed atomic_cond_read_relaxed | ||
| 79 | #endif | ||
| 80 | |||
| 81 | #ifdef CONFIG_64BIT | ||
| 82 | |||
| 83 | EOF | ||
| 84 | |||
| 85 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 86 | gen_proto "${meta}" "${name}" "atomic64" "s64" ${args} | ||
| 87 | done | ||
| 88 | |||
| 89 | cat <<EOF | ||
| 90 | #else /* CONFIG_64BIT */ | ||
| 91 | |||
| 92 | EOF | ||
| 93 | |||
| 94 | grep '^[a-z]' "$1" | while read name meta args; do | ||
| 95 | gen_proto "${meta}" "${name}" "atomic" "int" ${args} | ||
| 96 | done | ||
| 97 | |||
| 98 | cat <<EOF | ||
| 99 | #endif /* CONFIG_64BIT */ | ||
| 100 | #endif /* _ASM_GENERIC_ATOMIC_LONG_H */ | ||
| 101 | EOF | ||
diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh new file mode 100644 index 000000000000..27400b0cd732 --- /dev/null +++ b/scripts/atomic/gen-atomics.sh | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # | ||
| 4 | # Generate atomic headers | ||
| 5 | |||
| 6 | ATOMICDIR=$(dirname $0) | ||
| 7 | ATOMICTBL=${ATOMICDIR}/atomics.tbl | ||
| 8 | LINUXDIR=${ATOMICDIR}/../.. | ||
| 9 | |||
| 10 | cat <<EOF | | ||
| 11 | gen-atomic-instrumented.sh asm-generic/atomic-instrumented.h | ||
| 12 | gen-atomic-long.sh asm-generic/atomic-long.h | ||
| 13 | gen-atomic-fallback.sh linux/atomic-fallback.h | ||
| 14 | EOF | ||
| 15 | while read script header; do | ||
| 16 | ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header} | ||
| 17 | HASH="$(sha1sum ${LINUXDIR}/include/${header})" | ||
| 18 | HASH="${HASH%% *}" | ||
| 19 | printf "// %s\n" "${HASH}" >> ${LINUXDIR}/include/${header} | ||
| 20 | done | ||
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index cf931003395f..a18b47695f55 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh | |||
| @@ -30,12 +30,14 @@ cat << EOF | |||
| 30 | #define __IGNORE_readlink /* readlinkat */ | 30 | #define __IGNORE_readlink /* readlinkat */ |
| 31 | #define __IGNORE_symlink /* symlinkat */ | 31 | #define __IGNORE_symlink /* symlinkat */ |
| 32 | #define __IGNORE_utimes /* futimesat */ | 32 | #define __IGNORE_utimes /* futimesat */ |
| 33 | #if BITS_PER_LONG == 64 | ||
| 34 | #define __IGNORE_stat /* fstatat */ | 33 | #define __IGNORE_stat /* fstatat */ |
| 35 | #define __IGNORE_lstat /* fstatat */ | 34 | #define __IGNORE_lstat /* fstatat */ |
| 36 | #else | ||
| 37 | #define __IGNORE_stat64 /* fstatat64 */ | 35 | #define __IGNORE_stat64 /* fstatat64 */ |
| 38 | #define __IGNORE_lstat64 /* fstatat64 */ | 36 | #define __IGNORE_lstat64 /* fstatat64 */ |
| 37 | |||
| 38 | #ifndef __ARCH_WANT_SET_GET_RLIMIT | ||
| 39 | #define __IGNORE_getrlimit /* getrlimit */ | ||
| 40 | #define __IGNORE_setrlimit /* setrlimit */ | ||
| 39 | #endif | 41 | #endif |
| 40 | 42 | ||
| 41 | /* Missing flags argument */ | 43 | /* Missing flags argument */ |
| @@ -84,6 +86,26 @@ cat << EOF | |||
| 84 | #define __IGNORE_statfs64 | 86 | #define __IGNORE_statfs64 |
| 85 | #define __IGNORE_llseek | 87 | #define __IGNORE_llseek |
| 86 | #define __IGNORE_mmap2 | 88 | #define __IGNORE_mmap2 |
| 89 | #define __IGNORE_clock_gettime64 | ||
| 90 | #define __IGNORE_clock_settime64 | ||
| 91 | #define __IGNORE_clock_adjtime64 | ||
| 92 | #define __IGNORE_clock_getres_time64 | ||
| 93 | #define __IGNORE_clock_nanosleep_time64 | ||
| 94 | #define __IGNORE_timer_gettime64 | ||
| 95 | #define __IGNORE_timer_settime64 | ||
| 96 | #define __IGNORE_timerfd_gettime64 | ||
| 97 | #define __IGNORE_timerfd_settime64 | ||
| 98 | #define __IGNORE_utimensat_time64 | ||
| 99 | #define __IGNORE_pselect6_time64 | ||
| 100 | #define __IGNORE_ppoll_time64 | ||
| 101 | #define __IGNORE_io_pgetevents_time64 | ||
| 102 | #define __IGNORE_recvmmsg_time64 | ||
| 103 | #define __IGNORE_mq_timedsend_time64 | ||
| 104 | #define __IGNORE_mq_timedreceive_time64 | ||
| 105 | #define __IGNORE_semtimedop_time64 | ||
| 106 | #define __IGNORE_rt_sigtimedwait_time64 | ||
| 107 | #define __IGNORE_futex_time64 | ||
| 108 | #define __IGNORE_sched_rr_get_interval_time64 | ||
| 87 | #else | 109 | #else |
| 88 | #define __IGNORE_sendfile | 110 | #define __IGNORE_sendfile |
| 89 | #define __IGNORE_ftruncate | 111 | #define __IGNORE_ftruncate |
| @@ -98,6 +120,33 @@ cat << EOF | |||
| 98 | #define __IGNORE_statfs | 120 | #define __IGNORE_statfs |
| 99 | #define __IGNORE_lseek | 121 | #define __IGNORE_lseek |
| 100 | #define __IGNORE_mmap | 122 | #define __IGNORE_mmap |
| 123 | #define __IGNORE_clock_gettime | ||
| 124 | #define __IGNORE_clock_settime | ||
| 125 | #define __IGNORE_clock_adjtime | ||
| 126 | #define __IGNORE_clock_getres | ||
| 127 | #define __IGNORE_clock_nanosleep | ||
| 128 | #define __IGNORE_timer_gettime | ||
| 129 | #define __IGNORE_timer_settime | ||
| 130 | #define __IGNORE_timerfd_gettime | ||
| 131 | #define __IGNORE_timerfd_settime | ||
| 132 | #define __IGNORE_utimensat | ||
| 133 | #define __IGNORE_pselect6 | ||
| 134 | #define __IGNORE_ppoll | ||
| 135 | #define __IGNORE_io_pgetevents | ||
| 136 | #define __IGNORE_recvmmsg | ||
| 137 | #define __IGNORE_mq_timedsend | ||
| 138 | #define __IGNORE_mq_timedreceive | ||
| 139 | #define __IGNORE_semtimedop | ||
| 140 | #define __IGNORE_rt_sigtimedwait | ||
| 141 | #define __IGNORE_futex | ||
| 142 | #define __IGNORE_sched_rr_get_interval | ||
| 143 | #define __IGNORE_gettimeofday | ||
| 144 | #define __IGNORE_settimeofday | ||
| 145 | #define __IGNORE_wait4 | ||
| 146 | #define __IGNORE_adjtimex | ||
| 147 | #define __IGNORE_nanosleep | ||
| 148 | #define __IGNORE_io_getevents | ||
| 149 | #define __IGNORE_recvmmsg | ||
| 101 | #endif | 150 | #endif |
| 102 | 151 | ||
| 103 | /* i386-specific or historical system calls */ | 152 | /* i386-specific or historical system calls */ |
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 77cebad0474e..f75e7bda4889 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
| @@ -118,8 +118,8 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
| 118 | fprintf(stderr, "Read error or end of file.\n"); | 118 | fprintf(stderr, "Read error or end of file.\n"); |
| 119 | return -1; | 119 | return -1; |
| 120 | } | 120 | } |
| 121 | if (strlen(sym) > KSYM_NAME_LEN) { | 121 | if (strlen(sym) >= KSYM_NAME_LEN) { |
| 122 | fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n" | 122 | fprintf(stderr, "Symbol %s too long for kallsyms (%zu >= %d).\n" |
| 123 | "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n", | 123 | "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n", |
| 124 | sym, strlen(sym), KSYM_NAME_LEN); | 124 | sym, strlen(sym), KSYM_NAME_LEN); |
| 125 | return -1; | 125 | return -1; |
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 293004499b4d..160718383a71 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c | |||
| @@ -225,5 +225,8 @@ int main(void) | |||
| 225 | DEVID_FIELD(typec_device_id, svid); | 225 | DEVID_FIELD(typec_device_id, svid); |
| 226 | DEVID_FIELD(typec_device_id, mode); | 226 | DEVID_FIELD(typec_device_id, mode); |
| 227 | 227 | ||
| 228 | DEVID(tee_client_device_id); | ||
| 229 | DEVID_FIELD(tee_client_device_id, uuid); | ||
| 230 | |||
| 228 | return 0; | 231 | return 0; |
| 229 | } | 232 | } |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index a37af7d71973..d0e41723627f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -37,6 +37,9 @@ typedef unsigned char __u8; | |||
| 37 | typedef struct { | 37 | typedef struct { |
| 38 | __u8 b[16]; | 38 | __u8 b[16]; |
| 39 | } uuid_le; | 39 | } uuid_le; |
| 40 | typedef struct { | ||
| 41 | __u8 b[16]; | ||
| 42 | } uuid_t; | ||
| 40 | 43 | ||
| 41 | /* Big exception to the "don't include kernel headers into userspace, which | 44 | /* Big exception to the "don't include kernel headers into userspace, which |
| 42 | * even potentially has different endianness and word sizes, since | 45 | * even potentially has different endianness and word sizes, since |
| @@ -1287,6 +1290,21 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) | |||
| 1287 | return 1; | 1290 | return 1; |
| 1288 | } | 1291 | } |
| 1289 | 1292 | ||
| 1293 | /* Looks like: tee:uuid */ | ||
| 1294 | static int do_tee_entry(const char *filename, void *symval, char *alias) | ||
| 1295 | { | ||
| 1296 | DEF_FIELD(symval, tee_client_device_id, uuid); | ||
| 1297 | |||
| 1298 | sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", | ||
| 1299 | uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4], | ||
| 1300 | uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9], | ||
| 1301 | uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14], | ||
| 1302 | uuid.b[15]); | ||
| 1303 | |||
| 1304 | add_wildcard(alias); | ||
| 1305 | return 1; | ||
| 1306 | } | ||
| 1307 | |||
| 1290 | /* Does namelen bytes of name exactly match the symbol? */ | 1308 | /* Does namelen bytes of name exactly match the symbol? */ |
| 1291 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) | 1309 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) |
| 1292 | { | 1310 | { |
| @@ -1357,6 +1375,7 @@ static const struct devtable devtable[] = { | |||
| 1357 | {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, | 1375 | {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, |
| 1358 | {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, | 1376 | {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, |
| 1359 | {"typec", SIZE_typec_device_id, do_typec_entry}, | 1377 | {"typec", SIZE_typec_device_id, do_typec_entry}, |
| 1378 | {"tee", SIZE_tee_client_device_id, do_tee_entry}, | ||
| 1360 | }; | 1379 | }; |
| 1361 | 1380 | ||
| 1362 | /* Create MODULE_ALIAS() statements. | 1381 | /* Create MODULE_ALIAS() statements. |
