Skip to content

Commit 31528c3

Browse files
committed
Add function for secure capability verification
Introduces a function to verify Secure (SEV/SEV-ES/SNP/TDX) capability enablement on the host as well as in a VM: 1. Validates host support for secure feature. 2. Queries SEV status via QMP and verifies policy. 3. Executes guest command to confirm secure guest enablement. Signed-off-by: Srikanth Aithal <srikanth.aithal@amd.com>
1 parent 37b7568 commit 31528c3

2 files changed

Lines changed: 123 additions & 0 deletions

File tree

virttest/utils_linux_modules.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import logging
6+
import os
67

78
from avocado.utils import linux_modules
89

@@ -111,3 +112,30 @@ def kconfig_is_not_set(config_name, session=None):
111112
return (
112113
check_kernel_config(config_name, session) is linux_modules.ModuleConfig.NOT_SET
113114
)
115+
116+
117+
def get_module_parameter(module_name, param_name, session=None):
118+
"""
119+
Get the value of a specific kernel module parameter
120+
121+
:param module_name: Name of the kernel module (e.g., 'kvm_amd', 'kvm_intel')
122+
:param param_name: Name of the parameter to check (e.g., 'sev', 'tdx')
123+
:param session: Guest session, command is run on host if None
124+
:return: Parameter value as string, or None if not found
125+
:rtype: str or None
126+
"""
127+
param_path = f"/sys/module/{module_name}/parameters/{param_name}"
128+
129+
try:
130+
if session is None:
131+
if os.path.exists(param_path):
132+
with open(param_path, "r") as f:
133+
return f.read().strip()
134+
else:
135+
status, output = session.cmd_status_output(f"cat {param_path}")
136+
if status == 0:
137+
return output.strip()
138+
except (IOError, OSError) as e:
139+
LOG.debug("Failed to read module parameter %s: %s", param_path, e)
140+
141+
return None

virttest/utils_misc.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
kernel_interface,
8787
logging_manager,
8888
utils_disk,
89+
utils_linux_modules,
8990
utils_logfile,
9091
utils_selinux,
9192
)
@@ -4705,3 +4706,97 @@ def _md5(fd):
47054706
if _md5(fd_a) == _md5(fd_b):
47064707
return True
47074708
return False
4709+
4710+
4711+
def verify_secure_host(secure_guest_type, module_name, param_name, expected_values):
4712+
"""
4713+
Verify if specific cvm feature is enabled on the host
4714+
4715+
:param secure_guest_type: Type of secure guest (e.g., 'sev', 'snp', 'tdx')
4716+
:param module_name: Name of the kernel module (e.g., 'kvm_amd', 'kvm_intel')
4717+
:param param_name: Name of the module parameter to check (e.g., 'sev', 'tdx')
4718+
:param expected_values: List of acceptable parameter values (e.g., ['Y', '1'])
4719+
"""
4720+
LOG.info(f"Verifying cvm {secure_guest_type} capability enablement on host")
4721+
4722+
param_value = utils_linux_modules.get_module_parameter(module_name, param_name)
4723+
4724+
if param_value is None:
4725+
raise exceptions.TestCancel(
4726+
f"Host support for {secure_guest_type} capability: "
4727+
f"module parameter {module_name}/{param_name} not found."
4728+
)
4729+
4730+
if param_value not in expected_values:
4731+
raise exceptions.TestCancel(
4732+
f"Host support for {secure_guest_type} capability check failed: "
4733+
f"{module_name}/{param_name}={param_value}, expected one of {expected_values}"
4734+
)
4735+
4736+
4737+
def verify_secure_guest(
4738+
session, vm, secure_guest_type, guest_check_cmd, expected_policy=None
4739+
):
4740+
"""
4741+
Verify if specific cvm feature is enabled inside the VM
4742+
4743+
:param session: session object to vm
4744+
:param vm: virtual machine object
4745+
:param secure_guest_type: Type of secure guest (e.g., 'sev', 'snp', 'tdx')
4746+
:param guest_check_cmd: Command to run in guest to verify CVM capability
4747+
:param expected_policy: Expected policy value (can be hex string or int), optional for AMD CVM
4748+
"""
4749+
amd_cvm_secureguest = ["sev", "snp"]
4750+
if secure_guest_type in amd_cvm_secureguest:
4751+
try:
4752+
cvm_guest_info = vm.monitor.query_sev()
4753+
if not cvm_guest_info:
4754+
raise exceptions.TestFail("QMP query-sev returned empty response.")
4755+
LOG.info(f"QMP cvm info: {cvm_guest_info}")
4756+
except Exception as e:
4757+
raise exceptions.TestFail(f"QMP query-sev failed: {str(e)}")
4758+
4759+
if expected_policy is not None:
4760+
if isinstance(expected_policy, str):
4761+
policy_value = int(expected_policy, 0)
4762+
else:
4763+
policy_value = expected_policy
4764+
4765+
if secure_guest_type == "snp":
4766+
if "snp-policy" not in cvm_guest_info:
4767+
raise exceptions.TestFail(
4768+
"QMP snp-policy not found in query-sev response."
4769+
)
4770+
actual_policy = cvm_guest_info["snp-policy"]
4771+
else:
4772+
if "policy" not in cvm_guest_info:
4773+
raise exceptions.TestFail(
4774+
"QMP policy not found in query-sev response."
4775+
)
4776+
actual_policy = cvm_guest_info["policy"]
4777+
4778+
if actual_policy != policy_value:
4779+
raise exceptions.TestFail(
4780+
f"QMP cvm policy mismatch: expected {policy_value}, "
4781+
f"got {actual_policy}"
4782+
)
4783+
4784+
guest_state = cvm_guest_info.get("state")
4785+
if guest_state != "running":
4786+
raise exceptions.TestFail(
4787+
f"CVM state is {guest_state or 'missing'}, expected 'running'"
4788+
)
4789+
4790+
LOG.info(f"Verifying cvm {secure_guest_type} capability enablement in guest")
4791+
try:
4792+
return_code, output = session.cmd_status_output(guest_check_cmd, timeout=240)
4793+
if return_code != 0:
4794+
raise exceptions.TestFail(
4795+
f"Guest cvm {secure_guest_type} capability check failed with "
4796+
f"return code {return_code}: {output}"
4797+
)
4798+
LOG.info(f"Guest cvm {secure_guest_type} capability check output: {output}")
4799+
except Exception as e:
4800+
raise exceptions.TestFail(
4801+
f"Guest cvm {secure_guest_type} capability verify fail: {str(e)}"
4802+
)

0 commit comments

Comments
 (0)