/* SPDX-License-Identifier: GPL-2.0-only */ /* * AMD Memory Encryption Support * * Copyright (C) 2017 Advanced Micro Devices, Inc. * * Author: Tom Lendacky */ #include #include #include #include .text .code32 SYM_FUNC_START(get_sev_encryption_bit) xor %eax, %eax #ifdef CONFIG_AMD_MEM_ENCRYPT push %ebx push %ecx push %edx /* Check if running under a hypervisor */ movl $1, %eax cpuid bt $31, %ecx /* Check the hypervisor bit */ jnc .Lno_sev 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 %edx pop %ecx pop %ebx #endif /* CONFIG_AMD_MEM_ENCRYPT */ ret SYM_FUNC_END(get_sev_encryption_bit) .code64 #include "../../kernel/sev_verify_cbit.S" SYM_FUNC_START(set_sev_encryption_mask) #ifdef CONFIG_AMD_MEM_ENCRYPT push %rbp push %rdx movq %rsp, %rbp /* Save current stack pointer */ call get_sev_encryption_bit /* Get the encryption bit position */ testl %eax, %eax jz .Lno_sev_mask bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ /* * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in * get_sev_encryption_bit() because this function is 32-bit code and * shared between 64-bit and 32-bit boot path. */ movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ rdmsr /* Store MSR value in sev_status */ shlq $32, %rdx orq %rdx, %rax movq %rax, sev_status(%rip) .Lno_sev_mask: movq %rbp, %rsp /* Restore original stack pointer */ pop %rdx pop %rbp #endif xor %rax, %rax ret SYM_FUNC_END(set_sev_encryption_mask) .data #ifdef CONFIG_AMD_MEM_ENCRYPT .balign 8 SYM_DATA(sme_me_mask, .quad 0) SYM_DATA(sev_status, .quad 0) SYM_DATA(sev_check_data, .quad 0) #endif