#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) 2025 Intel Corporation # # Test for indirect target selection (ITS) cmdline permutations with other bugs # like spectre_v2 and retbleed. import os, sys, subprocess, itertools, re, shutil test_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(0, test_dir + '/../../kselftest') import ksft import common as c bug = "indirect_target_selection" mitigation = c.get_sysfs(bug) if not mitigation or "Not affected" in mitigation: ksft.test_result_skip("Skipping its_permutations.py: not applicable") ksft.finished() if shutil.which('vng') is None: ksft.test_result_skip("Skipping its_permutations.py: virtme-ng ('vng') not found in PATH.") ksft.finished() TEST = f"{test_dir}/its_sysfs.py" default_kparam = ['clearcpuid=hypervisor', 'panic=5', 'panic_on_warn=1', 'oops=panic', 'nmi_watchdog=1', 'hung_task_panic=1'] DEBUG = " -v " # Install dependencies # https://github.com/arighi/virtme-ng # apt install virtme-ng BOOT_CMD = f"vng --run {test_dir}/../../../../../arch/x86/boot/bzImage " #BOOT_CMD += DEBUG bug = "indirect_target_selection" input_options = { 'indirect_target_selection' : ['off', 'on', 'stuff', 'vmexit'], 'retbleed' : ['off', 'stuff', 'auto'], 'spectre_v2' : ['off', 'on', 'eibrs', 'retpoline', 'ibrs', 'eibrs,retpoline'], } def pretty_print(output): OKBLUE = '\033[94m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' # Define patterns and their corresponding colors patterns = { r"^ok \d+": OKGREEN, r"^not ok \d+": FAIL, r"^# Testing .*": OKBLUE, r"^# Found: .*": WARNING, r"^# Totals: .*": BOLD, r"pass:([1-9]\d*)": OKGREEN, r"fail:([1-9]\d*)": FAIL, r"skip:([1-9]\d*)": WARNING, } # Apply colors based on patterns for pattern, color in patterns.items(): output = re.sub(pattern, lambda match: f"{color}{match.group(0)}{ENDC}", output, flags=re.MULTILINE) print(output) combinations = list(itertools.product(*input_options.values())) ksft.print_header() ksft.set_plan(len(combinations)) logs = "" for combination in combinations: append = "" log = "" for p in default_kparam: append += f' --append={p}' command = BOOT_CMD + append test_params = "" for i, key in enumerate(input_options.keys()): param = f'{key}={combination[i]}' test_params += f' {param}' command += f" --append={param}" command += f" -- {TEST}" test_name = f"{bug} {test_params}" pretty_print(f'# Testing {test_name}') t = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) t.wait() output, _ = t.communicate() if t.returncode == 0: ksft.test_result_pass(test_name) else: ksft.test_result_fail(test_name) output = output.decode() log += f" {output}" pretty_print(log) logs += output + "\n" # Optionally use tappy to parse the output # apt install python3-tappy with open("logs.txt", "w") as f: f.write(logs) ksft.finished()