|
| 1 | +import json |
| 2 | +import os |
| 3 | +import re |
| 4 | + |
| 5 | +from avocado.utils import cpu, process |
| 6 | +from virttest import data_dir as virttest_data_dir |
| 7 | +from virttest import error_context, utils_misc |
| 8 | +from virttest.utils_misc import verify_dmesg |
| 9 | + |
| 10 | + |
| 11 | +@error_context.context_aware |
| 12 | +def run(test, params, env): |
| 13 | + """ |
| 14 | + CPU model test on SNP geust: |
| 15 | + 1. Check host snp capability |
| 16 | + 2. Get cpu model lists supported by host |
| 17 | + 3. Check if current cpu model is in the supported lists, if no, cancel test |
| 18 | + 4. Otherwise, boot snp guest with the cpu model |
| 19 | + 5. Verify snp enabled in guest |
| 20 | + 6. Verify attestation |
| 21 | +
|
| 22 | + :param test: QEMU test object |
| 23 | + :param params: Dictionary with the test parameters |
| 24 | + :param env: Dictionary with test environment. |
| 25 | + """ |
| 26 | + error_context.context("Start sev-snp test", test.log.info) |
| 27 | + |
| 28 | + snp_module_path = params["snp_module_path"] |
| 29 | + if os.path.exists(snp_module_path): |
| 30 | + with open(snp_module_path) as f: |
| 31 | + output = f.read().strip() |
| 32 | + if output not in params.objects("module_status"): |
| 33 | + test.cancel("Host sev-snp support check fail.") |
| 34 | + else: |
| 35 | + test.cancel("Host sev-snp support check fail.") |
| 36 | + |
| 37 | + qemu_binary = utils_misc.get_qemu_binary(params) |
| 38 | + qmp_cmds = [ |
| 39 | + '{"execute": "qmp_capabilities"}', |
| 40 | + '{"execute": "query-cpu-definitions", "id": "RAND91"}', |
| 41 | + '{"execute": "quit"}', |
| 42 | + ] |
| 43 | + cmd = ( |
| 44 | + "echo -e '{0}' | {1} -qmp stdio -vnc none -M none | grep return |" |
| 45 | + "grep RAND91".format(r"\n".join(qmp_cmds), qemu_binary) |
| 46 | + ) |
| 47 | + output = process.run( |
| 48 | + cmd, timeout=10, ignore_status=True, shell=True, verbose=False |
| 49 | + ).stdout_text |
| 50 | + out = json.loads(output)["return"] |
| 51 | + |
| 52 | + model = params["model"] |
| 53 | + model_pattern = params["model_pattern"] |
| 54 | + |
| 55 | + model_ib = "%s-IBPB" % model |
| 56 | + name_ib = " \\(with IBPB\\)" |
| 57 | + |
| 58 | + models = [x["name"] for x in out if not x["unavailable-features"]] |
| 59 | + if model == "host": |
| 60 | + cpu_model = "host" |
| 61 | + guest_model = "" |
| 62 | + elif model_ib in models: |
| 63 | + cpu_model = model_ib |
| 64 | + guest_model = model_pattern % name_ib |
| 65 | + elif model in models: |
| 66 | + cpu_model = model |
| 67 | + guest_model = model_pattern % "" |
| 68 | + else: |
| 69 | + test.cancel("This host doesn't support cpu model %s" % model) |
| 70 | + |
| 71 | + family_id = cpu.get_family() |
| 72 | + model_id = cpu.get_model() |
| 73 | + dict_cpu = {"251": "milan", "2517": "genoa", "2617": "turin"} |
| 74 | + key = str(family_id) + str(model_id) |
| 75 | + host_cpu_model = dict_cpu.get(key, "unknown") |
| 76 | + |
| 77 | + vm = env.get_vm(params["main_vm"]) |
| 78 | + vm.params["cpu_model"] = cpu_model # pylint: disable=E0606 |
| 79 | + vm.create() |
| 80 | + |
| 81 | + error_context.context("Try to log into guest", test.log.info) |
| 82 | + session = vm.wait_for_login() |
| 83 | + |
| 84 | + verify_dmesg() |
| 85 | + guest_check_cmd = params["snp_guest_check"] |
| 86 | + try: |
| 87 | + session.cmd_output(guest_check_cmd, timeout=240) |
| 88 | + except Exception as e: |
| 89 | + test.fail("Guest snp verify fail: %s" % str(e)) |
| 90 | + |
| 91 | + error_context.context("Check cpu model inside guest", test.log.info) |
| 92 | + cmd = params["get_model_cmd"] |
| 93 | + out = session.cmd_output(cmd) |
| 94 | + if not re.search(guest_model, out): # pylint: disable=E0606 |
| 95 | + test.fail("Guest cpu model is not right") |
| 96 | + |
| 97 | + # Verify attestation |
| 98 | + error_context.context("Start to do attestation", test.log.info) |
| 99 | + guest_dir = params["guest_dir"] |
| 100 | + host_script = params["host_script"] |
| 101 | + guest_cmd = params["guest_cmd"] |
| 102 | + deps_dir = virttest_data_dir.get_deps_dir() |
| 103 | + host_file = os.path.join(deps_dir, host_script) |
| 104 | + try: |
| 105 | + vm.copy_files_to(host_file, guest_dir) |
| 106 | + session.cmd_output(params["guest_tool_install"], timeout=240) |
| 107 | + session.cmd_output("chmod 755 %s" % guest_cmd) |
| 108 | + except Exception as e: |
| 109 | + test.fail("Guest test preperation fail: %s" % str(e)) |
| 110 | + guest_cmd = guest_cmd + " " + host_cpu_model |
| 111 | + s = session.cmd_status(guest_cmd, timeout=360) |
| 112 | + if s: |
| 113 | + test.fail("Guest script error") |
0 commit comments