From 893a8bcac64193a6d5fb6e86cb7d871884b78cd0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 20 Aug 2006 20:09:25 +0000 Subject: [PATCH] - 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 --- reactos/ntoskrnl/ke/i386/ctxswitch.S | 43 ++++++++++++++++++++++------ reactos/ntoskrnl/ke/i386/thread.c | 4 +-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/ctxswitch.S b/reactos/ntoskrnl/ke/i386/ctxswitch.S index 2d23bef0906..67840f04007 100644 --- a/reactos/ntoskrnl/ke/i386/ctxswitch.S +++ b/reactos/ntoskrnl/ke/i386/ctxswitch.S @@ -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 diff --git a/reactos/ntoskrnl/ke/i386/thread.c b/reactos/ntoskrnl/ke/i386/thread.c index 466db3c63ba..b7469485525 100644 --- a/reactos/ntoskrnl/ke/i386/thread.c +++ b/reactos/ntoskrnl/ke/i386/thread.c @@ -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. */