#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) 2025 Intel Corporation # # This contains kselftest framework adapted common functions for testing # mitigation for x86 bugs. import os, sys, re, shutil sys.path.insert(0, '../../kselftest') import ksft def read_file(path): if not os.path.exists(path): return None with open(path, 'r') as file: return file.read().strip() def cpuinfo_has(arg): cpuinfo = read_file('/proc/cpuinfo') if arg in cpuinfo: return True return False def cmdline_has(arg): cmdline = read_file('/proc/cmdline') if arg in cmdline: return True return False def cmdline_has_either(args): cmdline = read_file('/proc/cmdline') for arg in args: if arg in cmdline: return True return False def cmdline_has_none(args): return not cmdline_has_either(args) def cmdline_has_all(args): cmdline = read_file('/proc/cmdline') for arg in args: if arg not in cmdline: return False return True def get_sysfs(bug): return read_file("/sys/devices/system/cpu/vulnerabilities/" + bug) def sysfs_has(bug, mitigation): status = get_sysfs(bug) if mitigation in status: return True return False def sysfs_has_either(bugs, mitigations): for bug in bugs: for mitigation in mitigations: if sysfs_has(bug, mitigation): return True return False def sysfs_has_none(bugs, mitigations): return not sysfs_has_either(bugs, mitigations) def sysfs_has_all(bugs, mitigations): for bug in bugs: for mitigation in mitigations: if not sysfs_has(bug, mitigation): return False return True def bug_check_pass(bug, found): ksft.print_msg(f"\nFound: {found}") # ksft.print_msg(f"\ncmdline: {read_file('/proc/cmdline')}") ksft.test_result_pass(f'{bug}: {found}') def bug_check_fail(bug, found, expected): ksft.print_msg(f'\nFound:\t {found}') ksft.print_msg(f'Expected:\t {expected}') ksft.print_msg(f"\ncmdline: {read_file('/proc/cmdline')}") ksft.test_result_fail(f'{bug}: {found}') def bug_status_unknown(bug, found): ksft.print_msg(f'\nUnknown status: {found}') ksft.print_msg(f"\ncmdline: {read_file('/proc/cmdline')}") ksft.test_result_fail(f'{bug}: {found}') def basic_checks_sufficient(bug, mitigation): if not mitigation: bug_status_unknown(bug, "None") return True elif mitigation == "Not affected": ksft.test_result_pass(bug) return True elif mitigation == "Vulnerable": if cmdline_has_either([f'{bug}=off', 'mitigations=off']): bug_check_pass(bug, mitigation) return True return False def get_section_info(vmlinux, section_name): from elftools.elf.elffile import ELFFile with open(vmlinux, 'rb') as f: elffile = ELFFile(f) section = elffile.get_section_by_name(section_name) if section is None: ksft.print_msg("Available sections in vmlinux:") for sec in elffile.iter_sections(): ksft.print_msg(sec.name) raise ValueError(f"Section {section_name} not found in {vmlinux}") return section['sh_addr'], section['sh_offset'], section['sh_size'] def get_patch_sites(vmlinux, offset, size): import struct output = [] with open(vmlinux, 'rb') as f: f.seek(offset) i = 0 while i < size: data = f.read(4) # s32 if not data: break sym_offset = struct.unpack('