Skip to content

Commit bef9b32

Browse files
committed
Add SEV/SEV-ES/SEV-SNP boot test
Add CVM boot test case for AMD SEV, SEV-ES, and SEV-SNP on Milan, Genoa, and Turin hosts" The test verifies: - Host SEV, SEV-ES, and SEV-SNP support via /sys/module/kvm_amd/parameters. - Guest CVM enablement. - QMP query-sev policy and state compliance. Includes configuration file with parameters for SEV, SEV-ES, and SEV-SNP variants. Signed-off-by: Srikanth Aithal <[email protected]>
1 parent 0bbccbe commit bef9b32

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

qemu/tests/amd_cvm_boot.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import os
2+
3+
from avocado.utils import cpu
4+
from virttest import error_context
5+
from virttest.utils_misc import verify_dmesg
6+
7+
8+
@error_context.context_aware
9+
def run(test, params, env):
10+
"""
11+
Qemu CVM (SEV/SEV-ES/SEV-SNP) basic test on AMD Milan and above hosts.
12+
Steps:
13+
1. Verify host SEV/SEV-ES/SEV-SNP support via
14+
/sys/module/kvm_amd/parameters.
15+
2. Check for valid OVMF BIOS path.
16+
3. Validate host CPU (Milan, Genoa, Turin).
17+
4. Boot a SEV or SEV-ES or SEV-SNP CVM VM.
18+
5. Verify CVM enablement in guest via dmesg.
19+
6. Check QMP query-sev policy and state.
20+
:param test: QEMU test object.
21+
:param params: Dictionary with test parameters:
22+
- cvm_module_path: Path to SEV* status file
23+
(e.g., /sys/module/kvm_amd/parameters/sev).
24+
- module_status: Expected SEV*/SEV-SNP status (e.g., ["1", "Y"]).
25+
- bios_path: Path to OVMF BIOS for CVM.
26+
- main_vm: Name of the VM to test.
27+
- vm_secure_guest_type: Type of CVM ("sev" "seves" or "snp").
28+
- vm_sev_policy: Expected SEV/SEV-ES/SNP policy value.
29+
- cvm_guest_check: Command to verify CVM ("sev" "seves" or "snp")
30+
enablement in the guest.
31+
(e.g., 'journalctl|grep -i -w sev-es').
32+
- login_timeout: VM login timeout in seconds (default: 240).
33+
:param env: Dictionary with test environment.
34+
:raises: test.cancel if host lacks specific cvm capability support,
35+
BIOS is missing, or CPU is unsupported.
36+
:raises: test.fail if guest cvm capability verification,
37+
QMP policy check, or dmesg check fails.
38+
39+
"""
40+
error_context.context("Start cvm test", test.log.info)
41+
timeout = params.get_numeric("login_timeout", 240)
42+
43+
cvm_module_path = params["cvm_module_path"]
44+
cvm_type = params["vm_secure_guest_type"]
45+
if os.path.exists(cvm_module_path):
46+
with open(cvm_module_path) as f:
47+
output = f.read().strip()
48+
if output not in params.objects("module_status"):
49+
test.cancel(
50+
f"Host support for {cvm_type} capability check failed.")
51+
else:
52+
test.cancel(f"Host support for {cvm_type} capability check failed.")
53+
biospath = params.get("bios_path")
54+
if not os.path.isfile(biospath):
55+
test.cancel("bios_path not exist %s." % biospath)
56+
family_id = int(cpu.get_family())
57+
model_id = int(cpu.get_model())
58+
supported_cpus = {
59+
"milan": [25, 0, 15],
60+
"genoa": [25, 16, 31],
61+
"bergamo": [25, 160, 175],
62+
"turin": [26, 0, 31]
63+
}
64+
host_platform = None
65+
for platform, values in supported_cpus.items():
66+
if values[0] == family_id:
67+
if model_id >= values[1] and model_id <= values[2]:
68+
host_platform = platform
69+
if not host_platform:
70+
test.cancel("Unsupported platform. Requires Milan or above.")
71+
test.log.info("Detected platform: %s", host_platform)
72+
vm_name = params["main_vm"]
73+
vm = env.get_vm(vm_name)
74+
try:
75+
vm.create()
76+
vm.verify_alive()
77+
except Exception as e:
78+
test.fail("Failed to create VM: %s", str(e))
79+
error_context.context("Logging into VM", test.log.info)
80+
try:
81+
session = vm.wait_for_login(timeout=timeout)
82+
except Exception as e:
83+
test.fail("Failed to login to VM: %s", str(e))
84+
# Verify host dmesg for any errors during the guest boot
85+
verify_dmesg()
86+
87+
cvm_guest_info = vm.monitor.query_sev()
88+
if not cvm_guest_info:
89+
test.fail("QMP query-sev returned empty response.")
90+
test.log.info("QMP cvm info: %s:", cvm_guest_info)
91+
expected_policy = vm.params.get_numeric("vm_sev_policy")
92+
if params["vm_secure_guest_type"] == "snp":
93+
if "snp-policy" not in cvm_guest_info:
94+
test.fail("QMP snp-policy not found in query-sev response.")
95+
actual_policy = cvm_guest_info["snp-policy"]
96+
else:
97+
if "policy" not in cvm_guest_info:
98+
test.fail("QMP policy not found in query-sev response.")
99+
actual_policy = cvm_guest_info["policy"]
100+
if actual_policy != expected_policy:
101+
test.fail(
102+
"QMP cvm policy mismatch: expected %s, "
103+
"got %s", expected_policy, actual_policy
104+
)
105+
if cvm_guest_info.get("state") != "running":
106+
test.fail(
107+
"CVM state is %s, expected 'running'", cvm_guest_info.get('state'))
108+
error_context.context(
109+
f"Verifying cvm {cvm_type} capability enablement "
110+
"in guest", test.log.info
111+
)
112+
guest_check_cmd = params["cvm_guest_check"]
113+
try:
114+
return_code, output = session.cmd_status_output(
115+
guest_check_cmd, timeout=240)
116+
if return_code != 0:
117+
test.fail(
118+
"Guest cvm %s capability check failed with "
119+
"return code %d: %s", cvm_type, return_code, output
120+
)
121+
test.log.info(
122+
"Guest cvm %s capability check output: %s", cvm_type, output)
123+
except Exception as e:
124+
test.fail("Guest cvm {cvm_type} capability verify fail: %s" % str(e))
125+
finally:
126+
session.close()
127+
vm.destroy()

