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