1 /* 2 * AMD SEV support in kvm-unit-tests 3 * 4 * Copyright (c) 2021, Google Inc 5 * 6 * Authors: 7 * Zixuan Wang <zixuanwang@google.com> 8 * 9 * SPDX-License-Identifier: LGPL-2.0-or-later 10 */ 11 12 #include "amd_sev.h" 13 #include "x86/processor.h" 14 15 static unsigned short amd_sev_c_bit_pos; 16 17 bool amd_sev_enabled(void) 18 { 19 struct cpuid cpuid_out; 20 static bool sev_enabled; 21 static bool initialized = false; 22 23 /* Check CPUID and MSR for SEV status and store it for future function calls. */ 24 if (!initialized) { 25 sev_enabled = false; 26 initialized = true; 27 28 /* Test if we can query SEV features */ 29 cpuid_out = cpuid(CPUID_FN_LARGEST_EXT_FUNC_NUM); 30 if (cpuid_out.a < CPUID_FN_ENCRYPT_MEM_CAPAB) { 31 return sev_enabled; 32 } 33 34 /* Test if SEV is supported */ 35 cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB); 36 if (!(cpuid_out.a & SEV_SUPPORT_MASK)) { 37 return sev_enabled; 38 } 39 40 /* Test if SEV is enabled */ 41 if (rdmsr(MSR_SEV_STATUS) & SEV_ENABLED_MASK) { 42 sev_enabled = true; 43 } 44 } 45 46 return sev_enabled; 47 } 48 49 efi_status_t setup_amd_sev(void) 50 { 51 struct cpuid cpuid_out; 52 53 if (!amd_sev_enabled()) { 54 return EFI_UNSUPPORTED; 55 } 56 57 /* 58 * Extract C-Bit position from ebx[5:0] 59 * AMD64 Architecture Programmer's Manual Volume 3 60 * - Section " Function 8000_001Fh - Encrypted Memory Capabilities" 61 */ 62 cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB); 63 amd_sev_c_bit_pos = (unsigned short)(cpuid_out.b & 0x3f); 64 65 return EFI_SUCCESS; 66 } 67 68 unsigned long long get_amd_sev_c_bit_mask(void) 69 { 70 if (amd_sev_enabled()) { 71 return 1ull << amd_sev_c_bit_pos; 72 } else { 73 return 0; 74 } 75 } 76