]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm
UefiCpuPkg/PiSmmCpuDxeSmm: [CVE-2017-5715] Stuff RSB before RSM
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.nasm
CommitLineData
9a36d4dc 1;------------------------------------------------------------------------------ ;\r
e21e355e 2; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
9a36d4dc
LG
3; This program and the accompanying materials\r
4; are licensed and made available under the terms and conditions of the BSD License\r
5; which accompanies this distribution. The full text of the license may be found at\r
6; http://opensource.org/licenses/bsd-license.php.\r
7;\r
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10;\r
11; Module Name:\r
12;\r
13; SmiEntry.nasm\r
14;\r
15; Abstract:\r
16;\r
17; Code template of the SMI handler for a particular processor\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
02f7fd15
HW
21%include "StuffRsb.inc"\r
22\r
9a36d4dc
LG
23;\r
24; Variables referrenced by C code\r
25;\r
26\r
717fb604
JY
27%define MSR_IA32_MISC_ENABLE 0x1A0\r
28%define MSR_EFER 0xc0000080\r
29%define MSR_EFER_XD 0x800\r
30\r
9a36d4dc
LG
31;\r
32; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
33;\r
34%define DSC_OFFSET 0xfb00\r
35%define DSC_GDTPTR 0x30\r
36%define DSC_GDTSIZ 0x38\r
37%define DSC_CS 14\r
38%define DSC_DS 16\r
39%define DSC_SS 18\r
40%define DSC_OTHERSEG 20\r
41;\r
42; Constants relating to CPU State Save Area\r
43;\r
44%define SSM_DR6 0xffd0\r
45%define SSM_DR7 0xffc8\r
46\r
47%define PROTECT_MODE_CS 0x8\r
48%define PROTECT_MODE_DS 0x20\r
49%define LONG_MODE_CS 0x38\r
50%define TSS_SEGMENT 0x40\r
51%define GDT_SIZE 0x50\r
52\r
53extern ASM_PFX(SmiRendezvous)\r
54extern ASM_PFX(gSmiHandlerIdtr)\r
55extern ASM_PFX(CpuSmmDebugEntry)\r
56extern ASM_PFX(CpuSmmDebugExit)\r
57\r
5a1bfda4 58global ASM_PFX(gPatchSmbase)\r
3c5ce64f
LE
59extern ASM_PFX(mXdSupported)\r
60global ASM_PFX(gPatchXdSupported)\r
fc504fde 61global ASM_PFX(gPatchSmiStack)\r
c455687f 62global ASM_PFX(gPatchSmiCr3)\r
9a36d4dc
LG
63global ASM_PFX(gcSmiHandlerTemplate)\r
64global ASM_PFX(gcSmiHandlerSize)\r
65\r
66 DEFAULT REL\r
67 SECTION .text\r
68\r
69BITS 16\r
70ASM_PFX(gcSmiHandlerTemplate):\r
71_SmiEntryPoint:\r
72 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000\r
73 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
74 dec ax\r
75 mov [cs:bx], ax\r
76 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
77 mov [cs:bx + 2], eax\r
78o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
79 mov ax, PROTECT_MODE_CS\r
717fb604 80 mov [cs:bx-0x2],ax\r
5a1bfda4
LE
81 mov edi, strict dword 0 ; source operand will be patched\r
82ASM_PFX(gPatchSmbase):\r
9a36d4dc
LG
83 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]\r
84 mov [cs:bx-0x6],eax\r
85 mov ebx, cr0\r
86 and ebx, 0x9ffafff3\r
87 or ebx, 0x23\r
88 mov cr0, ebx\r
89 jmp dword 0x0:0x0\r
717fb604 90_GdtDesc:\r
9a36d4dc
LG
91 DW 0\r
92 DD 0\r
93\r
94BITS 32\r
95@ProtectedMode:\r
96 mov ax, PROTECT_MODE_DS\r
97o16 mov ds, ax\r
98o16 mov es, ax\r
99o16 mov fs, ax\r
100o16 mov gs, ax\r
101o16 mov ss, ax\r
fc504fde
LE
102 mov esp, strict dword 0 ; source operand will be patched\r
103ASM_PFX(gPatchSmiStack):\r
9a36d4dc
LG
104 jmp ProtFlatMode\r
105\r
106BITS 64\r
107ProtFlatMode:\r
c455687f
LE
108 mov eax, strict dword 0 ; source operand will be patched\r
109ASM_PFX(gPatchSmiCr3):\r
9a36d4dc
LG
110 mov cr3, rax\r
111 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3\r
112 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
113; Load TSS\r
114 sub esp, 8 ; reserve room in stack\r
115 sgdt [rsp]\r
116 mov eax, [rsp + 2] ; eax = GDT base\r
117 add esp, 8\r
118 mov dl, 0x89\r
119 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
120 mov eax, TSS_SEGMENT\r
121 ltr ax\r
122\r
717fb604 123; enable NXE if supported\r
3c5ce64f
LE
124 mov al, strict byte 1 ; source operand may be patched\r
125ASM_PFX(gPatchXdSupported):\r
717fb604
JY
126 cmp al, 0\r
127 jz @SkipXd\r
128;\r
129; Check XD disable bit\r
130;\r
131 mov ecx, MSR_IA32_MISC_ENABLE\r
132 rdmsr\r
133 sub esp, 4\r
134 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]\r
135 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
136 jz .0\r
137 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
138 wrmsr\r
139.0:\r
140 mov ecx, MSR_EFER\r
141 rdmsr\r
142 or ax, MSR_EFER_XD ; enable NXE\r
143 wrmsr\r
144 jmp @XdDone\r
145@SkipXd:\r
146 sub esp, 8\r
147@XdDone:\r
148\r
9a36d4dc
LG
149; Switch into @LongMode\r
150 push LONG_MODE_CS ; push cs hardcore here\r
717fb604 151 call Base ; push return address for retf later\r
9a36d4dc
LG
152Base:\r
153 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
717fb604
JY
154\r
155 mov ecx, MSR_EFER\r
9a36d4dc 156 rdmsr\r
717fb604 157 or ah, 1 ; enable LME\r
9a36d4dc
LG
158 wrmsr\r
159 mov rbx, cr0\r
717fb604 160 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
9a36d4dc
LG
161 mov cr0, rbx\r
162 retf\r
163@LongMode: ; long mode (64-bit code) starts here\r
e21e355e
LG
164 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)\r
165SmiHandlerIdtrAbsAddr:\r
9a36d4dc
LG
166 lidt [rax]\r
167 lea ebx, [rdi + DSC_OFFSET]\r
168 mov ax, [rbx + DSC_DS]\r
169 mov ds, eax\r
170 mov ax, [rbx + DSC_OTHERSEG]\r
171 mov es, eax\r
172 mov fs, eax\r
173 mov gs, eax\r
174 mov ax, [rbx + DSC_SS]\r
175 mov ss, eax\r
e21e355e
LG
176 mov rax, strict qword 0 ; mov rax, _SmiHandler\r
177_SmiHandlerAbsAddr:\r
178 jmp rax\r
9a36d4dc
LG
179\r
180_SmiHandler:\r
717fb604 181 mov rbx, [rsp + 0x8] ; rcx <- CpuIndex\r
9a36d4dc
LG
182\r
183 ;\r
184 ; Save FP registers\r
185 ;\r
717fb604 186 sub rsp, 0x200\r
d22c995a 187 fxsave64 [rsp]\r
9a36d4dc
LG
188\r
189 add rsp, -0x20\r
190\r
191 mov rcx, rbx\r
e21e355e 192 call ASM_PFX(CpuSmmDebugEntry)\r
717fb604 193\r
9a36d4dc 194 mov rcx, rbx\r
e21e355e 195 call ASM_PFX(SmiRendezvous)\r
717fb604 196\r
9a36d4dc 197 mov rcx, rbx\r
e21e355e 198 call ASM_PFX(CpuSmmDebugExit)\r
717fb604 199\r
9a36d4dc
LG
200 add rsp, 0x20\r
201\r
202 ;\r
203 ; Restore FP registers\r
204 ;\r
d22c995a 205 fxrstor64 [rsp]\r
9a36d4dc 206\r
717fb604
JY
207 add rsp, 0x200\r
208\r
e21e355e 209 lea rax, [ASM_PFX(mXdSupported)]\r
717fb604
JY
210 mov al, [rax]\r
211 cmp al, 0\r
212 jz .1\r
213 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
214 test edx, BIT2\r
215 jz .1\r
216 mov ecx, MSR_IA32_MISC_ENABLE\r
217 rdmsr\r
218 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
219 wrmsr\r
220\r
221.1:\r
02f7fd15 222 StuffRsb64\r
9a36d4dc
LG
223 rsm\r
224\r
8764ed57 225ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint\r
9a36d4dc 226\r
e21e355e
LG
227global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)\r
228ASM_PFX(PiSmmCpuSmiEntryFixupAddress):\r
229 lea rax, [ASM_PFX(gSmiHandlerIdtr)]\r
230 lea rcx, [SmiHandlerIdtrAbsAddr]\r
231 mov qword [rcx - 8], rax\r
232\r
233 lea rax, [_SmiHandler]\r
234 lea rcx, [_SmiHandlerAbsAddr]\r
235 mov qword [rcx - 8], rax\r
236 ret\r