- Don't use EFLAGS to store the Wait IRQL, just push directly, it's cleaner.

- Detect if kernel APCs are pending and request APC_LEVEL software interrupt from HAL if they are, returning with the right apc status.
- Also update INT21 VDM Descriptor handler when updating LDT descriptor.

svn path=/trunk/; revision=23624
This commit is contained in:
Alex Ionescu
2006-08-20 20:09:25 +00:00
parent 017e14551b
commit 893a8bcac6
2 changed files with 37 additions and 10 deletions
+35 -8
View File
@@ -115,14 +115,11 @@ BadThread:
.globl @KiSwapContextInternal@0
@KiSwapContextInternal@0:
/* Save WaitIrql APC-bypass in EFLAGS */
or cl, cl
/* Set the Thread to running */
mov byte ptr [esi+KTHREAD_STATE], Running
/* Save the flags */
pushf
/* Save the IRQL */
push ecx
/* Save the Exception list */
push [ebx+KPCR_EXCEPTION_LIST]
@@ -224,13 +221,36 @@ SameProcess:
/* Restore exception list */
pop [ebx+KPCR_EXCEPTION_LIST]
/* Retore EFLAGS */
popf
/* Restore IRQL */
pop ecx
/* Return no APC pending */
/* Check if kernel APCs are pending */
cmp byte ptr [esi+KTHREAD_PENDING_KERNEL_APC], 0
jnz CheckApc
/* No APCs, return */
xor eax, eax
ret
CheckApc:
/* Check if they're disabled */
cmp word ptr [esi+KTHREAD_SPECIAL_APC_DISABLE], 0
jnz ApcReturn
test cl, cl
jz ApcReturn
/* Request APC Delivery */
mov cl, APC_LEVEL
call @HalRequestSoftwareInterrupt@4
or eax, esp
ApcReturn:
/* Return with APC pending */
setz al
ret
LdtStuff:
/* Write the LDT Selector */
@@ -240,6 +260,13 @@ LdtStuff:
mov eax, [edi+KPROCESS_LDT_DESCRIPTOR1]
mov [ecx+KGDT_LDT+4], eax
/* Write the INT21 handler */
mov ecx, [ebx+KPCR_IDT]
mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR0]
mov [ecx+0x108], eax
mov eax, [ebp+KPROCESS_INT21_DESCRIPTOR1]
mov [ecx+0x10C], eax
/* Save LDT Selector */
mov eax, KGDT_LDT
jmp LoadLdt
+2 -2
View File
@@ -15,7 +15,7 @@
typedef struct _KSHARED_CTXSWITCH_FRAME
{
PVOID ExceptionList;
ULONG Flags;
KIRQL WaitIrql;
PVOID RetEip;
} KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME;
@@ -231,7 +231,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
/* And set up the Context Switch Frame */
CtxSwitchFrame->RetEip = KiThreadStartup;
CtxSwitchFrame->Flags = EFLAGS_INTERRUPT_MASK;
CtxSwitchFrame->WaitIrql = APC_LEVEL;
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
/* Save back the new value of the kernel stack. */