1 | ;------------------------------------------------------------------------------
|
---|
2 | ; @file
|
---|
3 | ; Transition from 32 bit flat protected mode into 64 bit flat protected mode
|
---|
4 | ;
|
---|
5 | ; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
|
---|
6 | ; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
---|
7 | ; SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
8 | ;
|
---|
9 | ;------------------------------------------------------------------------------
|
---|
10 |
|
---|
11 | BITS 32
|
---|
12 |
|
---|
13 | ;
|
---|
14 | ; Modified: EAX, ECX, EDX
|
---|
15 | ;
|
---|
16 | Transition32FlatTo64Flat:
|
---|
17 |
|
---|
18 | OneTimeCall SetCr3ForPageTables64
|
---|
19 |
|
---|
20 | mov eax, cr4
|
---|
21 | bts eax, 5 ; enable PAE
|
---|
22 | mov cr4, eax
|
---|
23 |
|
---|
24 | ;
|
---|
25 | ; In TDX LME has already been set. So we're done and jump to enable
|
---|
26 | ; paging directly if Tdx is enabled.
|
---|
27 | ; EBX is cleared because in the later it will be used to check if
|
---|
28 | ; the second step of the SEV-ES mitigation is to be performed.
|
---|
29 | ;
|
---|
30 | xor ebx, ebx
|
---|
31 | OneTimeCall IsTdxEnabled
|
---|
32 | test eax, eax
|
---|
33 | jnz EnablePaging
|
---|
34 |
|
---|
35 | mov ecx, 0xc0000080
|
---|
36 | rdmsr
|
---|
37 | bts eax, 8 ; set LME
|
---|
38 | wrmsr
|
---|
39 |
|
---|
40 | ;
|
---|
41 | ; SEV-ES mitigation check support
|
---|
42 | ;
|
---|
43 | xor ebx, ebx
|
---|
44 |
|
---|
45 | mov ecx, 1
|
---|
46 | bt [SEV_ES_WORK_AREA_STATUS_MSR], ecx
|
---|
47 | jnc EnablePaging
|
---|
48 |
|
---|
49 | ;
|
---|
50 | ; SEV-ES is active, perform a quick sanity check against the reported
|
---|
51 | ; encryption bit position. This is to help mitigate against attacks where
|
---|
52 | ; the hypervisor reports an incorrect encryption bit position.
|
---|
53 | ;
|
---|
54 | ; This is the first step in a two step process. Before paging is enabled
|
---|
55 | ; writes to memory are encrypted. Using the RDRAND instruction (available
|
---|
56 | ; on all SEV capable processors), write 64-bits of random data to the
|
---|
57 | ; SEV_ES_WORK_AREA and maintain the random data in registers (register
|
---|
58 | ; state is protected under SEV-ES). This will be used in the second step.
|
---|
59 | ;
|
---|
60 | RdRand1:
|
---|
61 | rdrand ecx
|
---|
62 | jnc RdRand1
|
---|
63 | mov dword[SEV_ES_WORK_AREA_RDRAND], ecx
|
---|
64 | RdRand2:
|
---|
65 | rdrand edx
|
---|
66 | jnc RdRand2
|
---|
67 | mov dword[SEV_ES_WORK_AREA_RDRAND + 4], edx
|
---|
68 |
|
---|
69 | ;
|
---|
70 | ; Use EBX instead of the SEV_ES_WORK_AREA memory to determine whether to
|
---|
71 | ; perform the second step.
|
---|
72 | ;
|
---|
73 | mov ebx, 1
|
---|
74 |
|
---|
75 | EnablePaging:
|
---|
76 | mov eax, cr0
|
---|
77 | bts eax, 31 ; set PG
|
---|
78 | mov cr0, eax ; enable paging
|
---|
79 |
|
---|
80 | jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)
|
---|
81 | BITS 64
|
---|
82 | jumpTo64BitAndLandHere:
|
---|
83 |
|
---|
84 | ;
|
---|
85 | ; Check if the second step of the SEV-ES mitigation is to be performed.
|
---|
86 | ;
|
---|
87 | test ebx, ebx
|
---|
88 | jz InsnCompare
|
---|
89 |
|
---|
90 | ;
|
---|
91 | ; SEV-ES is active, perform the second step of the encryption bit postion
|
---|
92 | ; mitigation check. The ECX and EDX register contain data from RDRAND that
|
---|
93 | ; was stored to memory in encrypted form. If the encryption bit position is
|
---|
94 | ; valid, the contents of ECX and EDX will match the memory location.
|
---|
95 | ;
|
---|
96 | cmp dword[SEV_ES_WORK_AREA_RDRAND], ecx
|
---|
97 | jne SevEncBitHlt
|
---|
98 | cmp dword[SEV_ES_WORK_AREA_RDRAND + 4], edx
|
---|
99 | jne SevEncBitHlt
|
---|
100 |
|
---|
101 | ;
|
---|
102 | ; If SEV or SEV-ES is active, perform a quick sanity check against
|
---|
103 | ; the reported encryption bit position. This is to help mitigate
|
---|
104 | ; against attacks where the hypervisor reports an incorrect encryption
|
---|
105 | ; bit position. If SEV is not active, this check will always succeed.
|
---|
106 | ;
|
---|
107 | ; The cmp instruction compares the first four bytes of the cmp instruction
|
---|
108 | ; itself (which will be read decrypted if SEV or SEV-ES is active and the
|
---|
109 | ; encryption bit position is valid) against the immediate within the
|
---|
110 | ; instruction (an instruction fetch is always decrypted correctly by
|
---|
111 | ; hardware) based on RIP relative addressing.
|
---|
112 | ;
|
---|
113 | InsnCompare:
|
---|
114 | cmp dword[rel InsnCompare], 0xFFF63D81
|
---|
115 | je GoodCompare
|
---|
116 |
|
---|
117 | ;
|
---|
118 | ; The hypervisor provided an incorrect encryption bit position, do not
|
---|
119 | ; proceed.
|
---|
120 | ;
|
---|
121 | SevEncBitHlt:
|
---|
122 | cli
|
---|
123 | hlt
|
---|
124 | jmp SevEncBitHlt
|
---|
125 |
|
---|
126 | GoodCompare:
|
---|
127 | debugShowPostCode POSTCODE_64BIT_MODE
|
---|
128 |
|
---|
129 | OneTimeCallRet Transition32FlatTo64Flat
|
---|
130 |
|
---|