|
| 1 | +#!/usr/bin/python3 |
| 2 | + |
| 3 | +# SPDX-License-Identifier: GPL-2.0-only |
| 4 | +# Copyright (c) 2026 Intel Corporation |
| 5 | + |
| 6 | +# Author: Kai Zhang <kai.zhang@intel.com> |
| 7 | +# |
| 8 | +# History: Apr. 2026 - Kai Zhang - creation |
| 9 | + |
| 10 | +import random |
| 11 | +import re |
| 12 | +import time |
| 13 | + |
| 14 | +from provider import dmesg_router # pylint: disable=unused-import |
| 15 | +from avocado.utils import process, cpu |
| 16 | +from virttest import error_context, env_process |
| 17 | +from provider.cpu_utils import check_cpu_flags |
| 18 | + |
| 19 | + |
| 20 | +@error_context.context_aware |
| 21 | +def run(test, params, env): |
| 22 | + """ |
| 23 | + TDX CPU off pinned VM down test: |
| 24 | + 1. Boot TDVM |
| 25 | + 2. Pin a TD VM to a cpu, poweroff the cpu and shutdown the TD VM |
| 26 | +
|
| 27 | + :param test: QEMU test object |
| 28 | + :param params: Dictionary with the test parameters |
| 29 | + :param env: Dictionary with test environment. |
| 30 | + """ |
| 31 | + # TD can not boot up with vCPU number larger than host pCPU |
| 32 | + if cpu.online_count() < 64: |
| 33 | + test.cancel("Platform doesn't support to run this test") |
| 34 | + params["smp"] = 64 |
| 35 | + |
| 36 | + for i in range(0, 20): |
| 37 | + params["start_vm"] = "yes" |
| 38 | + env_process.preprocess_vm(test, params, env, params["main_vm"]) |
| 39 | + vm = env.get_vm(params["main_vm"]) |
| 40 | + vm.verify_alive() |
| 41 | + timeout = params.get_numeric("login_timeout", 240) |
| 42 | + session = vm.wait_for_login(timeout=timeout) |
| 43 | + flags = params["guest_flags"] |
| 44 | + check_cpu_flags(params, flags, test, session) |
| 45 | + pid = vm.get_pid() |
| 46 | + |
| 47 | + host_cpu_list = cpu.online_list() |
| 48 | + processor_list = random.sample(host_cpu_list, 1) |
| 49 | + for processor in processor_list: |
| 50 | + process.system(f"taskset -pc {processor} {pid}", ignore_status=True) |
| 51 | + cpu.offline(processor) |
| 52 | + session.cmd("init 0 &", ignore_all_errors=True) |
| 53 | + time.sleep(3) |
| 54 | + |
| 55 | + hkid = params["hkid"] |
| 56 | + tdx_crash_flag = params["tdx_crash_flag"] |
| 57 | + dmesg = process.system_output("dmesg") |
| 58 | + hkid_str = re.findall(r'%s' % hkid, dmesg.decode('utf-8')) |
| 59 | + crash_str = re.findall(r'%s' % tdx_crash_flag, dmesg.decode('utf-8')) |
| 60 | + seamcall_failed_pattern = re.compile(r'^.*SEAMCALL.*failed.*$', re.MULTILINE) |
| 61 | + seamcall_failed_match = seamcall_failed_pattern.search(dmesg.decode('utf-8')) |
| 62 | + if hkid_str or crash_str or seamcall_failed_match: |
| 63 | + test.fail(f"Detected the crash information in {i} time run. Fail!") |
| 64 | + for processor in processor_list: |
| 65 | + cpu.online(processor) |
| 66 | + session.close() |
0 commit comments