[KMTESTS/KE]

- KeIrql: make use of the new build type features
- KeApc: test internals of enabling/disable APCs
[KMTESTS/EX]
- better portability for ExInterlocked test

svn path=/branches/GSoC_2011/KMTestSuite/; revision=52782
This commit is contained in:
Thomas Faber 2011-07-22 12:01:48 +00:00
parent ed72d2fbd2
commit ca91b96107
4 changed files with 195 additions and 89 deletions

View file

@ -43,7 +43,7 @@ const KMT_TEST TestList[] =
{ "KeDpc", Test_KeDpc }, { "KeDpc", Test_KeDpc },
{ "KeIrql", Test_KeIrql }, { "KeIrql", Test_KeIrql },
{ "KeProcessor", Test_KeProcessor }, { "KeProcessor", Test_KeProcessor },
{ "KernelType", Test_KernelType }, { "-KernelType", Test_KernelType },
{ "ObCreate", Test_ObCreate }, { "ObCreate", Test_ObCreate },
{ NULL, NULL } { NULL, NULL }
}; };

View file

@ -38,10 +38,20 @@ __declspec(dllimport) int __stdcall Exi386InterlockedDecrementLo
static KSPIN_LOCK SpinLock; static KSPIN_LOCK SpinLock;
#ifdef _M_IX86
typedef struct typedef struct
{ {
int esi, edi, ebx, ebp, esp; unsigned long esi, edi, ebx, ebp, esp;
} PROCESSOR_STATE, *PPROCESSOR_STATE; } PROCESSOR_STATE;
#elif defined(_M_AMD64)
typedef struct
{
unsigned long long rsi, rdi, rbx, rbp, rsp, r12, r13, r14, r15;
} PROCESSOR_STATE;
#else
// dummy
typedef int PROCESSOR_STATE;
#endif
#if defined(_MSC_VER) && defined(_M_IX86) #if defined(_MSC_VER) && defined(_M_IX86)
#define SaveState(State) do \ #define SaveState(State) do \
@ -63,6 +73,56 @@ typedef struct
ok_eq_hex((OldState)->esp, (NewState)->esp); \ ok_eq_hex((OldState)->esp, (NewState)->esp); \
} while (0) } while (0)
#elif defined(__GNUC__) && defined(_M_IX86)
#define SaveState(State) \
asm volatile( \
".intel_syntax noprefix\n\t" \
"mov\t[ecx], esi\n\t" \
"mov\t[ecx+4], edi\n\t" \
"mov\t[ecx+8], ebx\n\t" \
"mov\t[ecx+12], ebp\n\t" \
"mov\t[ecx+16], esp\n\t" \
".att_syntax prefix" \
: : "c" (&State) : "memory" \
);
#define CheckState(OldState, NewState) do \
{ \
ok_eq_hex((OldState)->esi, (NewState)->esi); \
ok_eq_hex((OldState)->edi, (NewState)->edi); \
ok_eq_hex((OldState)->ebx, (NewState)->ebx); \
ok_eq_hex((OldState)->ebp, (NewState)->ebp); \
ok_eq_hex((OldState)->esp, (NewState)->esp); \
} while (0)
#elif defined(__GNUC__) && defined(_M_AMD64)
#define SaveState(State) \
asm volatile( \
".intel_syntax noprefix\n\t" \
"mov\t[rcx], rsi\n\t" \
"mov\t[rcx+8], rdi\n\t" \
"mov\t[rcx+16], rbx\n\t" \
"mov\t[rcx+24], rbp\n\t" \
"mov\t[rcx+32], rsp\n\t" \
"mov\t[rcx+40], r12\n\t" \
"mov\t[rcx+48], r13\n\t" \
"mov\t[rcx+56], r14\n\t" \
"mov\t[rcx+64], r15\n\t" \
".att_syntax prefix" \
: : "c" (&State) : "memory" \
);
#define CheckState(OldState, NewState) do \
{ \
ok_eq_hex((OldState)->rsi, (NewState)->rsi); \
ok_eq_hex((OldState)->rdi, (NewState)->rdi); \
ok_eq_hex((OldState)->rbx, (NewState)->rbx); \
ok_eq_hex((OldState)->rbp, (NewState)->rbp); \
ok_eq_hex((OldState)->rsp, (NewState)->rsp); \
ok_eq_hex((OldState)->r12, (NewState)->r12); \
ok_eq_hex((OldState)->r13, (NewState)->r13); \
ok_eq_hex((OldState)->r14, (NewState)->r14); \
ok_eq_hex((OldState)->r15, (NewState)->r15); \
} while (0)
#else #else
#define SaveState(State) #define SaveState(State)
#define CheckState(OldState, NewState) #define CheckState(OldState, NewState)
@ -218,10 +278,6 @@ TestInterlockedFunctional(VOID)
/* CompareExchange */ /* CompareExchange */
/* macro version */ /* macro version */
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L);
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L);
/* exported function */
#undef InterlockedCompareExchange
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L); CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L);
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L); CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L);
/* these only exist as macros on x86 */ /* these only exist as macros on x86 */
@ -229,27 +285,35 @@ TestInterlockedFunctional(VOID)
CheckInterlockedCmpXchg(InterlockedCompareExchangeAcquire, LONG, "%ld", 16, 16, 4, 4L, 16L); CheckInterlockedCmpXchg(InterlockedCompareExchangeAcquire, LONG, "%ld", 16, 16, 4, 4L, 16L);
CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 123, 38, 27L, 27L); CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 123, 38, 27L, 27L);
CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 27, 39, 39L, 27L); CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 27, 39, 39L, 27L);
/* exported function */
#undef InterlockedCompareExchange
#ifdef _M_IX86
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L);
CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L);
#endif
/* only exists as a macro */ /* only exists as a macro */
CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)711, (PVOID)12, (PVOID)117, (PVOID)117); CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)711, (PVOID)12, (PVOID)117, (PVOID)117);
CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)117, (PVOID)228, (PVOID)228, (PVOID)117); CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)117, (PVOID)228, (PVOID)228, (PVOID)117);
/* macro version */ /* macro version */
CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock); CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock);
CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock); CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock);
#ifdef _M_IX86
/* exported function */ /* exported function */
CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock); CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock);
CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock); CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock);
/* fastcall version */ /* fastcall version */
CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL); CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL);
CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL); CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL);
#endif
/* Exchange */ /* Exchange */
CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L); CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L);
#undef InterlockedExchange
CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L);
CheckInterlockedOp(InterlockedExchangePointer, PVOID, "%p", (PVOID)700, (PVOID)93, (PVOID)93, (PVOID)700); CheckInterlockedOp(InterlockedExchangePointer, PVOID, "%p", (PVOID)700, (PVOID)93, (PVOID)93, (PVOID)700);
#undef InterlockedExchange
#ifdef _M_IX86
CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L);
CheckInterlockedOp(ExInterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock); CheckInterlockedOp(ExInterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock);
CheckInterlockedOp((ExInterlockedExchangeUlong), ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock); CheckInterlockedOp((ExInterlockedExchangeUlong), ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock);
#ifdef _M_IX86
CheckInterlockedOp(Exi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU); CheckInterlockedOp(Exi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU);
CheckInterlockedOp(Exfi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU); CheckInterlockedOp(Exfi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU);
#endif #endif
@ -258,7 +322,9 @@ TestInterlockedFunctional(VOID)
/* TODO: ExInterlockedExchangeAddLargeInteger? */ /* TODO: ExInterlockedExchangeAddLargeInteger? */
CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L); CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L);
#undef InterlockedExchangeAdd #undef InterlockedExchangeAdd
#ifdef _M_IX86
CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L); CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L);
#endif
/* Add */ /* Add */
/* these DO need a valid spinlock even on x86 */ /* these DO need a valid spinlock even on x86 */
@ -271,11 +337,12 @@ TestInterlockedFunctional(VOID)
/* Increment */ /* Increment */
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L); CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L);
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG); CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG);
#undef InterlockedIncrement
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L);
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG);
CheckInterlockedOpNoArg(InterlockedIncrementAcquire, LONG, "%ld", 2341L, 2342L, 2342L); CheckInterlockedOpNoArg(InterlockedIncrementAcquire, LONG, "%ld", 2341L, 2342L, 2342L);
CheckInterlockedOpNoArg(InterlockedIncrementRelease, LONG, "%ld", 2341L, 2342L, 2342L); CheckInterlockedOpNoArg(InterlockedIncrementRelease, LONG, "%ld", 2341L, 2342L, 2342L);
#undef InterlockedIncrement
#ifdef _M_IX86
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L);
CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG);
CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative, pSpinLock);
CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock);
CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock);
@ -284,7 +351,6 @@ TestInterlockedFunctional(VOID)
CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock);
CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock);
CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)ResultNegative, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)ResultNegative, pSpinLock);
#ifdef _M_IX86
CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative); CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative);
CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero); CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero);
CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive); CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive);
@ -294,11 +360,12 @@ TestInterlockedFunctional(VOID)
/* Decrement */ /* Decrement */
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L); CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L);
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG); CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG);
#undef InterlockedDecrement
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L);
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG);
CheckInterlockedOpNoArg(InterlockedDecrementAcquire, LONG, "%ld", 1745L, 1744L, 1744L); CheckInterlockedOpNoArg(InterlockedDecrementAcquire, LONG, "%ld", 1745L, 1744L, 1744L);
CheckInterlockedOpNoArg(InterlockedDecrementRelease, LONG, "%ld", 1745L, 1744L, 1744L); CheckInterlockedOpNoArg(InterlockedDecrementRelease, LONG, "%ld", 1745L, 1744L, 1744L);
#undef InterlockedDecrement
#ifdef _M_IX86
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L);
CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG);
CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive, pSpinLock);
CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock);
CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock); CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock);
@ -307,7 +374,6 @@ TestInterlockedFunctional(VOID)
CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock);
CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock);
CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 2L, 1L, (LONG)ResultPositive, pSpinLock); CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 2L, 1L, (LONG)ResultPositive, pSpinLock);
#ifdef _M_IX86
CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive); CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive);
CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative); CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative);
CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero); CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero);

