#!/bin/bash # SPDX-License-Identifier: GPL-2.0 set -ue CROSS_COMPILE="${CROSS_COMPILE:-""}" test_dir=$(realpath "$(dirname "$0")") kernel_dir=$(realpath "$test_dir/../../../..") tmp_dir=$(mktemp -d /tmp/kho-test.XXXXXXXX) headers_dir="$tmp_dir/usr" initrd_dir="$tmp_dir/initrd" initrd="$tmp_dir/initrd.cpio" source "$test_dir/../kselftest/ktap_helpers.sh" function usage() { cat < "$kho_config" </dev/null || skip "$opt is missing" done < "$kho_config" $make_cmd "$kimage" $make_cmd headers_install INSTALL_HDR_PATH="$headers_dir" } function mkinitrd() { local kernel=$1 mkdir -p "$initrd_dir"/{dev,debugfs,proc} sudo mknod "$initrd_dir/dev/console" c 5 1 "$CROSS_COMPILE"gcc -s -static -Os -nostdinc -I"$headers_dir/include" \ -fno-asynchronous-unwind-tables -fno-ident -nostdlib \ -include "$test_dir/../../../include/nolibc/nolibc.h" \ -o "$initrd_dir/init" "$test_dir/init.c" \ cp "$kernel" "$initrd_dir/kernel" pushd "$initrd_dir" &>/dev/null find . | cpio -H newc --create > "$initrd" 2>/dev/null popd &>/dev/null } function run_qemu() { local qemu_cmd=$1 local cmdline=$2 local kernel=$3 local serial="$tmp_dir/qemu.serial" cmdline="$cmdline kho=on panic=-1" $qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \ -accel kvm -accel hvf -accel tcg \ -serial file:"$serial" \ -append "$cmdline" \ -kernel "$kernel" \ -initrd "$initrd" grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed" } function target_to_arch() { local target=$1 case $target in aarch64) echo "arm64" ;; x86_64) echo "x86" ;; *) skip "architecture $target is not supported" esac } function main() { local build_dir="$kernel_dir/.kho" local jobs=$(($(nproc) * 2)) local target="$(uname -m)" # skip the test if any of the preparation steps fails set -o errtrace trap skip ERR while getopts 'hd:j:t:' opt; do case $opt in d) build_dir="$OPTARG" ;; j) jobs="$OPTARG" ;; t) target="$OPTARG" ;; h) usage exit 0 ;; *) echo Unknown argument "$opt" usage exit 1 ;; esac done ktap_print_header ktap_set_plan 1 if [[ "$target" != "$(uname -m)" ]] && [[ -z "$CROSS_COMPILE" ]]; then skip "Cross-platform testing needs to specify CROSS_COMPILE" fi mkdir -p "$build_dir" local arch=$(target_to_arch "$target") source "$test_dir/$arch.conf" # build the kernel and create initrd # initrd includes the kernel image that will be kexec'ed local make_cmd="make ARCH=$arch CROSS_COMPILE=$CROSS_COMPILE -j$jobs" build_kernel "$build_dir" "$make_cmd" "$QEMU_KCONFIG" "$KERNEL_IMAGE" local kernel="$build_dir/arch/$arch/boot/$KERNEL_IMAGE" mkinitrd "$kernel" run_qemu "$QEMU_CMD" "$KERNEL_CMDLINE" "$kernel" ktap_test_pass "KHO succeeded" } main "$@"