|
18 | 18 |
|
19 | 19 | from avocado.utils import cpu as utils |
20 | 20 |
|
21 | | -from virttest.cpu import cpuid |
| 21 | +from virttest.cpu import UnsupportedCPU, cpuid |
22 | 22 |
|
23 | 23 | LOG = logging.getLogger("avocado." + __name__) |
24 | 24 |
|
25 | 25 |
|
| 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 | + |
26 | 90 | def is_sev_snp_supported(): |
27 | 91 | """ |
28 | 92 | Check if AMD SEV-SNP (Secure Nested Paging) is supported. |
29 | 93 |
|
30 | 94 | :return: True if SEV-SNP is supported, False otherwise |
31 | 95 | """ |
32 | 96 | 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() |
44 | 98 | # Check SEV-SNP support bit (EAX bit 4) |
45 | 99 | return bool(eax & (1 << 4)) |
46 | | - except Exception: |
| 100 | + except UnsupportedCPU: |
47 | 101 | return False |
0 commit comments