Skip to content

Commit d806c57

Browse files
vladimirolteankuba-moo
authored andcommitted
tests: dtbs_check: new test
The idea is that subsystems (i.e. netdev) apply dt-binding patches, but those can introduce warnings in existing device trees. So we need a check. The trouble is that NIPA builds only for the host architecture (x86_64) whereas device trees are for lots of other architectures. The kernel build technically requires a cross-compilation toolchain, but "make dtbs" technically doesn't cross-compile anything. We just need the C preprocessor (gcc -E). This is a bit of a hack, but to get each and every architecture to compile, we use exclusively the host gcc and set up arch-specific 'shims' for it (which disregard options that the host gcc doesn't understand). Signed-off-by: Vladimir Oltean <[email protected]>
1 parent 36ac2d9 commit d806c57

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
# Copyright 2025-2026 NXP
4+
5+
HEAD=$(git rev-parse HEAD)
6+
nproc=$(grep -c processor /proc/cpuinfo)
7+
build_flags="-j $nproc"
8+
rc=0
9+
10+
architectures=(
11+
"arc" \
12+
"arm" \
13+
"arm64" \
14+
"csky" \
15+
"loongarch" \
16+
"microblaze" \
17+
"mips" \
18+
"nios2" \
19+
"openrisc" \
20+
"powerpc" \
21+
"riscv" \
22+
"sh" \
23+
"xtensa" \
24+
)
25+
26+
pr() {
27+
echo " ====== $* ======" | tee -a /dev/stderr
28+
}
29+
30+
# "make dtbs" will fail on many archs during the syncconfig stage, where it
31+
# tries to probe the cross-compiler version. We don't actually need any
32+
# cross-compilation feature, the host gcc could in principle handle everything
33+
# as long as we filter out arch-specific flags.
34+
setup_shims() {
35+
local shims_dir="$1"
36+
37+
mkdir -p "$shims_dir"
38+
39+
cat > "$shims_dir/gcc" << 'EOF'
40+
#!/bin/bash
41+
args=()
42+
skip_next=false
43+
for arg in "$@"; do
44+
if [[ "$skip_next" == "true" ]]; then
45+
skip_next=false
46+
continue
47+
fi
48+
case "$arg" in
49+
-mdiv|-mno-stack-size|-mhard-float|-msoft-float|-mcpu=*|-march=*|-mtune=*|\
50+
-mmedium-calls|-mlock|-mswape|-munaligned-access|-mno-sdata|-mbig-endian|\
51+
-mabi=*|-mcmodel=*|-G|-mno-abicalls|-EB|0)
52+
;;
53+
*)
54+
args+=("$arg")
55+
;;
56+
esac
57+
done
58+
exec /usr/bin/gcc "${args[@]}"
59+
EOF
60+
61+
chmod +x "$shims_dir/gcc"
62+
63+
# Special case for xtensa
64+
ln -s $(which gcc) "$shims_dir/xtensa_fsf-gcc"
65+
ln -s "$(which ld)" "$shims_dir/xtensa_fsf-ld"
66+
}
67+
68+
prep_config() {
69+
local arch=$1
70+
local output_dir=$2
71+
local shims_dir=$3
72+
PATH="$shims_dir:$PATH" make ARCH=$arch O=$output_dir allmodconfig $build_flags
73+
}
74+
75+
build() {
76+
local arch=$1
77+
local output_dir=$2
78+
local shims_dir=$3
79+
PATH="$shims_dir:$PATH" make -s ARCH=$arch O=$output_dir $build_flags DT_CHECKER_FLAGS=-m CHECK_DT_BINDING=y dtbs 2>&1
80+
}
81+
82+
clean_build() {
83+
local output_dir=$1
84+
rm -rf "$output_dir"
85+
}
86+
87+
schema_modified=false
88+
if git show --diff-filter=AM --pretty="" --name-only "${HEAD}" | \
89+
grep -q -E "^Documentation/devicetree/bindings/"
90+
then
91+
schema_modified=true
92+
fi
93+
94+
touched_archs=()
95+
for arch in "${architectures[@]}"; do
96+
if git show --diff-filter=AM --pretty="" --name-only "${HEAD}" | \
97+
grep -q -E "^arch/${arch}/boot/dts/"
98+
then
99+
touched_archs+=("$arch")
100+
fi
101+
done
102+
103+
test_archs=()
104+
if [ "$schema_modified" = true ]; then
105+
test_archs=("${architectures[@]}")
106+
echo "DT schema files modified, testing all architectures" >&"$DESC_FD"
107+
elif [ ${#touched_archs[@]} -gt 0 ]; then
108+
test_archs=("${touched_archs[@]}")
109+
echo "DTS files touched for architectures: ${test_archs[*]}" >&"$DESC_FD"
110+
else
111+
echo "No DT schema or DTS files touched, skip" >&"$DESC_FD"
112+
exit 0
113+
fi
114+
115+
echo "Tree base:"
116+
git log -1 --pretty='%h ("%s")' HEAD~
117+
echo "Now at:"
118+
git log -1 --pretty='%h ("%s")' HEAD
119+
120+
# Set up compiler shims
121+
shims_dir="$PWD/shims"
122+
setup_shims "$shims_dir"
123+
124+
for arch in "${test_archs[@]}"; do
125+
output_dir="build_dtbs_check_${arch}/"
126+
127+
tmpfile_o_raw=$(mktemp)
128+
tmpfile_n_raw=$(mktemp)
129+
tmp_new_issues=$(mktemp)
130+
131+
pr "Checking $arch before the patch"
132+
git checkout -q HEAD~
133+
134+
# Prepare config and run the check on the parent commit
135+
clean_build "$output_dir"
136+
prep_config "$arch" "$output_dir" "$shims_dir"
137+
(build "$arch" "$output_dir" "$shims_dir" | tee -a "$tmpfile_o_raw") || true
138+
139+
# Sort the output
140+
sort "$tmpfile_o_raw" > "${tmpfile_o_raw}.sorted"
141+
mv "${tmpfile_o_raw}.sorted" "$tmpfile_o_raw"
142+
incumbent_total=$(wc -l < "$tmpfile_o_raw")
143+
144+
pr "Checking $arch with the patch"
145+
git checkout -q "$HEAD"
146+
147+
# Prepare config and run the check on the new commit
148+
clean_build "$output_dir"
149+
prep_config "$arch" "$output_dir" "$shims_dir"
150+
(build "$arch" "$output_dir" "$shims_dir" | tee -a "$tmpfile_n_raw") || true
151+
152+
# Sort the output
153+
sort "$tmpfile_n_raw" > "${tmpfile_n_raw}.sorted"
154+
mv "${tmpfile_n_raw}.sorted" "$tmpfile_n_raw"
155+
current_total=$(wc -l < "$tmpfile_n_raw")
156+
157+
# Compare the lists to find new and fixed issues
158+
# Use comm to find fixed issues (lines only in the old log, column 1).
159+
fixed_issues_count=$(comm -23 "$tmpfile_o_raw" "$tmpfile_n_raw" | wc -l)
160+
161+
# Use comm to find new issues (lines only in the new log, column 2)
162+
# and save them for later display.
163+
comm -13 "$tmpfile_o_raw" "$tmpfile_n_raw" > "$tmp_new_issues"
164+
new_issues_count=$(wc -l < "$tmp_new_issues")
165+
166+
echo "[$arch] Issues before: $incumbent_total, after: $current_total" \
167+
"(Fixed: $fixed_issues_count, New: $new_issues_count)" >&"$DESC_FD"
168+
169+
if [ "$new_issues_count" -gt 0 ]; then
170+
echo "[$arch] New issues added:" 1>&2
171+
# Print the new issues we saved
172+
cat "$tmp_new_issues" 1>&2
173+
rc=1
174+
elif [ "$fixed_issues_count" -gt 0 ]; then
175+
echo "[$arch] Patch fixed $fixed_issues_count issue(s)." >&2
176+
# No new issues, and some were fixed. This is a success.
177+
fi
178+
179+
rm "$tmpfile_o_raw" "$tmpfile_n_raw" "$tmp_new_issues"
180+
done
181+
182+
# Clean up shims directory
183+
rm -rf "$shims_dir"
184+
185+
exit $rc

tests/patch/dtbs_check/info.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"run": ["dtbs_check.sh"]
3+
}

0 commit comments

Comments
 (0)