blob: 6afb7130a38791570441d98b18fe2216306dbe26 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Tom Lendacky1958b5f2017-10-20 09:30:54 -05002/*
3 * AMD Memory Encryption Support
4 *
5 * Copyright (C) 2017 Advanced Micro Devices, Inc.
6 *
7 * Author: Tom Lendacky <thomas.lendacky@amd.com>
Tom Lendacky1958b5f2017-10-20 09:30:54 -05008 */
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
18ENTRY(get_sev_encryption_bit)
19 xor %eax, %eax
20
21#ifdef CONFIG_AMD_MEM_ENCRYPT
22 push %ebx
23 push %ecx
24 push %edx
Tom Lendacky1958b5f2017-10-20 09:30:54 -050025
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 */
Tom Lendacky1958b5f2017-10-20 09:30:54 -050055 jmp .Lsev_exit
56
57.Lno_sev:
58 xor %eax, %eax
Tom Lendacky1958b5f2017-10-20 09:30:54 -050059
60.Lsev_exit:
Tom Lendacky1958b5f2017-10-20 09:30:54 -050061 pop %edx
62 pop %ecx
63 pop %ebx
64
65#endif /* CONFIG_AMD_MEM_ENCRYPT */
66
67 ret
68ENDPROC(get_sev_encryption_bit)
69
70 .code64
Tom Lendacky07344b12018-03-27 17:07:11 -050071ENTRY(set_sev_encryption_mask)
Tom Lendacky1958b5f2017-10-20 09:30:54 -050072#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
Tom Lendacky07344b12018-03-27 17:07:11 -050082 bts %rax, sme_me_mask(%rip) /* Create the encryption mask */
Tom Lendacky1958b5f2017-10-20 09:30:54 -050083
84.Lno_sev_mask:
85 movq %rbp, %rsp /* Restore original stack pointer */
86
87 pop %rdx
88 pop %rbp
89#endif
90
Tom Lendacky07344b12018-03-27 17:07:11 -050091 xor %rax, %rax
Tom Lendacky1958b5f2017-10-20 09:30:54 -050092 ret
Tom Lendacky07344b12018-03-27 17:07:11 -050093ENDPROC(set_sev_encryption_mask)
Tom Lendacky1958b5f2017-10-20 09:30:54 -050094
95 .data
Tom Lendacky07344b12018-03-27 17:07:11 -050096
97#ifdef CONFIG_AMD_MEM_ENCRYPT
98 .balign 8
99GLOBAL(sme_me_mask)
100 .quad 0
101#endif