/* * AMD SEV support in kvm-unit-tests * * Copyright (c) 2021, Google Inc * * Authors: * Zixuan Wang * * SPDX-License-Identifier: LGPL-2.0-or-later */ #include "amd_sev.h" #include "x86/processor.h" static unsigned short amd_sev_c_bit_pos; bool amd_sev_enabled(void) { struct cpuid cpuid_out; static bool sev_enabled; static bool initialized = false; /* Check CPUID and MSR for SEV status and store it for future function calls. */ if (!initialized) { sev_enabled = false; initialized = true; /* Test if we can query SEV features */ cpuid_out = cpuid(CPUID_FN_LARGEST_EXT_FUNC_NUM); if (cpuid_out.a < CPUID_FN_ENCRYPT_MEM_CAPAB) { return sev_enabled; } /* Test if SEV is supported */ cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB); if (!(cpuid_out.a & SEV_SUPPORT_MASK)) { return sev_enabled; } /* Test if SEV is enabled */ if (rdmsr(MSR_SEV_STATUS) & SEV_ENABLED_MASK) { sev_enabled = true; } } return sev_enabled; } efi_status_t setup_amd_sev(void) { struct cpuid cpuid_out; if (!amd_sev_enabled()) { return EFI_UNSUPPORTED; } /* * Extract C-Bit position from ebx[5:0] * AMD64 Architecture Programmer's Manual Volume 3 * - Section " Function 8000_001Fh - Encrypted Memory Capabilities" */ cpuid_out = cpuid(CPUID_FN_ENCRYPT_MEM_CAPAB); amd_sev_c_bit_pos = (unsigned short)(cpuid_out.b & 0x3f); return EFI_SUCCESS; } unsigned long long get_amd_sev_c_bit_mask(void) { if (amd_sev_enabled()) { return 1ull << amd_sev_c_bit_pos; } else { return 0; } }