]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm
UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiException.nasm
CommitLineData
28ee5816 1;------------------------------------------------------------------------------ ;\r
3eb69b08 2; Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
28ee5816
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; SmiException.nasm\r
14;\r
15; Abstract:\r
16;\r
17; Exception handlers used in SM mode\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21extern ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))\r
28ee5816 22extern ASM_PFX(SmiPFHandler)\r
09afd9a4 23extern ASM_PFX(mSetupDebugTrap)\r
28ee5816
LG
24\r
25global ASM_PFX(gcSmiIdtr)\r
26global ASM_PFX(gcSmiGdtr)\r
717fb604 27global ASM_PFX(gTaskGateDescriptor)\r
28ee5816
LG
28global ASM_PFX(gcPsd)\r
29\r
30 SECTION .data\r
31\r
32NullSeg: DQ 0 ; reserved by architecture\r
33CodeSeg32:\r
34 DW -1 ; LimitLow\r
35 DW 0 ; BaseLow\r
36 DB 0 ; BaseMid\r
37 DB 0x9b\r
38 DB 0xcf ; LimitHigh\r
39 DB 0 ; BaseHigh\r
40ProtModeCodeSeg32:\r
41 DW -1 ; LimitLow\r
42 DW 0 ; BaseLow\r
43 DB 0 ; BaseMid\r
44 DB 0x9b\r
45 DB 0xcf ; LimitHigh\r
46 DB 0 ; BaseHigh\r
47ProtModeSsSeg32:\r
48 DW -1 ; LimitLow\r
49 DW 0 ; BaseLow\r
50 DB 0 ; BaseMid\r
51 DB 0x93\r
52 DB 0xcf ; LimitHigh\r
53 DB 0 ; BaseHigh\r
54DataSeg32:\r
55 DW -1 ; LimitLow\r
56 DW 0 ; BaseLow\r
57 DB 0 ; BaseMid\r
58 DB 0x93\r
59 DB 0xcf ; LimitHigh\r
60 DB 0 ; BaseHigh\r
61CodeSeg16:\r
62 DW -1\r
63 DW 0\r
64 DB 0\r
65 DB 0x9b\r
66 DB 0x8f\r
67 DB 0\r
68DataSeg16:\r
69 DW -1\r
70 DW 0\r
71 DB 0\r
72 DB 0x93\r
73 DB 0x8f\r
74 DB 0\r
75CodeSeg64:\r
76 DW -1 ; LimitLow\r
77 DW 0 ; BaseLow\r
78 DB 0 ; BaseMid\r
79 DB 0x9b\r
80 DB 0xaf ; LimitHigh\r
81 DB 0 ; BaseHigh\r
82GDT_SIZE equ $ - NullSeg\r
83\r
84TssSeg:\r
85 DW TSS_DESC_SIZE ; LimitLow\r
86 DW 0 ; BaseLow\r
87 DB 0 ; BaseMid\r
88 DB 0x89\r
89 DB 0x80 ; LimitHigh\r
90 DB 0 ; BaseHigh\r
91ExceptionTssSeg:\r
3eb69b08 92 DW EXCEPTION_TSS_DESC_SIZE ; LimitLow\r
28ee5816
LG
93 DW 0 ; BaseLow\r
94 DB 0 ; BaseMid\r
95 DB 0x89\r
96 DB 0x80 ; LimitHigh\r
97 DB 0 ; BaseHigh\r
98\r
99CODE_SEL equ CodeSeg32 - NullSeg\r
100DATA_SEL equ DataSeg32 - NullSeg\r
101TSS_SEL equ TssSeg - NullSeg\r
102EXCEPTION_TSS_SEL equ ExceptionTssSeg - NullSeg\r
103\r
104struc IA32_TSS\r
105 resw 1\r
106 resw 1\r
107 .ESP0: resd 1\r
108 .SS0: resw 1\r
109 resw 1\r
110 .ESP1: resd 1\r
111 .SS1: resw 1\r
112 resw 1\r
113 .ESP2: resd 1\r
114 .SS2: resw 1\r
115 resw 1\r
116 ._CR3: resd 1\r
117 .EIP: resd 1\r
118 .EFLAGS: resd 1\r
119 ._EAX: resd 1\r
120 ._ECX: resd 1\r
121 ._EDX: resd 1\r
122 ._EBX: resd 1\r
123 ._ESP: resd 1\r
124 ._EBP: resd 1\r
125 ._ESI: resd 1\r
126 ._EDI: resd 1\r
127 ._ES: resw 1\r
128 resw 1\r
129 ._CS: resw 1\r
130 resw 1\r
131 ._SS: resw 1\r
132 resw 1\r
133 ._DS: resw 1\r
134 resw 1\r
135 ._FS: resw 1\r
136 resw 1\r
137 ._GS: resw 1\r
138 resw 1\r
139 .LDT: resw 1\r
140 resw 1\r
141 resw 1\r
142 resw 1\r
143endstruc\r
144\r
145; Create 2 TSS segments just after GDT\r
146TssDescriptor:\r
147 DW 0 ; PreviousTaskLink\r
148 DW 0 ; Reserved\r
149 DD 0 ; ESP0\r
150 DW 0 ; SS0\r
151 DW 0 ; Reserved\r
152 DD 0 ; ESP1\r
153 DW 0 ; SS1\r
154 DW 0 ; Reserved\r
155 DD 0 ; ESP2\r
156 DW 0 ; SS2\r
157 DW 0 ; Reserved\r
158 DD 0 ; CR3\r
159 DD 0 ; EIP\r
160 DD 0 ; EFLAGS\r
161 DD 0 ; EAX\r
162 DD 0 ; ECX\r
163 DD 0 ; EDX\r
164 DD 0 ; EBX\r
165 DD 0 ; ESP\r
166 DD 0 ; EBP\r
167 DD 0 ; ESI\r
168 DD 0 ; EDI\r
169 DW 0 ; ES\r
170 DW 0 ; Reserved\r
171 DW 0 ; CS\r
172 DW 0 ; Reserved\r
173 DW 0 ; SS\r
174 DW 0 ; Reserved\r
175 DW 0 ; DS\r
176 DW 0 ; Reserved\r
177 DW 0 ; FS\r
178 DW 0 ; Reserved\r
179 DW 0 ; GS\r
180 DW 0 ; Reserved\r
181 DW 0 ; LDT Selector\r
182 DW 0 ; Reserved\r
183 DW 0 ; T\r
184 DW 0 ; I/O Map Base\r
185TSS_DESC_SIZE equ $ - TssDescriptor\r
186\r
187ExceptionTssDescriptor:\r
188 DW 0 ; PreviousTaskLink\r
189 DW 0 ; Reserved\r
190 DD 0 ; ESP0\r
191 DW 0 ; SS0\r
192 DW 0 ; Reserved\r
193 DD 0 ; ESP1\r
194 DW 0 ; SS1\r
195 DW 0 ; Reserved\r
196 DD 0 ; ESP2\r
197 DW 0 ; SS2\r
198 DW 0 ; Reserved\r
199 DD 0 ; CR3\r
200 DD PFHandlerEntry ; EIP\r
201 DD 00000002 ; EFLAGS\r
202 DD 0 ; EAX\r
203 DD 0 ; ECX\r
204 DD 0 ; EDX\r
205 DD 0 ; EBX\r
206 DD 0 ; ESP\r
207 DD 0 ; EBP\r
208 DD 0 ; ESI\r
209 DD 0 ; EDI\r
210 DW DATA_SEL ; ES\r
211 DW 0 ; Reserved\r
212 DW CODE_SEL ; CS\r
213 DW 0 ; Reserved\r
214 DW DATA_SEL ; SS\r
215 DW 0 ; Reserved\r
216 DW DATA_SEL ; DS\r
217 DW 0 ; Reserved\r
218 DW DATA_SEL ; FS\r
219 DW 0 ; Reserved\r
220 DW DATA_SEL ; GS\r
221 DW 0 ; Reserved\r
222 DW 0 ; LDT Selector\r
223 DW 0 ; Reserved\r
224 DW 0 ; T\r
225 DW 0 ; I/O Map Base\r
3eb69b08
JY
226 DD 0 ; SSP\r
227EXCEPTION_TSS_DESC_SIZE equ $ - ExceptionTssDescriptor\r
28ee5816
LG
228\r
229ASM_PFX(gcPsd):\r
230 DB 'PSDSIG '\r
231 DW PSD_SIZE\r
232 DW 2\r
233 DW 1 << 2\r
234 DW CODE_SEL\r
235 DW DATA_SEL\r
236 DW DATA_SEL\r
237 DW DATA_SEL\r
238 DW 0\r
239 DQ 0\r
240 DQ 0\r
241 DQ 0\r
242 DD 0\r
243 DD NullSeg\r
244 DD GDT_SIZE\r
245 DD 0\r
246 times 24 DB 0\r
247 DD 0\r
854c6b80 248 DD 0\r
28ee5816
LG
249PSD_SIZE equ $ - ASM_PFX(gcPsd)\r
250\r
251ASM_PFX(gcSmiGdtr):\r
252 DW GDT_SIZE - 1\r
253 DD NullSeg\r
254\r
255ASM_PFX(gcSmiIdtr):\r
717fb604
JY
256 DW 0\r
257 DD 0\r
28ee5816 258\r
717fb604 259ASM_PFX(gTaskGateDescriptor):\r
28ee5816
LG
260 DW 0 ; Reserved\r
261 DW EXCEPTION_TSS_SEL ; TSS Segment selector\r
262 DB 0 ; Reserved\r
263 DB 0x85 ; Task Gate, present, DPL = 0\r
264 DW 0 ; Reserved\r
265\r
266 SECTION .text\r
267;------------------------------------------------------------------------------\r
268; PageFaultIdtHandlerSmmProfile is the entry point page fault only\r
269;\r
270;\r
271; Stack:\r
272; +---------------------+\r
273; + EFlags +\r
274; +---------------------+\r
275; + CS +\r
276; +---------------------+\r
277; + EIP +\r
278; +---------------------+\r
279; + Error Code +\r
280; +---------------------+\r
281; + Vector Number +\r
282; +---------------------+\r
283; + EBP +\r
284; +---------------------+ <-- EBP\r
285;\r
286;\r
287;------------------------------------------------------------------------------\r
288global ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
289ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
290 push 0xe ; Page Fault\r
291\r
292 push ebp\r
293 mov ebp, esp\r
294\r
295 ;\r
296 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
297 ; is 16-byte aligned\r
298 ;\r
299 and esp, 0xfffffff0\r
300 sub esp, 12\r
301\r
302;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
303 push eax\r
304 push ecx\r
305 push edx\r
306 push ebx\r
307 lea ecx, [ebp + 6 * 4]\r
308 push ecx ; ESP\r
309 push dword [ebp] ; EBP\r
310 push esi\r
311 push edi\r
312\r
313;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
314 mov eax, ss\r
315 push eax\r
316 movzx eax, word [ebp + 4 * 4]\r
317 push eax\r
318 mov eax, ds\r
319 push eax\r
320 mov eax, es\r
321 push eax\r
322 mov eax, fs\r
323 push eax\r
324 mov eax, gs\r
325 push eax\r
326\r
327;; UINT32 Eip;\r
328 mov eax, [ebp + 3 * 4]\r
329 push eax\r
330\r
331;; UINT32 Gdtr[2], Idtr[2];\r
332 sub esp, 8\r
333 sidt [esp]\r
334 mov eax, [esp + 2]\r
335 xchg eax, [esp]\r
336 and eax, 0xFFFF\r
337 mov [esp+4], eax\r
338\r
339 sub esp, 8\r
340 sgdt [esp]\r
341 mov eax, [esp + 2]\r
342 xchg eax, [esp]\r
343 and eax, 0xFFFF\r
344 mov [esp+4], eax\r
345\r
346;; UINT32 Ldtr, Tr;\r
347 xor eax, eax\r
348 str ax\r
349 push eax\r
350 sldt ax\r
351 push eax\r
352\r
353;; UINT32 EFlags;\r
354 mov eax, [ebp + 5 * 4]\r
355 push eax\r
356\r
357;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
358 mov eax, cr4\r
359 or eax, 0x208\r
360 mov cr4, eax\r
361 push eax\r
362 mov eax, cr3\r
363 push eax\r
364 mov eax, cr2\r
365 push eax\r
366 xor eax, eax\r
367 push eax\r
368 mov eax, cr0\r
369 push eax\r
370\r
371;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
372 mov eax, dr7\r
373 push eax\r
374 mov eax, dr6\r
375 push eax\r
376 mov eax, dr3\r
377 push eax\r
378 mov eax, dr2\r
379 push eax\r
380 mov eax, dr1\r
381 push eax\r
382 mov eax, dr0\r
383 push eax\r
384\r
385;; FX_SAVE_STATE_IA32 FxSaveState;\r
386 sub esp, 512\r
387 mov edi, esp\r
d22c995a 388 fxsave [edi]\r
28ee5816
LG
389\r
390; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
391 cld\r
392\r
393;; UINT32 ExceptionData;\r
394 push dword [ebp + 2 * 4]\r
395\r
396;; call into exception handler\r
397\r
398;; Prepare parameter and call\r
399 mov edx, esp\r
400 push edx\r
401 mov edx, dword [ebp + 1 * 4]\r
402 push edx\r
403\r
404 ;\r
405 ; Call External Exception Handler\r
406 ;\r
407 mov eax, ASM_PFX(SmiPFHandler)\r
408 call eax\r
409 add esp, 8\r
410\r
411;; UINT32 ExceptionData;\r
412 add esp, 4\r
413\r
414;; FX_SAVE_STATE_IA32 FxSaveState;\r
415 mov esi, esp\r
d22c995a 416 fxrstor [esi]\r
28ee5816
LG
417 add esp, 512\r
418\r
419;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
420;; Skip restoration of DRx registers to support debuggers\r
421;; that set breakpoint in interrupt/exception context\r
422 add esp, 4 * 6\r
423\r
424;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
425 pop eax\r
426 mov cr0, eax\r
427 add esp, 4 ; not for Cr1\r
428 pop eax\r
429 mov cr2, eax\r
430 pop eax\r
431 mov cr3, eax\r
432 pop eax\r
433 mov cr4, eax\r
434\r
435;; UINT32 EFlags;\r
436 pop dword [ebp + 5 * 4]\r
437\r
438;; UINT32 Ldtr, Tr;\r
439;; UINT32 Gdtr[2], Idtr[2];\r
440;; Best not let anyone mess with these particular registers...\r
441 add esp, 24\r
442\r
443;; UINT32 Eip;\r
444 pop dword [ebp + 3 * 4]\r
445\r
446;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
447;; NOTE - modified segment registers could hang the debugger... We\r
448;; could attempt to insulate ourselves against this possibility,\r
449;; but that poses risks as well.\r
450;;\r
451 pop gs\r
452 pop fs\r
453 pop es\r
454 pop ds\r
455 pop dword [ebp + 4 * 4]\r
456 pop ss\r
457\r
458;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
459 pop edi\r
460 pop esi\r
461 add esp, 4 ; not for ebp\r
462 add esp, 4 ; not for esp\r
463 pop ebx\r
464 pop edx\r
465 pop ecx\r
466 pop eax\r
467\r
468 mov esp, ebp\r
469 pop ebp\r
470\r
471; Enable TF bit after page fault handler runs\r
472 bts dword [esp + 16], 8 ; EFLAGS\r
473\r
474 add esp, 8 ; skip INT# & ErrCode\r
475Return:\r
476 iretd\r
477;\r
478; Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
479; Executiot starts here after a task switch\r
480;\r
481PFHandlerEntry:\r
482;\r
483; Get this processor's TSS\r
484;\r
485 sub esp, 8\r
486 sgdt [esp + 2]\r
487 mov eax, [esp + 4] ; GDT base\r
488 add esp, 8\r
489 mov ecx, [eax + TSS_SEL + 2]\r
490 shl ecx, 8\r
491 mov cl, [eax + TSS_SEL + 7]\r
492 ror ecx, 8 ; ecx = TSS base\r
493\r
494 mov ebp, esp\r
495\r
496 ;\r
497 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
498 ; is 16-byte aligned\r
499 ;\r
500 and esp, 0xfffffff0\r
501 sub esp, 12\r
502\r
503;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
504 push dword [ecx + IA32_TSS._EAX]\r
505 push dword [ecx + IA32_TSS._ECX]\r
506 push dword [ecx + IA32_TSS._EDX]\r
507 push dword [ecx + IA32_TSS._EBX]\r
508 push dword [ecx + IA32_TSS._ESP]\r
509 push dword [ecx + IA32_TSS._EBP]\r
510 push dword [ecx + IA32_TSS._ESI]\r
511 push dword [ecx + IA32_TSS._EDI]\r
512\r
513;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
514 movzx eax, word [ecx + IA32_TSS._SS]\r
515 push eax\r
516 movzx eax, word [ecx + IA32_TSS._CS]\r
517 push eax\r
518 movzx eax, word [ecx + IA32_TSS._DS]\r
519 push eax\r
520 movzx eax, word [ecx + IA32_TSS._ES]\r
521 push eax\r
522 movzx eax, word [ecx + IA32_TSS._FS]\r
523 push eax\r
524 movzx eax, word [ecx + IA32_TSS._GS]\r
525 push eax\r
526\r
527;; UINT32 Eip;\r
528 push dword [ecx + IA32_TSS.EIP]\r
529\r
530;; UINT32 Gdtr[2], Idtr[2];\r
531 sub esp, 8\r
532 sidt [esp]\r
533 mov eax, [esp + 2]\r
534 xchg eax, [esp]\r
535 and eax, 0xFFFF\r
536 mov [esp+4], eax\r
537\r
538 sub esp, 8\r
539 sgdt [esp]\r
540 mov eax, [esp + 2]\r
541 xchg eax, [esp]\r
542 and eax, 0xFFFF\r
543 mov [esp+4], eax\r
544\r
545;; UINT32 Ldtr, Tr;\r
546 mov eax, TSS_SEL\r
547 push eax\r
548 movzx eax, word [ecx + IA32_TSS.LDT]\r
549 push eax\r
550\r
551;; UINT32 EFlags;\r
552 push dword [ecx + IA32_TSS.EFLAGS]\r
553\r
554;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
555 mov eax, cr4\r
556 or eax, 0x208\r
557 mov cr4, eax\r
558 push eax\r
559 mov eax, cr3\r
560 push eax\r
561 mov eax, cr2\r
562 push eax\r
563 xor eax, eax\r
564 push eax\r
565 mov eax, cr0\r
566 push eax\r
567\r
568;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
569 mov eax, dr7\r
570 push eax\r
571 mov eax, dr6\r
572 push eax\r
573 mov eax, dr3\r
574 push eax\r
575 mov eax, dr2\r
576 push eax\r
577 mov eax, dr1\r
578 push eax\r
579 mov eax, dr0\r
580 push eax\r
581\r
582;; FX_SAVE_STATE_IA32 FxSaveState;\r
583;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
584;; when executing fxsave/fxrstor instruction\r
585 clts\r
586 sub esp, 512\r
587 mov edi, esp\r
d22c995a 588 fxsave [edi]\r
28ee5816
LG
589\r
590; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
591 cld\r
592\r
593;; UINT32 ExceptionData;\r
594 push dword [ebp]\r
595\r
596;; call into exception handler\r
597 mov ebx, ecx\r
598 mov eax, ASM_PFX(SmiPFHandler)\r
599\r
600;; Prepare parameter and call\r
601 mov edx, esp\r
602 push edx\r
603 mov edx, 14\r
604 push edx\r
605\r
606 ;\r
607 ; Call External Exception Handler\r
608 ;\r
609 call eax\r
610 add esp, 8\r
611\r
612 mov ecx, ebx\r
613;; UINT32 ExceptionData;\r
614 add esp, 4\r
615\r
616;; FX_SAVE_STATE_IA32 FxSaveState;\r
617 mov esi, esp\r
d22c995a 618 fxrstor [esi]\r
28ee5816
LG
619 add esp, 512\r
620\r
621;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
622;; Skip restoration of DRx registers to support debuggers\r
623;; that set breakpoints in interrupt/exception context\r
624 add esp, 4 * 6\r
625\r
626;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
627 pop eax\r
628 mov cr0, eax\r
629 add esp, 4 ; not for Cr1\r
630 pop eax\r
631 mov cr2, eax\r
632 pop eax\r
633 mov dword [ecx + IA32_TSS._CR3], eax\r
634 pop eax\r
635 mov cr4, eax\r
636\r
637;; UINT32 EFlags;\r
638 pop dword [ecx + IA32_TSS.EFLAGS]\r
639\r
640;; UINT32 Ldtr, Tr;\r
641;; UINT32 Gdtr[2], Idtr[2];\r
642;; Best not let anyone mess with these particular registers...\r
643 add esp, 24\r
644\r
645;; UINT32 Eip;\r
646 pop dword [ecx + IA32_TSS.EIP]\r
647\r
648;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
649;; NOTE - modified segment registers could hang the debugger... We\r
650;; could attempt to insulate ourselves against this possibility,\r
651;; but that poses risks as well.\r
652;;\r
653 pop eax\r
654o16 mov [ecx + IA32_TSS._GS], ax\r
655 pop eax\r
656o16 mov [ecx + IA32_TSS._FS], ax\r
657 pop eax\r
658o16 mov [ecx + IA32_TSS._ES], ax\r
659 pop eax\r
660o16 mov [ecx + IA32_TSS._DS], ax\r
661 pop eax\r
662o16 mov [ecx + IA32_TSS._CS], ax\r
663 pop eax\r
664o16 mov [ecx + IA32_TSS._SS], ax\r
665\r
666;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
667 pop dword [ecx + IA32_TSS._EDI]\r
668 pop dword [ecx + IA32_TSS._ESI]\r
669 add esp, 4 ; not for ebp\r
670 add esp, 4 ; not for esp\r
671 pop dword [ecx + IA32_TSS._EBX]\r
672 pop dword [ecx + IA32_TSS._EDX]\r
673 pop dword [ecx + IA32_TSS._ECX]\r
674 pop dword [ecx + IA32_TSS._EAX]\r
675\r
676 mov esp, ebp\r
677\r
678; Set single step DB# if SMM profile is enabled and page fault exception happens\r
09afd9a4 679 cmp byte [dword ASM_PFX(mSetupDebugTrap)], 0\r
28ee5816
LG
680 jz @Done2\r
681\r
682; Create return context for iretd in stub function\r
683 mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack pointer\r
684 mov ebx, dword [ecx + IA32_TSS.EIP]\r
685 mov [eax - 0xc], ebx ; create EIP in old stack\r
686 movzx ebx, word [ecx + IA32_TSS._CS]\r
687 mov [eax - 0x8], ebx ; create CS in old stack\r
688 mov ebx, dword [ecx + IA32_TSS.EFLAGS]\r
689 bts ebx, 8\r
690 mov [eax - 0x4], ebx ; create eflags in old stack\r
691 mov eax, dword [ecx + IA32_TSS._ESP] ; Get old stack pointer\r
692 sub eax, 0xc ; minus 12 byte\r
693 mov dword [ecx + IA32_TSS._ESP], eax ; Set new stack pointer\r
694; Replace the EIP of interrupted task with stub function\r
695 mov eax, ASM_PFX(PageFaultStubFunction)\r
696 mov dword [ecx + IA32_TSS.EIP], eax\r
697; Jump to the iretd so next page fault handler as a task will start again after iretd.\r
698@Done2:\r
699 add esp, 4 ; skip ErrCode\r
700\r
701 jmp Return\r
702\r
703global ASM_PFX(PageFaultStubFunction)\r
704ASM_PFX(PageFaultStubFunction):\r
705;\r
706; we need clean TS bit in CR0 to execute\r
707; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
708;\r
709 clts\r
710 iretd\r
711\r