1507806e9SBenjamin Tissoires#!/bin/bash 2507806e9SBenjamin Tissoires# SPDX-License-Identifier: GPL-2.0 3507806e9SBenjamin Tissoires 4507806e9SBenjamin Tissoiresset -u 5507806e9SBenjamin Tissoiresset -e 6507806e9SBenjamin Tissoires 7507806e9SBenjamin Tissoires# This script currently only works for x86_64 8507806e9SBenjamin TissoiresARCH="$(uname -m)" 9507806e9SBenjamin Tissoirescase "${ARCH}" in 10507806e9SBenjamin Tissoiresx86_64) 11507806e9SBenjamin Tissoires QEMU_BINARY=qemu-system-x86_64 12507806e9SBenjamin Tissoires BZIMAGE="arch/x86/boot/bzImage" 13507806e9SBenjamin Tissoires ;; 14507806e9SBenjamin Tissoires*) 15507806e9SBenjamin Tissoires echo "Unsupported architecture" 16507806e9SBenjamin Tissoires exit 1 17507806e9SBenjamin Tissoires ;; 18507806e9SBenjamin Tissoiresesac 19507806e9SBenjamin TissoiresSCRIPT_DIR="$(dirname $(realpath $0))" 20507806e9SBenjamin TissoiresOUTPUT_DIR="$SCRIPT_DIR/results" 21507806e9SBenjamin TissoiresKCONFIG_REL_PATHS=("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" "${SCRIPT_DIR}/config.${ARCH}") 22507806e9SBenjamin TissoiresB2C_URL="https://gitlab.freedesktop.org/mupuf/boot2container/-/raw/master/vm2c.py" 23507806e9SBenjamin TissoiresNUM_COMPILE_JOBS="$(nproc)" 24507806e9SBenjamin TissoiresLOG_FILE_BASE="$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")" 25507806e9SBenjamin TissoiresLOG_FILE="${LOG_FILE_BASE}.log" 26507806e9SBenjamin TissoiresEXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status" 277d0b3f10SBenjamin TissoiresCONTAINER_IMAGE="registry.freedesktop.org/libevdev/hid-tools/fedora/37:2023-02-17.1" 287d0b3f10SBenjamin Tissoires 297d0b3f10SBenjamin TissoiresTARGETS="${TARGETS:=$(basename ${SCRIPT_DIR})}" 30ffb85d5cSBenjamin TissoiresDEFAULT_COMMAND="pip3 install hid-tools; make -C tools/testing/selftests TARGETS=${TARGETS} run_tests" 31507806e9SBenjamin Tissoires 32507806e9SBenjamin Tissoiresusage() 33507806e9SBenjamin Tissoires{ 34507806e9SBenjamin Tissoires cat <<EOF 35507806e9SBenjamin TissoiresUsage: $0 [-i] [-s] [-d <output_dir>] -- [<command>] 36507806e9SBenjamin Tissoires 37507806e9SBenjamin Tissoires<command> is the command you would normally run when you are in 387d0b3f10SBenjamin Tissoiresthe source kernel direcory. e.g: 39507806e9SBenjamin Tissoires 407d0b3f10SBenjamin Tissoires $0 -- ./tools/testing/selftests/hid/hid_bpf 41507806e9SBenjamin Tissoires 42507806e9SBenjamin TissoiresIf no command is specified and a debug shell (-s) is not requested, 43507806e9SBenjamin Tissoires"${DEFAULT_COMMAND}" will be run by default. 44507806e9SBenjamin Tissoires 45507806e9SBenjamin TissoiresIf you build your kernel using KBUILD_OUTPUT= or O= options, these 46507806e9SBenjamin Tissoirescan be passed as environment variables to the script: 47507806e9SBenjamin Tissoires 487d0b3f10SBenjamin Tissoires O=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf 49507806e9SBenjamin Tissoires 50507806e9SBenjamin Tissoiresor 51507806e9SBenjamin Tissoires 527d0b3f10SBenjamin Tissoires KBUILD_OUTPUT=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf 53507806e9SBenjamin Tissoires 54507806e9SBenjamin TissoiresOptions: 55507806e9SBenjamin Tissoires 56507806e9SBenjamin Tissoires -u) Update the boot2container script to a newer version. 57507806e9SBenjamin Tissoires -d) Update the output directory (default: ${OUTPUT_DIR}) 58507806e9SBenjamin Tissoires -j) Number of jobs for compilation, similar to -j in make 59507806e9SBenjamin Tissoires (default: ${NUM_COMPILE_JOBS}) 60507806e9SBenjamin Tissoires -s) Instead of powering off the VM, start an interactive 61507806e9SBenjamin Tissoires shell. If <command> is specified, the shell runs after 62507806e9SBenjamin Tissoires the command finishes executing 63507806e9SBenjamin TissoiresEOF 64507806e9SBenjamin Tissoires} 65507806e9SBenjamin Tissoires 66507806e9SBenjamin Tissoiresdownload() 67507806e9SBenjamin Tissoires{ 68507806e9SBenjamin Tissoires local file="$1" 69507806e9SBenjamin Tissoires 70507806e9SBenjamin Tissoires echo "Downloading $file..." >&2 71507806e9SBenjamin Tissoires curl -Lsf "$file" -o "${@:2}" 72507806e9SBenjamin Tissoires} 73507806e9SBenjamin Tissoires 74507806e9SBenjamin Tissoiresrecompile_kernel() 75507806e9SBenjamin Tissoires{ 76507806e9SBenjamin Tissoires local kernel_checkout="$1" 77507806e9SBenjamin Tissoires local make_command="$2" 78507806e9SBenjamin Tissoires 79507806e9SBenjamin Tissoires cd "${kernel_checkout}" 80507806e9SBenjamin Tissoires 81507806e9SBenjamin Tissoires ${make_command} olddefconfig 82*f9abdcc6SBenjamin Tissoires ${make_command} headers 83507806e9SBenjamin Tissoires ${make_command} 84507806e9SBenjamin Tissoires} 85507806e9SBenjamin Tissoires 86507806e9SBenjamin Tissoiresupdate_selftests() 87507806e9SBenjamin Tissoires{ 88507806e9SBenjamin Tissoires local kernel_checkout="$1" 89507806e9SBenjamin Tissoires local selftests_dir="${kernel_checkout}/tools/testing/selftests/hid" 90507806e9SBenjamin Tissoires 91507806e9SBenjamin Tissoires cd "${selftests_dir}" 92507806e9SBenjamin Tissoires ${make_command} 93507806e9SBenjamin Tissoires} 94507806e9SBenjamin Tissoires 95507806e9SBenjamin Tissoiresrun_vm() 96507806e9SBenjamin Tissoires{ 977d0b3f10SBenjamin Tissoires local run_dir="$1" 987d0b3f10SBenjamin Tissoires local b2c="$2" 997d0b3f10SBenjamin Tissoires local kernel_bzimage="$3" 1007d0b3f10SBenjamin Tissoires local command="$4" 101507806e9SBenjamin Tissoires local post_command="" 102507806e9SBenjamin Tissoires 1037d0b3f10SBenjamin Tissoires cd "${run_dir}" 1047d0b3f10SBenjamin Tissoires 105507806e9SBenjamin Tissoires if ! which "${QEMU_BINARY}" &> /dev/null; then 106507806e9SBenjamin Tissoires cat <<EOF 107507806e9SBenjamin TissoiresCould not find ${QEMU_BINARY} 108507806e9SBenjamin TissoiresPlease install qemu or set the QEMU_BINARY environment variable. 109507806e9SBenjamin TissoiresEOF 110507806e9SBenjamin Tissoires exit 1 111507806e9SBenjamin Tissoires fi 112507806e9SBenjamin Tissoires 113507806e9SBenjamin Tissoires # alpine (used in post-container requires the PATH to have /bin 114507806e9SBenjamin Tissoires export PATH=$PATH:/bin 115507806e9SBenjamin Tissoires 116507806e9SBenjamin Tissoires if [[ "${debug_shell}" != "yes" ]] 117507806e9SBenjamin Tissoires then 118507806e9SBenjamin Tissoires touch ${OUTPUT_DIR}/${LOG_FILE} 119507806e9SBenjamin Tissoires command="mount bpffs -t bpf /sys/fs/bpf/; set -o pipefail ; ${command} 2>&1 | tee ${OUTPUT_DIR}/${LOG_FILE}" 120507806e9SBenjamin Tissoires post_command="cat ${OUTPUT_DIR}/${LOG_FILE}" 121507806e9SBenjamin Tissoires else 122507806e9SBenjamin Tissoires command="mount bpffs -t bpf /sys/fs/bpf/; ${command}" 123507806e9SBenjamin Tissoires fi 124507806e9SBenjamin Tissoires 125507806e9SBenjamin Tissoires set +e 126507806e9SBenjamin Tissoires $b2c --command "${command}" \ 127507806e9SBenjamin Tissoires --kernel ${kernel_bzimage} \ 128507806e9SBenjamin Tissoires --workdir ${OUTPUT_DIR} \ 129507806e9SBenjamin Tissoires --image ${CONTAINER_IMAGE} 130507806e9SBenjamin Tissoires 131507806e9SBenjamin Tissoires echo $? > ${OUTPUT_DIR}/${EXIT_STATUS_FILE} 132507806e9SBenjamin Tissoires 133507806e9SBenjamin Tissoires set -e 134507806e9SBenjamin Tissoires 135507806e9SBenjamin Tissoires ${post_command} 136507806e9SBenjamin Tissoires} 137507806e9SBenjamin Tissoires 138507806e9SBenjamin Tissoiresis_rel_path() 139507806e9SBenjamin Tissoires{ 140507806e9SBenjamin Tissoires local path="$1" 141507806e9SBenjamin Tissoires 142507806e9SBenjamin Tissoires [[ ${path:0:1} != "/" ]] 143507806e9SBenjamin Tissoires} 144507806e9SBenjamin Tissoires 145507806e9SBenjamin Tissoiresdo_update_kconfig() 146507806e9SBenjamin Tissoires{ 147507806e9SBenjamin Tissoires local kernel_checkout="$1" 148507806e9SBenjamin Tissoires local kconfig_file="$2" 149507806e9SBenjamin Tissoires 150507806e9SBenjamin Tissoires rm -f "$kconfig_file" 2> /dev/null 151507806e9SBenjamin Tissoires 152507806e9SBenjamin Tissoires for config in "${KCONFIG_REL_PATHS[@]}"; do 153507806e9SBenjamin Tissoires local kconfig_src="${config}" 154507806e9SBenjamin Tissoires cat "$kconfig_src" >> "$kconfig_file" 155507806e9SBenjamin Tissoires done 156507806e9SBenjamin Tissoires} 157507806e9SBenjamin Tissoires 158507806e9SBenjamin Tissoiresupdate_kconfig() 159507806e9SBenjamin Tissoires{ 160507806e9SBenjamin Tissoires local kernel_checkout="$1" 161507806e9SBenjamin Tissoires local kconfig_file="$2" 162507806e9SBenjamin Tissoires 163507806e9SBenjamin Tissoires if [[ -f "${kconfig_file}" ]]; then 164507806e9SBenjamin Tissoires local local_modified="$(stat -c %Y "${kconfig_file}")" 165507806e9SBenjamin Tissoires 166507806e9SBenjamin Tissoires for config in "${KCONFIG_REL_PATHS[@]}"; do 167507806e9SBenjamin Tissoires local kconfig_src="${config}" 168507806e9SBenjamin Tissoires local src_modified="$(stat -c %Y "${kconfig_src}")" 169507806e9SBenjamin Tissoires # Only update the config if it has been updated after the 170507806e9SBenjamin Tissoires # previously cached config was created. This avoids 171507806e9SBenjamin Tissoires # unnecessarily compiling the kernel and selftests. 172507806e9SBenjamin Tissoires if [[ "${src_modified}" -gt "${local_modified}" ]]; then 173507806e9SBenjamin Tissoires do_update_kconfig "$kernel_checkout" "$kconfig_file" 174507806e9SBenjamin Tissoires # Once we have found one outdated configuration 175507806e9SBenjamin Tissoires # there is no need to check other ones. 176507806e9SBenjamin Tissoires break 177507806e9SBenjamin Tissoires fi 178507806e9SBenjamin Tissoires done 179507806e9SBenjamin Tissoires else 180507806e9SBenjamin Tissoires do_update_kconfig "$kernel_checkout" "$kconfig_file" 181507806e9SBenjamin Tissoires fi 182507806e9SBenjamin Tissoires} 183507806e9SBenjamin Tissoires 184507806e9SBenjamin Tissoiresmain() 185507806e9SBenjamin Tissoires{ 186507806e9SBenjamin Tissoires local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" 187507806e9SBenjamin Tissoires local kernel_checkout=$(realpath "${script_dir}"/../../../../) 188507806e9SBenjamin Tissoires # By default the script searches for the kernel in the checkout directory but 189507806e9SBenjamin Tissoires # it also obeys environment variables O= and KBUILD_OUTPUT= 190507806e9SBenjamin Tissoires local kernel_bzimage="${kernel_checkout}/${BZIMAGE}" 191507806e9SBenjamin Tissoires local command="${DEFAULT_COMMAND}" 192507806e9SBenjamin Tissoires local update_b2c="no" 193507806e9SBenjamin Tissoires local debug_shell="no" 194507806e9SBenjamin Tissoires 195507806e9SBenjamin Tissoires while getopts ':hsud:j:' opt; do 196507806e9SBenjamin Tissoires case ${opt} in 197507806e9SBenjamin Tissoires u) 198507806e9SBenjamin Tissoires update_b2c="yes" 199507806e9SBenjamin Tissoires ;; 200507806e9SBenjamin Tissoires d) 201507806e9SBenjamin Tissoires OUTPUT_DIR="$OPTARG" 202507806e9SBenjamin Tissoires ;; 203507806e9SBenjamin Tissoires j) 204507806e9SBenjamin Tissoires NUM_COMPILE_JOBS="$OPTARG" 205507806e9SBenjamin Tissoires ;; 206507806e9SBenjamin Tissoires s) 207507806e9SBenjamin Tissoires command="/bin/sh" 208507806e9SBenjamin Tissoires debug_shell="yes" 209507806e9SBenjamin Tissoires ;; 210507806e9SBenjamin Tissoires h) 211507806e9SBenjamin Tissoires usage 212507806e9SBenjamin Tissoires exit 0 213507806e9SBenjamin Tissoires ;; 214507806e9SBenjamin Tissoires \? ) 215507806e9SBenjamin Tissoires echo "Invalid Option: -$OPTARG" 216507806e9SBenjamin Tissoires usage 217507806e9SBenjamin Tissoires exit 1 218507806e9SBenjamin Tissoires ;; 219507806e9SBenjamin Tissoires : ) 220507806e9SBenjamin Tissoires echo "Invalid Option: -$OPTARG requires an argument" 221507806e9SBenjamin Tissoires usage 222507806e9SBenjamin Tissoires exit 1 223507806e9SBenjamin Tissoires ;; 224507806e9SBenjamin Tissoires esac 225507806e9SBenjamin Tissoires done 226507806e9SBenjamin Tissoires shift $((OPTIND -1)) 227507806e9SBenjamin Tissoires 228507806e9SBenjamin Tissoires # trap 'catch "$?"' EXIT 229507806e9SBenjamin Tissoires 230507806e9SBenjamin Tissoires if [[ "${debug_shell}" == "no" ]]; then 231507806e9SBenjamin Tissoires if [[ $# -eq 0 ]]; then 232507806e9SBenjamin Tissoires echo "No command specified, will run ${DEFAULT_COMMAND} in the vm" 233507806e9SBenjamin Tissoires else 234507806e9SBenjamin Tissoires command="$@" 235507806e9SBenjamin Tissoires 236507806e9SBenjamin Tissoires if [[ "${command}" == "/bin/bash" || "${command}" == "bash" ]] 237507806e9SBenjamin Tissoires then 238507806e9SBenjamin Tissoires debug_shell="yes" 239507806e9SBenjamin Tissoires fi 240507806e9SBenjamin Tissoires fi 241507806e9SBenjamin Tissoires fi 242507806e9SBenjamin Tissoires 243507806e9SBenjamin Tissoires local kconfig_file="${OUTPUT_DIR}/latest.config" 244507806e9SBenjamin Tissoires local make_command="make -j ${NUM_COMPILE_JOBS} KCONFIG_CONFIG=${kconfig_file}" 245507806e9SBenjamin Tissoires 246507806e9SBenjamin Tissoires # Figure out where the kernel is being built. 247507806e9SBenjamin Tissoires # O takes precedence over KBUILD_OUTPUT. 248507806e9SBenjamin Tissoires if [[ "${O:=""}" != "" ]]; then 249507806e9SBenjamin Tissoires if is_rel_path "${O}"; then 250507806e9SBenjamin Tissoires O="$(realpath "${PWD}/${O}")" 251507806e9SBenjamin Tissoires fi 252507806e9SBenjamin Tissoires kernel_bzimage="${O}/${BZIMAGE}" 253507806e9SBenjamin Tissoires make_command="${make_command} O=${O}" 254507806e9SBenjamin Tissoires elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then 255507806e9SBenjamin Tissoires if is_rel_path "${KBUILD_OUTPUT}"; then 256507806e9SBenjamin Tissoires KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")" 257507806e9SBenjamin Tissoires fi 258507806e9SBenjamin Tissoires kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}" 259507806e9SBenjamin Tissoires make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}" 260507806e9SBenjamin Tissoires fi 261507806e9SBenjamin Tissoires 262507806e9SBenjamin Tissoires local b2c="${OUTPUT_DIR}/vm2c.py" 263507806e9SBenjamin Tissoires 264507806e9SBenjamin Tissoires echo "Output directory: ${OUTPUT_DIR}" 265507806e9SBenjamin Tissoires 266507806e9SBenjamin Tissoires mkdir -p "${OUTPUT_DIR}" 267507806e9SBenjamin Tissoires update_kconfig "${kernel_checkout}" "${kconfig_file}" 268507806e9SBenjamin Tissoires 269507806e9SBenjamin Tissoires recompile_kernel "${kernel_checkout}" "${make_command}" 270507806e9SBenjamin Tissoires 271507806e9SBenjamin Tissoires if [[ "${update_b2c}" == "no" && ! -f "${b2c}" ]]; then 272507806e9SBenjamin Tissoires echo "vm2c script not found in ${b2c}" 273507806e9SBenjamin Tissoires update_b2c="yes" 274507806e9SBenjamin Tissoires fi 275507806e9SBenjamin Tissoires 276507806e9SBenjamin Tissoires if [[ "${update_b2c}" == "yes" ]]; then 277507806e9SBenjamin Tissoires download $B2C_URL $b2c 278507806e9SBenjamin Tissoires chmod +x $b2c 279507806e9SBenjamin Tissoires fi 280507806e9SBenjamin Tissoires 281507806e9SBenjamin Tissoires update_selftests "${kernel_checkout}" "${make_command}" 2827d0b3f10SBenjamin Tissoires run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}" 283507806e9SBenjamin Tissoires if [[ "${debug_shell}" != "yes" ]]; then 284507806e9SBenjamin Tissoires echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}" 285507806e9SBenjamin Tissoires fi 286507806e9SBenjamin Tissoires 287507806e9SBenjamin Tissoires exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE}) 288507806e9SBenjamin Tissoires} 289507806e9SBenjamin Tissoires 290507806e9SBenjamin Tissoiresmain "$@" 291