View file

@ -6,146 +6,181 @@
*/ */
#include <ntddk.h> #include <ntddk.h>
#include <ntifs.h>
#include <ndk/ketypes.h>
#include <kmt_test.h> #include <kmt_test.h>
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, Irql) do \ #define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
{ \ { \
ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled); \ ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
ok_eq_bool(KeAreAllApcsDisabled(), SpecialApcsDisabled); \ ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
ok_irql(Irql); \ ok_eq_bool(KeAreAllApcsDisabled(), AllApcsDisabled); \
ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
ok_irql(Irql); \
} while (0) } while (0)
START_TEST(KeApc) START_TEST(KeApc)
{ {
KIRQL Irql; KIRQL Irql;
PKTHREAD Thread = KeGetCurrentThread();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* critical region */ /* critical region */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-3, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* guarded region */ /* guarded region */
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -3, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* mix them */ /* mix them */
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* leave without entering */
KeLeaveCriticalRegion();
CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeLeaveGuardedRegion();
CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
KeEnterGuardedRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion();
CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
KeLeaveGuardedRegion();
CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
KeEnterCriticalRegion();
CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
KeEnterGuardedRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* manually disable APCs */
Thread->KernelApcDisable = -1;
CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
Thread->SpecialApcDisable = -1;
CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
Thread->KernelApcDisable = 0;
CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
Thread->SpecialApcDisable = 0;
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* raised irql - APC_LEVEL should disable APCs */ /* raised irql - APC_LEVEL should disable APCs */
KeRaiseIrql(APC_LEVEL, &Irql); KeRaiseIrql(APC_LEVEL, &Irql);
CheckApcs(FALSE, TRUE, APC_LEVEL); CheckApcs(0, 0, TRUE, APC_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */ /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
KeRaiseIrql(DISPATCH_LEVEL, &Irql); KeRaiseIrql(DISPATCH_LEVEL, &Irql);
CheckApcs(FALSE, TRUE, DISPATCH_LEVEL); CheckApcs(0, 0, TRUE, DISPATCH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* ... but also work on higher levels! */ /* ... but also work on higher levels! */
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* now comes the crazy stuff */ /* now comes the crazy stuff */
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(0, -1, TRUE, HIGH_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(0, -1, TRUE, HIGH_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeEnterGuardedRegion(); KeEnterGuardedRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(0, -1, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(TRUE, TRUE, PASSIVE_LEVEL); CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeLeaveGuardedRegion(); KeLeaveGuardedRegion();
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
KeEnterCriticalRegion(); KeEnterCriticalRegion();
CheckApcs(TRUE, FALSE, PASSIVE_LEVEL); CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql); KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(TRUE, TRUE, HIGH_LEVEL); CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
CheckApcs(FALSE, TRUE, HIGH_LEVEL); CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql); KeLowerIrql(Irql);
CheckApcs(FALSE, FALSE, PASSIVE_LEVEL); CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
} }

View file

@ -23,18 +23,12 @@ START_TEST(KeIrql)
PrevIrql = KeGetCurrentIrql(); PrevIrql = KeGetCurrentIrql();
// SYNCH_LEVEL is different for UP/MP /* SYNCH_LEVEL is different for UP/MP */
if (KeGetCurrentPrcb()->BuildType & PRCB_BUILD_UNIPROCESSOR) if (KmtIsMultiProcessorBuild)
{
trace("This is a Uniprocessor kernel\n");
SynchIrql = DISPATCH_LEVEL;
}
else
{
trace("This is a Multiprocessor kernel\n");
SynchIrql = IPI_LEVEL - 2; SynchIrql = IPI_LEVEL - 2;
} else
SynchIrql = DISPATCH_LEVEL;
/* some Irqls MUST work */ /* some Irqls MUST work */
{ {
const KIRQL Irqls[] = { LOW_LEVEL, PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL, const KIRQL Irqls[] = { LOW_LEVEL, PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL,
@ -129,6 +123,17 @@ START_TEST(KeIrql)
ok_eq_uint(Irql, SynchIrql); ok_eq_uint(Irql, SynchIrql);
KeLowerIrql(PASSIVE_LEVEL); KeLowerIrql(PASSIVE_LEVEL);
/* these bugcheck on a checked build but run fine on free! */
if (!KmtIsCheckedBuild)
{
KeRaiseIrql(HIGH_LEVEL, &Irql);
KeRaiseIrql(APC_LEVEL, &Irql);
ok_irql(APC_LEVEL);
KeLowerIrql(HIGH_LEVEL);
ok_irql(HIGH_LEVEL);
KeLowerIrql(PASSIVE_LEVEL);
}
/* make sure we exit gracefully */ /* make sure we exit gracefully */
ok_irql(PASSIVE_LEVEL); ok_irql(PASSIVE_LEVEL);
KeLowerIrql(PASSIVE_LEVEL); KeLowerIrql(PASSIVE_LEVEL);