1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * AMD Memory Encryption Support
5 * Copyright (C) 2017 Advanced Micro Devices, Inc.
7 * Author: Tom Lendacky <thomas.lendacky@amd.com>
10 #include <linux/linkage.h>
12 #include <asm/processor-flags.h>
14 #include <asm/asm-offsets.h>
18 SYM_FUNC_START(get_sev_encryption_bit)
21 #ifdef CONFIG_AMD_MEM_ENCRYPT
26 /* Check if running under a hypervisor */
29 bt $31, %ecx /* Check the hypervisor bit */
32 movl $0x80000000, %eax /* CPUID to check the highest leaf */
34 cmpl $0x8000001f, %eax /* See if 0x8000001f is available */
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
43 movl $0x8000001f, %eax
45 bt $1, %eax /* Check if SEV is available */
48 movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */
50 bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */
54 andl $0x3f, %eax /* Return the encryption bit location */
65 #endif /* CONFIG_AMD_MEM_ENCRYPT */
68 SYM_FUNC_END(get_sev_encryption_bit)
72 #include "../../kernel/sev_verify_cbit.S"
74 SYM_FUNC_START(set_sev_encryption_mask)
75 #ifdef CONFIG_AMD_MEM_ENCRYPT
79 movq %rsp, %rbp /* Save current stack pointer */
81 call get_sev_encryption_bit /* Get the encryption bit position */
85 bts %rax, sme_me_mask(%rip) /* Create the encryption mask */
88 * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in
89 * get_sev_encryption_bit() because this function is 32-bit code and
90 * shared between 64-bit and 32-bit boot path.
92 movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */
95 /* Store MSR value in sev_status */
98 movq %rax, sev_status(%rip)
101 movq %rbp, %rsp /* Restore original stack pointer */
109 SYM_FUNC_END(set_sev_encryption_mask)
113 #ifdef CONFIG_AMD_MEM_ENCRYPT
115 SYM_DATA(sme_me_mask, .quad 0)
116 SYM_DATA(sev_status, .quad 0)
117 SYM_DATA(sev_check_data, .quad 0)