qemu/tests/cfg/amd_cvm_boot.cfg

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
- amd_cvm_boot:
2+
type = amd_cvm_boot
3+
only Linux
4+
kill_vm = yes
5+
login_timeout = 240
6+
start_vm = no
7+
image_snapshot = yes
8+
mem = 8192
9+
smp = 8
10+
virtio_dev_iommu_platform = on
11+
virtio_dev_disable_legacy = on
12+
bios_path = /usr/share/ovmf/OVMF.fd
13+
module_status = Y y 1
14+
variants:
15+
- sev:
16+
vm_secure_guest_type = sev
17+
required_qemu = [2.12, )
18+
vm_sev_cbitpos = 51
19+
vm_sev_reduced_phys_bits = 1
20+
cvm_module_path = "/sys/module/kvm_amd/parameters/sev"
21+
cvm_guest_check = "journalctl | grep -i -w sev"
22+
vm_sev_policy = 3
23+
- seves:
24+
vm_secure_guest_type = sev
25+
required_qemu = [6.0, )
26+
vm_sev_cbitpos = 51
27+
vm_sev_reduced_phys_bits = 1
28+
cvm_module_path = "/sys/module/kvm_amd/parameters/sev_es"
29+
cvm_guest_check = "journalctl | grep -i -w sev-es"
30+
vm_sev_policy = 7
31+
- snp:
32+
vm_secure_guest_type = snp
33+
required_qemu = [9.1.0, )
34+
vm_sev_reduced_phys_bits = 1
35+
vm_sev_cbitpos = 51
36+
cvm_module_path = "/sys/module/kvm_amd/parameters/sev_snp"
37+
cvm_guest_check = "journalctl | grep -i -w snp"
38+
vm_sev_policy = 196608

0 commit comments

Comments
 (0)