movl $0x80000000, %eax /* CPUID to check the highest leaf */
cpuid
cmpl $0x8000001f, %eax /* See if 0x8000001f is available */
jb .Lno_sev
/* * Check for the SEV feature: * CPUID Fn8000_001F[EAX] - Bit 1 * CPUID Fn8000_001F[EBX] - Bits 5:0 * Pagetable bit position used to indicate encryption
*/
movl $0x8000001f, %eax
cpuid
bt $1, %eax /* Check if SEV is available */
jnc .Lno_sev
movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */
rdmsr
bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */
jnc .Lno_sev
movl %ebx, %eax
andl $0x3f, %eax /* Return the encryption bit location */
jmp .Lsev_exit
.Lno_sev:
xor %eax, %eax
.Lsev_exit:
pop %ebx
RET
SYM_FUNC_END(get_sev_encryption_bit)
/** * sev_es_req_cpuid - Request a CPUID value from the Hypervisor using * the GHCB MSR protocol * * @%eax: Register to request (0=EAX, 1=EBX, 2=ECX, 3=EDX) * @%edx: CPUID Function * * Returns 0 in %eax on success, non-zero on failure * %edx returns CPUID value on success
*/
SYM_CODE_START_LOCAL(sev_es_req_cpuid)
shll $30, %eax
orl $0x00000004, %eax
movl $MSR_AMD64_SEV_ES_GHCB, %ecx
wrmsr
rep; vmmcall # VMGEXIT
rdmsr
pop %ebx
pop %ebp
RET
SYM_FUNC_END(startup32_load_idt)
/* * Check for the correct C-bit position when the startup_32 boot-path is used. * * The check makes use of the fact that all memory is encrypted when paging is * disabled. The function creates 64 bits of random data using the RDRAND * instruction. RDRAND is mandatory for SEV guests, so always available. If the * hypervisor violates that the kernel will crash right here. * * The 64 bits of random data are stored to a memory location and at the same * time kept in the %eax and %ebx registers. Since encryption is always active * when paging is off the random data will be stored encrypted in main memory. * * Then paging is enabled. When the C-bit position is correct all memory is * still mapped encrypted and comparing the register values with memory will * succeed. An incorrect C-bit position will map all memory unencrypted, so that * the compare will use the encrypted random data and fail.
*/
SYM_FUNC_START(startup32_check_sev_cbit)
pushl %ebx
pushl %ebp
/* * Get two 32-bit random values - Don't bail out if RDRAND fails * because it is better to prevent forward progress if no random value * can be gathered.
*/
1: rdrand %eax
jnc 1b
2: rdrand %ebx
jnc 2b
/* Store to memory and keep it in the registers */
leal (sev_check_data - 0b)(%ebp), %ebp
movl %eax, 0(%ebp)
movl %ebx, 4(%ebp)
/* Enable paging to see if encryption is active */
movl %cr0, %edx /* Backup %cr0 in %edx */
movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
movl %ecx, %cr0
cmpl %eax, 0(%ebp)
jne 3f
cmpl %ebx, 4(%ebp)
jne 3f
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.