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 movl $0x80000000, %eax /* CPUID to check the highest leaf */ 27 cpuid 28 cmpl $0x8000001f, %eax /* See if 0x8000001f is available */ 29 jb .Lno_sev 30 31 /* 32 * Check for the SEV feature: 33 * CPUID Fn8000_001F[EAX] - Bit 1 34 * CPUID Fn8000_001F[EBX] - Bits 5:0 35 * Pagetable bit position used to indicate encryption 36 */ 37 movl $0x8000001f, %eax 38 cpuid 39 bt $1, %eax /* Check if SEV is available */ 40 jnc .Lno_sev 41 42 movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ 43 rdmsr 44 bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */ 45 jnc .Lno_sev 46 47 movl %ebx, %eax 48 andl $0x3f, %eax /* Return the encryption bit location */ 49 jmp .Lsev_exit 50 51.Lno_sev: 52 xor %eax, %eax 53 54.Lsev_exit: 55 pop %edx 56 pop %ecx 57 pop %ebx 58 59#endif /* CONFIG_AMD_MEM_ENCRYPT */ 60 61 RET 62SYM_FUNC_END(get_sev_encryption_bit) 63 64 .code64 65 66#include "../../kernel/sev_verify_cbit.S" 67 68SYM_FUNC_START(set_sev_encryption_mask) 69#ifdef CONFIG_AMD_MEM_ENCRYPT 70 push %rbp 71 push %rdx 72 73 movq %rsp, %rbp /* Save current stack pointer */ 74 75 call get_sev_encryption_bit /* Get the encryption bit position */ 76 testl %eax, %eax 77 jz .Lno_sev_mask 78 79 bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ 80 81 /* 82 * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in 83 * get_sev_encryption_bit() because this function is 32-bit code and 84 * shared between 64-bit and 32-bit boot path. 85 */ 86 movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ 87 rdmsr 88 89 /* Store MSR value in sev_status */ 90 shlq $32, %rdx 91 orq %rdx, %rax 92 movq %rax, sev_status(%rip) 93 94.Lno_sev_mask: 95 movq %rbp, %rsp /* Restore original stack pointer */ 96 97 pop %rdx 98 pop %rbp 99#endif 100 101 xor %rax, %rax 102 RET 103SYM_FUNC_END(set_sev_encryption_mask) 104 105 .data 106 107#ifdef CONFIG_AMD_MEM_ENCRYPT 108 .balign 8 109SYM_DATA(sme_me_mask, .quad 0) 110SYM_DATA(sev_status, .quad 0) 111SYM_DATA(sev_check_data, .quad 0) 112#endif 113