diff --git a/cet/cet_tests.sh b/cet/cet_tests.sh index b5533ef..5755fd0 100755 --- a/cet/cet_tests.sh +++ b/cet/cet_tests.sh @@ -13,6 +13,7 @@ TEST_MOD="cet_ioctl" TEST_MOD_KO="${TEST_MOD}.ko" KO_FILE="./cet_driver/${TEST_MOD_KO}" +export OFFLINE_CPUS="" export teardown_handler="cet_teardown" usage() { @@ -28,6 +29,10 @@ __EOF # Reserve for taerdown, present no change for cpu test cet_teardown() { + [[ -z "$OFFLINE_CPUS" ]] || { + set_cpus_on_off "$OFFLINE_CPUS" || test_print_err "Set offline $OFFLINE_CPUS" + } + check_mod=$(lsmod | grep "$TEST_MOD") [[ -z "$check_mod" ]] || { test_print_trc "rmmod $TEST_MOD" @@ -58,6 +63,95 @@ load_cet_driver() { fi } +# Check test used time cycles in log, and print 2 test logs gap rate +# $1: 1st test log file +# $2: 2nd test log file +# $3: test log folder path +# Return: 0 for true, otherwise false or die +cet_perf_compare() { + local file1=$1 + local file2=$2 + local path=$3 + local key_word="RESULTS" + local cycle1="" + local cycle2="" + local gap="" + local gap_rate="" + local result="" + local gap_upper="0.6" + local gap_lower="-2.0" + + cycle1=$(grep "$key_word" "${path}/${file1}" | cut -d ':' -f 4) + cycle2=$(grep "$key_word" "${path}/${file2}" | cut -d ':' -f 4) + test_print_trc "$file1 used cycles $cycle1" + test_print_trc "$file2 used cycles $cycle2" + gap=$(echo "$cycle1 - $cycle2" | bc) + gap_rate=$(echo "scale=4;$gap/$cycle1" | bc) + test_print_trc "$file1 and $file2 gap rate:$gap_rate" + result=$(echo "$gap_rate > $gap_lower && $gap_rate < $gap_upper" | bc) + [[ $result -eq 1 ]] || { + test_print_wrg "gap: $gap_rate is not in the range:$gap_lower ~ $gap_upper" + return 1 + } +} + +bin_parm_test() { + local bin_name=$1 + local bin_parm=$2 + local log_path=/tmp/$3 + + [[ -n "$bin_name" ]] || die "File $bin_name does not exist" + [[ -d "$log_path" ]] || mkdir -p "$log_path" + bin=$(which "$bin_name") + [[ -e "$bin" ]] || { + die "bin:$bin does not exist" + } + + bin_parm_name=$(echo "$bin_parm" | tr ' ' '_') + if [[ "$bin_parm" == "null" ]]; then + log="${log_path}/${bin_name}_${bin_parm_name}.log" + $bin > "$log" + else + log="${log_path}/${bin_name}_${bin_parm_name}.log" + $bin "${bin_parm}" > "$log" || { + test_print_err "Failed to run $bin $bin_parm ret:$?" + return 1 + } + fi + + [[ -e "$log" ]] || die "No $log file" + + return 0 +} + +dmesg_check() { + local key=$1 + local key_parm=$2 + local dmesg_file="" + + dmesg_file=$(extract_case_dmesg -f) + verify_key=$(grep -i "$key" "$dmesg_file") + case $key_parm in + "$CONTAIN") + if [[ -z "$verify_key" ]]; then + die "No $key found in dmesg when test $BIN_NAME, fail." + else + test_print_trc "$key found in dmesg, pass." + fi + ;; + "$NULL") + if [[ -z "$verify_key" ]]; then + test_print_trc "No $key in dmesg when test $BIN_NAME, pass." + else + die "$key found in dmesg when test $BIN_NAME, fail." + fi + ;; + *) + block_test "Invalid key_parm:$key_parm" + ;; + esac +} + cet_shstk_check() { local bin_name=$1 local bin_parm=$2 @@ -144,7 +238,8 @@ cet_dmesg_check() { } cet_tests() { - bin_file="" + local bin_file="" + local legacy="legacy" # Absolute path of BIN_NAME bin_file=$(which "$BIN_NAME") @@ -167,6 +262,95 @@ cet_tests() { cet_ssp) cet_shstk_check "$bin_file" "$PARM" "$TYPE" ;; + specific_cpu_perf) + local cpus="" + local cpu_num="" + local err_num=0 + local cet_compare_path="/tmp/${TYPE}" + + cpus=$(cut -d "-" -f 2 "${CPU_SYSFS_FOLDER}/present") + if [[ "$PARM" == "random" ]]; then + cpu_num=$(shuf -i 0-"$cpus" -n 1) + elif [[ "$PARM" -ge 0 && "$PARM" -le "$cpus" ]]; then + cpu_num=$PARM + else + block_test "Invalid CPU NUM in PARM:$PARM" + fi + + # Check cpu and kernel enable user space SHSTK really first + bin_parm_test "$BIN_NAME" "0" "$TYPE" || { + ((err_num++)) + } + check_fail=$(grep "FAIL" "$cet_compare_path/${BIN_NAME}_0.log") + [[ -z "$check_fail" ]] || { + test_print_wrg "Found FAIL in $BIN_NAME 0 output:$check_fail" + block_test "CET user space SHSTK could not be enabled!" + } + [[ "$err_num" -eq 0 ]] || die "Test cpu 0 $BIN_NAME failed!" + + # CPU 0 must be 1, so do not check cpu 0 + [[ "$cpu_num" -eq 0 ]] || { + cpu_num_on_off=$(cat "${CPU_SYSFS_FOLDER}/cpu${cpu_num}/online") + [[ "$cpu_num_on_off" == "1" ]] || OFFLINE_CPUS="$cpu_num" + set_specific_cpu_on_off "1" "$cpu_num" + } + + last_dmesg_timestamp + bin_parm_test "$BIN_NAME" "$i" "$TYPE" || { + ((err_num++)) + } + bin_parm_test "${BIN_NAME}_${legacy}" "$i" "$TYPE" || { + ((err_num++)) + } + cet_perf_compare "${BIN_NAME}_${i}.log" \ + "${BIN_NAME}_${legacy}_${i}.log" "$cet_compare_path" || { + test_print_err "CPU$i met $BIN_NAME perf regression!" + ((err_num++)) + } + [[ "$err_num" -eq 0 ]] || die "All cpu cet test with err_cnt:$err_num" + dmesg_check "control protection" "$NULL" + dmesg_check "Call Trace" "$NULL" + dmesg_check "segfault" "$NULL" + ;; + all_cpu_perf) + local cet_compare_path="/tmp/${TYPE}" + local err_num=0 + local check_fail="" + + # Check cpu and kernel enable user space SHSTK really first + bin_parm_test "$BIN_NAME" "0" "$TYPE" || { + ((err_num++)) + } + check_fail=$(grep "FAIL" "$cet_compare_path/${BIN_NAME}_0.log") + [[ -z "$check_fail" ]] || { + test_print_wrg "Found FAIL in $BIN_NAME 0 output:$check_fail" + block_test "CET user space SHSTK could not be enabled!" + } + [[ "$err_num" -eq 0 ]] || die "Test cpu 0 $BIN_NAME failed!" + + last_dmesg_timestamp + OFFLINE_CPUS=$(cat "${CPU_SYSFS_FOLDER}/offline") + online_all_cpu + cpus=$(cut -d "-" -f 2 "${CPU_SYSFS_FOLDER}/present") + + for((i=0;i<=cpus;i++)); do + bin_parm_test "$BIN_NAME" "$i" "$TYPE" || { + ((err_num++)) + } + bin_parm_test "${BIN_NAME}_${legacy}" "$i" "$TYPE" || { + ((err_num++)) + } + cet_perf_compare "${BIN_NAME}_${i}.log" \ + "${BIN_NAME}_${legacy}_${i}.log" "$cet_compare_path" || { + test_print_err "CPU$i met $BIN_NAME perf regression!" + ((err_num++)) + } + done + [[ "$err_num" -eq 0 ]] || die "All cpu cet test with err_cnt:$err_num" + dmesg_check "control protection" "$NULL" + dmesg_check "Call Trace" "$NULL" + dmesg_check "segfault" "$NULL" + ;; *) usage block_test "Invalid TYPE:$TYPE" diff --git a/cet/tests b/cet/tests index c694b09..caa44b4 100755 --- a/cet/tests +++ b/cet/tests @@ -21,6 +21,10 @@ cet_tests.sh -t no_cp -n glibc_shstk_test -k "control protection" -p s1 cet_tests.sh -t no_cp -n glibc_shstk_test -k "control protection" -p s3 cet_tests.sh -t no_cp -n glibc_shstk_test -k "control protection" -p buf2 cet_tests.sh -t cet_ssp -n glibc_shstk_test -p ssp +# CET user space SHSTK enable/disable performance tests on random cpu +cet_tests.sh -t specific_cpu_perf -n shstk_cpu -p "random" +# CET user space SHSTK enable/disable performance tests on each cpu +cet_tests.sh -t all_cpu_perf -n shstk_cpu # Kernel space IBT tests cet_tests.sh -t kmod_ibt_illegal -n cet_app -p "b1" -k "Missing ENDBR" cet_tests.sh -t kmod_ibt_legal -n cet_app -p "b2" -k "Missing ENDBR"