]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm
UefiCpuPkg/SmmCpuFeaturesLib: [CVE-2017-5715] Stuff RSB before RSM
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / Ia32 / SmiEntry.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
7 ;
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 ;
11 ; Module Name:
12 ;
13 ; SmiEntry.nasm
14 ;
15 ; Abstract:
16 ;
17 ; Code template of the SMI handler for a particular processor
18 ;
19 ;-------------------------------------------------------------------------------
20
21 %include "StuffRsb.inc"
22
23 %define MSR_IA32_MISC_ENABLE 0x1A0
24 %define MSR_EFER 0xc0000080
25 %define MSR_EFER_XD 0x800
26
27 ;
28 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
29 ;
30 %define DSC_OFFSET 0xfb00
31 %define DSC_GDTPTR 0x48
32 %define DSC_GDTSIZ 0x50
33 %define DSC_CS 0x14
34 %define DSC_DS 0x16
35 %define DSC_SS 0x18
36 %define DSC_OTHERSEG 0x1a
37
38 %define PROTECT_MODE_CS 0x8
39 %define PROTECT_MODE_DS 0x20
40 %define TSS_SEGMENT 0x40
41
42 extern ASM_PFX(SmiRendezvous)
43 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
44 extern ASM_PFX(CpuSmmDebugEntry)
45 extern ASM_PFX(CpuSmmDebugExit)
46
47 global ASM_PFX(gcStmSmiHandlerTemplate)
48 global ASM_PFX(gcStmSmiHandlerSize)
49 global ASM_PFX(gcStmSmiHandlerOffset)
50 global ASM_PFX(gStmSmiCr3)
51 global ASM_PFX(gStmSmiStack)
52 global ASM_PFX(gStmSmbase)
53 global ASM_PFX(gStmXdSupported)
54 extern ASM_PFX(gStmSmiHandlerIdtr)
55
56 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
57 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
58 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
59 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
60
61 SECTION .text
62
63 BITS 16
64 ASM_PFX(gcStmSmiHandlerTemplate):
65 _StmSmiEntryPoint:
66 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
67 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
68 dec ax
69 mov [cs:bx], ax
70 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
71 mov [cs:bx + 2], eax
72 mov ebp, eax ; ebp = GDT base
73 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
74 mov ax, PROTECT_MODE_CS
75 mov [cs:bx-0x2],ax
76 o32 mov edi, strict dword 0
77 StmSmbasePatch:
78 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]
79 mov [cs:bx-0x6],eax
80 mov ebx, cr0
81 and ebx, 0x9ffafff3
82 or ebx, 0x23
83 mov cr0, ebx
84 jmp dword 0x0:0x0
85 _StmGdtDesc:
86 DW 0
87 DD 0
88
89 BITS 32
90 @32bit:
91 mov ax, PROTECT_MODE_DS
92 o16 mov ds, ax
93 o16 mov es, ax
94 o16 mov fs, ax
95 o16 mov gs, ax
96 o16 mov ss, ax
97 mov esp, strict dword 0
98 StmSmiStackPatch:
99 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
100 lidt [eax]
101 jmp ProtFlatMode
102
103 ProtFlatMode:
104 mov eax, strict dword 0
105 StmSmiCr3Patch:
106 mov cr3, eax
107 ;
108 ; Need to test for CR4 specific bit support
109 ;
110 mov eax, 1
111 cpuid ; use CPUID to determine if specific CR4 bits are supported
112 xor eax, eax ; Clear EAX
113 test edx, BIT2 ; Check for DE capabilities
114 jz .0
115 or eax, BIT3
116 .0:
117 test edx, BIT6 ; Check for PAE capabilities
118 jz .1
119 or eax, BIT5
120 .1:
121 test edx, BIT7 ; Check for MCE capabilities
122 jz .2
123 or eax, BIT6
124 .2:
125 test edx, BIT24 ; Check for FXSR capabilities
126 jz .3
127 or eax, BIT9
128 .3:
129 test edx, BIT25 ; Check for SSE capabilities
130 jz .4
131 or eax, BIT10
132 .4: ; as cr4.PGE is not set here, refresh cr3
133 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
134
135 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
136 jz .6
137 ; Load TSS
138 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
139 mov eax, TSS_SEGMENT
140 ltr ax
141 .6:
142
143 ; enable NXE if supported
144 mov al, strict byte 1
145 StmXdSupportedPatch:
146 cmp al, 0
147 jz @SkipXd
148 ;
149 ; Check XD disable bit
150 ;
151 mov ecx, MSR_IA32_MISC_ENABLE
152 rdmsr
153 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
154 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
155 jz .5
156 and dx, 0xFFFB ; clear XD Disable bit if it is set
157 wrmsr
158 .5:
159 mov ecx, MSR_EFER
160 rdmsr
161 or ax, MSR_EFER_XD ; enable NXE
162 wrmsr
163 jmp @XdDone
164 @SkipXd:
165 sub esp, 4
166 @XdDone:
167
168 mov ebx, cr0
169 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
170 mov cr0, ebx
171 lea ebx, [edi + DSC_OFFSET]
172 mov ax, [ebx + DSC_DS]
173 mov ds, eax
174 mov ax, [ebx + DSC_OTHERSEG]
175 mov es, eax
176 mov fs, eax
177 mov gs, eax
178 mov ax, [ebx + DSC_SS]
179 mov ss, eax
180
181 CommonHandler:
182 mov ebx, [esp + 4] ; CPU Index
183 push ebx
184 mov eax, ASM_PFX(CpuSmmDebugEntry)
185 call eax
186 add esp, 4
187
188 push ebx
189 mov eax, ASM_PFX(SmiRendezvous)
190 call eax
191 add esp, 4
192
193 push ebx
194 mov eax, ASM_PFX(CpuSmmDebugExit)
195 call eax
196 add esp, 4
197
198 mov eax, ASM_PFX(gStmXdSupported)
199 mov al, [eax]
200 cmp al, 0
201 jz .7
202 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
203 test edx, BIT2
204 jz .7
205 mov ecx, MSR_IA32_MISC_ENABLE
206 rdmsr
207 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
208 wrmsr
209
210 .7:
211 StuffRsb32
212 rsm
213
214
215 _StmSmiHandler:
216 ;
217 ; Check XD disable bit
218 ;
219 xor esi, esi
220 mov eax, ASM_PFX(gStmXdSupported)
221 mov al, [eax]
222 cmp al, 0
223 jz @StmXdDone
224 mov ecx, MSR_IA32_MISC_ENABLE
225 rdmsr
226 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
227 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
228 jz .5
229 and dx, 0xFFFB ; clear XD Disable bit if it is set
230 wrmsr
231 .5:
232 mov ecx, MSR_EFER
233 rdmsr
234 or ax, MSR_EFER_XD ; enable NXE
235 wrmsr
236 @StmXdDone:
237 push esi
238
239 ; below step is needed, because STM does not run above code.
240 ; we have to run below code to set IDT/CR0/CR4
241 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
242 lidt [eax]
243
244 mov eax, cr0
245 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
246 mov cr0, eax
247 ;
248 ; Need to test for CR4 specific bit support
249 ;
250 mov eax, 1
251 cpuid ; use CPUID to determine if specific CR4 bits are supported
252 mov eax, cr4 ; init EAX
253 test edx, BIT2 ; Check for DE capabilities
254 jz .0
255 or eax, BIT3
256 .0:
257 test edx, BIT6 ; Check for PAE capabilities
258 jz .1
259 or eax, BIT5
260 .1:
261 test edx, BIT7 ; Check for MCE capabilities
262 jz .2
263 or eax, BIT6
264 .2:
265 test edx, BIT24 ; Check for FXSR capabilities
266 jz .3
267 or eax, BIT9
268 .3:
269 test edx, BIT25 ; Check for SSE capabilities
270 jz .4
271 or eax, BIT10
272 .4: ; as cr4.PGE is not set here, refresh cr3
273 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
274 ; STM init finish
275 jmp CommonHandler
276
277 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
278 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint
279
280 global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)
281 ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):
282 ret