1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * AMD Memory Encryption Support 4 * 5 * Copyright (C) 2017 Advanced Micro Devices, Inc. 6 * 7 * Author: Tom Lendacky <thomas.lendacky@amd.com> 8 */ 9 10#include <linux/linkage.h> 11 12#include <asm/processor-flags.h> 13#include <asm/msr.h> 14#include <asm/asm-offsets.h> 15 16 .text 17 .code32 18SYM_FUNC_START(get_sev_encryption_bit) 19 xor %eax, %eax 20 21#ifdef CONFIG_AMD_MEM_ENCRYPT 22 push %ebx 23 push %ecx 24 push %edx 25 26 /* Check if running under a hypervisor */ 27 movl $1, %eax 28 cpuid 29 bt $31, %ecx /* Check the hypervisor bit */ 30 jnc .Lno_sev 31 32 movl $0x80000000, %eax /* CPUID to check the highest leaf */ 33 cpuid 34 cmpl $0x8000001f, %eax /* See if 0x8000001f is available */ 35 jb .Lno_sev 36 37 /* 38 * Check for the SEV feature: 39 * CPUID Fn8000_001F[EAX] - Bit 1 40 * CPUID Fn8000_001F[EBX] - Bits 5:0 41 * Pagetable bit position used to indicate encryption 42 */ 43 movl $0x8000001f, %eax 44 cpuid 45 bt $1, %eax /* Check if SEV is available */ 46 jnc .Lno_sev 47 48 movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ 49 rdmsr 50 bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */ 51 jnc .Lno_sev 52 53 movl %ebx, %eax 54 andl $0x3f, %eax /* Return the encryption bit location */ 55 jmp .Lsev_exit 56 57.Lno_sev: 58 xor %eax, %eax 59 60.Lsev_exit: 61 pop %edx 62 pop %ecx 63 pop %ebx 64 65#endif /* CONFIG_AMD_MEM_ENCRYPT */ 66 67 ret 68SYM_FUNC_END(get_sev_encryption_bit) 69 70 .code64 71SYM_FUNC_START(set_sev_encryption_mask) 72#ifdef CONFIG_AMD_MEM_ENCRYPT 73 push %rbp 74 push %rdx 75 76 movq %rsp, %rbp /* Save current stack pointer */ 77 78 call get_sev_encryption_bit /* Get the encryption bit position */ 79 testl %eax, %eax 80 jz .Lno_sev_mask 81 82 bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ 83 84.Lno_sev_mask: 85 movq %rbp, %rsp /* Restore original stack pointer */ 86 87 pop %rdx 88 pop %rbp 89#endif 90 91 xor %rax, %rax 92 ret 93SYM_FUNC_END(set_sev_encryption_mask) 94 95 .data 96 97#ifdef CONFIG_AMD_MEM_ENCRYPT 98 .balign 8 99SYM_DATA(sme_me_mask, .quad 0) 100#endif 101