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