@@ -220,7 +220,7 @@ ifnb <r0exclbl>
220220else
221221 jz exclbl
222222endif
223- if ?KDSUPP or ?ALLOWR0IRQ
223+ if ?KDSUPP or ?ALLOWR0IRQ or ?NMISAFE
224224 push eax
225225 lea eax , [ esp + R3FAULT32 + 4 ]
226226 cmp eax , ss : [ dwHostStack ]
@@ -2075,8 +2075,22 @@ endif
20752075 pop edx
20762076 pop ecx
20772077 pop eax
2078+ if ?NMISAFE
2079+ cmp [ ebp + 4 ] .LCEFR.dwExc , 2 ;v3.24: avoid IRETD for NMI
2080+ jz @F
2081+ endif
20782082 pop ebp
20792083 iretd
2084+ if ?NMISAFE
2085+ @@:
2086+ mov ebp ,[ ebp + 4 ] .LCEFR.r.rFL
2087+ xchg ebp ,[ esp + 1 * 4 ] ;set flags, get eip
2088+ xchg ebp ,[ esp + 2 * 4 ] ;set eip, get cs
2089+ mov [ esp + 3 * 4 ], ebp ;set cs
2090+ pop ebp
2091+ popfd
2092+ retd
2093+ endif
20802094 align 4
20812095lpms_call_exc endp
20822096
@@ -2705,41 +2719,61 @@ endif
27052719intr01 endp
27062720
27072721intr02 proc
2708- cmp word ptr [ esp .IRET32.rCS ], _CSSEL_ ;NMI in ring 0?
2709- if ?NMI2RM
2710- jz intr02_r0 ; v3.24: route NMI in PL0 to real-mode
2722+ ;--- v3.24: check PL, not CS
2723+ ; cmp word ptr [esp.IRET32.rCS],_CSSEL_ ;NMI in ring 0?
2724+ push eax
2725+ lar eax ,[ esp + 4 ] .IRET32.rCSd
2726+ and ah , 60h
2727+ pop eax
2728+ ;--- v3.24: route NMI in PL0 to real-mode for NMI-safe variant
2729+ if ?NMISAFE
2730+ jz intr02_r0
27112731else
27122732 jz iretexit ; skip NMI in PL0
27132733endif
27142734 @exception 02
27152735 @mapexc2int 02
2716- if ?NMI2RM
2736+ if ?NMISAFE
27172737;--- v3.24: route NMI to real-mode if it occured in ring 0
27182738intr02_r0:
2739+ push eax
27192740;--- save pm segment regs, they will be undefined after @rawjmp_pm
27202741 push ds
27212742 push es
27222743 push fs
27232744 push gs
27242745;--- save/restore global vars that may be modified by mode switches
2725- push ss : [ taskseg._Eax ]
27262746 push ss : [ dwPmDest ]
2747+ push ss : [ taskseg._Eax ]
27272748 push ss : [ dwHostStack ]
27282749 mov ss : [ dwHostStack ], esp
2729- @rawjmp_rm @F
2730- _TEXT16 segment
2750+ mov ax , offset intr02_rm1
2751+ cmp ss : [ oldint02rm ], 0
2752+ jnz @F
2753+ mov ax , offset intr02_rm2
27312754@@:
2755+ @rawjmp_rm ax
2756+ _TEXT16 segment
2757+ intr02_rm1:
2758+ pushf
2759+ db 9ah
2760+ oldint02rm dd 0
2761+ @rawjmp_pm intr02_pm
2762+ intr02_rm2:
27322763 int 02
2733- @rawjmp_pm @F
2764+ @rawjmp_pm intr02_pm
27342765_TEXT16 ends
2735- @@:
2766+ ;--- v86iret segregs weren't modified; NMI still masked
2767+ intr02_pm:
27362768 pop ss : [ dwHostStack ]
2737- pop ss : [ dwPmDest ]
27382769 pop ss : [ taskseg._Eax ]
2770+ pop ss : [ dwPmDest ]
27392771 pop gs
27402772 pop fs
27412773 pop es
27422774 pop ds
2775+ @NMI_ON ;intr02 (wait until all seg regs are restored!)
2776+ pop eax
27432777 iretd
27442778endif
27452779intr02 endp
@@ -3303,7 +3337,7 @@ irqrm2pm_1:
33033337 mov fs , ss :pmstate.rFS
33043338 mov gs , ss :pmstate.rGS
33053339
3306- @NMI_ON 0
3340+ @NMI_ON ;initrmcb_pm
33073341
33083342ifdef _DEBUG
33093343 verw word ptr ss :pmstate.rSSd
0 commit comments