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