Skip to content

Commit 0874a20

Browse files
authored
Merge pull request #4255 from JinLiul/snp_cpu_model
snp_cpu_model:Add cpu model test on snp guest
2 parents e843780 + cf5a1ec commit 0874a20

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

qemu/tests/cfg/snp_cpu_model.cfg

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
- snp_cpu_model:
2+
type = snp_cpu_model
3+
only Linux
4+
only x86_64
5+
kill_vm = yes
6+
login_timeout = 240
7+
start_vm = no
8+
image_snapshot = yes
9+
mem = 8192
10+
smp = 8
11+
vm_secure_guest_type = snp
12+
vm_sev_reduced_phys_bits = 1
13+
vm_sev_cbitpos = 51
14+
virtio_dev_disable_legacy = on
15+
bios_path = /usr/share/edk2/ovmf/OVMF.amdsev.fd
16+
snp_module_path = "/sys/module/kvm_amd/parameters/sev_snp"
17+
guest_tool_install = "dnf install -y snpguest"
18+
attestation_script = regular_attestation_workflow.sh
19+
guest_dir = /home
20+
guest_cmd = ${guest_dir}/${attestation_script}
21+
host_script = sev-snp/${attestation_script}
22+
module_status = Y y 1
23+
snp_guest_check = "journalctl|grep -i -w snp"
24+
only HostCpuVendor.amd
25+
auto_cpu_model = no
26+
get_model_cmd = "lscpu | grep 'Model name'"
27+
variants model:
28+
- EPYC-Genoa:
29+
cpu_model = EPYC-Genoa
30+
model_pattern = "AMD EPYC-Genoa Processor%s"
31+
- EPYC-Genoa-v1:
32+
cpu_model = EPYC-Genoa-v1
33+
model_pattern = "AMD EPYC-Genoa Processor%s"
34+
- EPYC-v4:
35+
cpu_model = EPYC-v4
36+
model_pattern = "AMD EPYC-v4 Processor%s"
37+
- EPYC-Milan-v2:
38+
cpu_model = EPYC-Milan-v2
39+
model_pattern = "AMD EPYC-Milan-v2 Processor%s"
40+
- host:
41+
cpu_model = host
42+
model_pattern = ""
43+
required_qemu = [9.1.0, )

qemu/tests/snp_cpu_model.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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

Comments
 (0)