Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux...
[sfrench/cifs-2.6.git] / arch / x86 / boot / compressed / mem_encrypt.S
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
18 SYM_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
68 SYM_FUNC_END(get_sev_encryption_bit)
69
70         .code64
71 SYM_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
93 SYM_FUNC_END(set_sev_encryption_mask)
94
95         .data
96
97 #ifdef CONFIG_AMD_MEM_ENCRYPT
98         .balign 8
99 SYM_DATA(sme_me_mask, .quad 0)
100 #endif