Merge tag 'arm-soc-drivers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.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
72 #include "../../kernel/sev_verify_cbit.S"
73
74 SYM_FUNC_START(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         /*
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.
91          */
92         movl    $MSR_AMD64_SEV, %ecx    /* Read the SEV MSR */
93         rdmsr
94
95         /* Store MSR value in sev_status */
96         shlq    $32, %rdx
97         orq     %rdx, %rax
98         movq    %rax, sev_status(%rip)
99
100 .Lno_sev_mask:
101         movq    %rbp, %rsp              /* Restore original stack pointer */
102
103         pop     %rdx
104         pop     %rbp
105 #endif
106
107         xor     %rax, %rax
108         ret
109 SYM_FUNC_END(set_sev_encryption_mask)
110
111         .data
112
113 #ifdef CONFIG_AMD_MEM_ENCRYPT
114         .balign 8
115 SYM_DATA(sme_me_mask,           .quad 0)
116 SYM_DATA(sev_status,            .quad 0)
117 SYM_DATA(sev_check_data,        .quad 0)
118 #endif