Skip to content

Commit 07ac157

Browse files
authored
Merge pull request avocado-framework#4276 from PaulYuuu/sev-auto-bits
feat: auto-detect SEV cbitpos and reduced-phys-bits from host capability
2 parents 87f56e2 + 49afc5f commit 07ac157

3 files changed

Lines changed: 75 additions & 57 deletions

File tree

virttest/coco/__init__.py

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,4 @@
1313
# Copyright: Red Hat (c) 2025
1414
# Author: Yihuang Yu <yihyu@redhat.com>
1515

16-
17-
import logging
18-
19-
from avocado.utils import cpu as utils
20-
21-
from virttest.cpu import UnsupportedCPU, cpuid
22-
23-
LOG = logging.getLogger("avocado." + __name__)
24-
25-
26-
def get_amd_cbit_position():
27-
"""
28-
Get AMD C-bit position for memory encryption
29-
30-
This function checks if the CPU supports SEV (Secure Encrypted Virtualization)
31-
and returns the C-bit position used for memory encryption.
32-
33-
:return: C-bit position (0-63)
34-
:raises: UnsupportedCPU if not an AMD CPU, CPU doesn't support required
35-
extended CPUID leaf, or SEV is not supported
36-
"""
37-
if utils.get_vendor() != "amd":
38-
raise UnsupportedCPU("C-bit detection only supported on AMD CPU")
39-
40-
# Check maximum extended leaf
41-
eax, _, _, _ = cpuid(0x80000000)
42-
if eax < 0x8000001F:
43-
raise UnsupportedCPU("CPU does not support extended leaf 0x8000001f")
44-
45-
# Query SEV/SME features
46-
eax, ebx, _, _ = cpuid(0x8000001F)
47-
48-
# Check SEV support bit (EAX bit 1)
49-
if (eax & 2) == 0:
50-
raise UnsupportedCPU("CPU does not support SEV")
51-
52-
# Extract C-bit position (lower 6 bits of EBX) with additional validation
53-
cbit_position = ebx & 0x3F
54-
LOG.debug("AMD C-bit position: %d", cbit_position)
55-
return cbit_position
16+
from . import sev

virttest/coco/sev.py

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,84 @@
1818

1919
from avocado.utils import cpu as utils
2020

21-
from virttest.cpu import cpuid
21+
from virttest.cpu import UnsupportedCPU, cpuid
2222

2323
LOG = logging.getLogger("avocado." + __name__)
2424

2525

26+
def _get_mem_encryption_features():
27+
"""
28+
Get AMD memory encryption CPUID features (internal helper)
29+
30+
Query CPUID leaf 0x8000001F for SME/SEV memory encryption features.
31+
32+
:return: Tuple of (eax, ebx, ecx, edx) register values from CPUID 0x8000001F
33+
:raises: UnsupportedCPU if not an AMD CPU, CPU doesn't support required
34+
extended CPUID leaf, or SME/SEV is not supported
35+
"""
36+
if utils.get_vendor() != "amd":
37+
raise UnsupportedCPU("AMD memory encryption only supported on AMD CPU")
38+
39+
# Check maximum extended leaf
40+
eax, _, _, _ = cpuid(0x80000000)
41+
if eax < 0x8000001F:
42+
raise UnsupportedCPU("CPU does not support extended leaf 0x8000001f")
43+
44+
# Query SEV/SME features
45+
eax, ebx, ecx, edx = cpuid(0x8000001F)
46+
47+
# Check SME or SEV support (EAX bit 0 or bit 1)
48+
if (eax & 0x3) == 0:
49+
raise UnsupportedCPU("CPU does not support SME or SEV")
50+
51+
return eax, ebx, ecx, edx
52+
53+
54+
def get_cbit_position():
55+
"""
56+
Get C-bit position for memory encryption
57+
58+
This function checks if the CPU supports SME/SEV and returns the C-bit
59+
position used for memory encryption.
60+
61+
:return: C-bit position (0-63)
62+
:raises: UnsupportedCPU if not an AMD CPU, CPU doesn't support required
63+
extended CPUID leaf, or SME/SEV is not supported
64+
"""
65+
_, ebx, _, _ = _get_mem_encryption_features()
66+
67+
# Extract C-bit position (lower 6 bits of EBX)
68+
cbit_position = ebx & 0x3F
69+
return cbit_position
70+
71+
72+
def get_reduced_phys_bits():
73+
"""
74+
Get physical address bits reduced by memory encryption
75+
76+
This function checks if the CPU supports SME/SEV and returns the number
77+
of physical address bits reduced due to encryption metadata overhead.
78+
79+
:return: Number of physical address bits reduced (0-63)
80+
:raises: UnsupportedCPU if not an AMD CPU, CPU doesn't support required
81+
extended CPUID leaf, or SME/SEV is not supported
82+
"""
83+
_, ebx, _, _ = _get_mem_encryption_features()
84+
85+
# Extract reduced physical address bits (bits [11:6] of EBX)
86+
reduced_bits = (ebx >> 6) & 0x3F
87+
return reduced_bits
88+
89+
2690
def is_sev_snp_supported():
2791
"""
2892
Check if AMD SEV-SNP (Secure Nested Paging) is supported.
2993
3094
:return: True if SEV-SNP is supported, False otherwise
3195
"""
3296
try:
33-
if utils.get_vendor() != "amd":
34-
return False
35-
36-
# Check maximum extended leaf
37-
eax, _, _, _ = cpuid(0x80000000)
38-
if eax < 0x8000001F:
39-
return False
40-
41-
# Query SEV/SME features
42-
eax, _, _, _ = cpuid(0x8000001F)
43-
97+
eax, _, _, _ = _get_mem_encryption_features()
4498
# Check SEV-SNP support bit (EAX bit 4)
4599
return bool(eax & (1 << 4))
46-
except Exception:
100+
except UnsupportedCPU:
47101
return False

virttest/qemu_devices/qcontainer.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
# Internal imports
3535
from virttest import (
3636
arch,
37+
coco,
3738
data_dir,
3839
qemu_storage,
3940
storage,
@@ -3981,10 +3982,12 @@ def _gen_sev_common_props(params):
39813982
Required: cbitpos, reduced-phys-bits
39823983
"""
39833984
sev_common_props = {
3984-
# FIXME: Set the following two properties from sev capabilities
3985-
# if they are not set yet
3986-
"cbitpos": int(params["vm_sev_cbitpos"]),
3987-
"reduced-phys-bits": int(params["vm_sev_reduced_phys_bits"]),
3985+
"cbitpos": params.get_numeric(
3986+
"vm_sev_cbitpos", coco.sev.get_cbit_position()
3987+
),
3988+
"reduced-phys-bits": params.get_numeric(
3989+
"vm_sev_reduced_phys_bits", coco.sev.get_reduced_phys_bits()
3990+
),
39883991
}
39893992

39903993
if params.get("vm_sev_kernel_hashes"):

0 commit comments

Comments
 (0)