isolate POSIX builds from the host UCRT, wire lwext4 and ntfs-3g as ext4.sys and ntfs.sys, split the FAT driver into directory/file/async/driver/mount units, add posixsrv and dwm plus input/console/desktop syscall clients and a pile of new smoke targets, rename serial.sys to cereal.sys, name HDA/USB/lwIP/AHCI workers, harden ATA probing/reset/removal around actual hardware deadlines, absent-channel detection, diagnostics and explicit worker lifetime, redo ACPI S5 shutdown around GAS/MMIO and HW-reduced firmware, scan SSDTs for _S5 and deal with Intel SMI sleep trapping, make serial and SMP timeouts use real monotonic deadlines, add thread names and fix terminal thread teardown, scheduler and APC prepare/commit races, make advisory file locks queryable and preserve split ranges and add mutable file append state, add shared-memory pipes with kernel-assisted wait/wake, introduce capability-scoped input and display managers, split surface map rights into read/write, add explicit unmap and replace present with commit/generation/damage tracking while keeping physical presentation under the display manager, decouple native exception classes from Win32 exception numbers and translate them in kernel32, add opaque process startup data, bump the resource protocol to v3 with namespace directories, symlinks and enumeration and service control to v2 with generic READY handle exports, add the new POSIX errno/status surface and rebuild fds around posixsrv-owned shared open descriptions, descriptor-local flags, exact inheritance snapshots, dup/fcntl/record locks and shared-ring pipes, add waitpid, POSIX credentials/groups/sessions/passwd/group lookups and move sockets onto stable open descriptions, port the shells and apps to the new console/input services and surface commit API, teach init to load services.ini and start/supervise RSSRV, DWM and generic services under restricted capabilities while publishing their endpoints through RSSRV, split RSSRV into namespace, volume, display, session, input, console and resource components and make /SystemRoot a real symlink to the independently published system volume, shift the syscall table again, expand lock/resource/surface/POSIX/service/thread smoke coverage, make docs scream ASK QUESTIONS and DISCUSS at LLMs, replace MIT No Attribution with WTFPL+.

This commit is contained in:
maksw committed 2026-09-16 10:33:20 +02:00
1 parent 3dacbd32c8
commit 73abd6f90d
441 files changed
+187073 -6549

No files matched your search

+69 -442
View File
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <intrin.h>
#include <kernel/hal/hal_api.h>
#include <kernel/ke_apc.h>
@@ -28,460 +29,83 @@
#include <kernel/ob_object.h>
#include <kernel/ke_smp.h>
// Kernel APC self-test.
typedef struct KI_APC_SELFTEST_STATE {
EVENT* ReadyEvent;
EVENT* GoEvent;
EVENT* DoneEvent;
EVENT* FinishedEvent;
THREAD* WorkerThread;
volatile int SelfDelivered;
volatile int DeferredDelivered;
volatile int CrossDelivered;
} KI_APC_SELFTEST_STATE;
static void KiApcSelfTestKernelRoutine(KAPC* apc,
void** normalRoutine,
void** normalContext,
void** systemArgument1,
void** systemArgument2) {
DbgPrint("APC selftest: kernel routine apc=0x%016llX normal=0x%016llX ctx=0x%016llX arg1=0x%016llX arg2=0x%016llX irql=%u\n",
(uint64_t)apc,
(uint64_t)*normalRoutine,
(uint64_t)*normalContext,
(uint64_t)*systemArgument1,
(uint64_t)*systemArgument2,
KeGetCurrentIrql());
}
static void KiApcSelfTestNormalRoutine(void* normalContext,
void* systemArgument1,
void* systemArgument2) {
volatile int* counter = (volatile int*)normalContext;
DbgPrint("APC selftest: normal routine ctx=0x%016llX arg1=0x%016llX arg2=0x%016llX irql=%u\n",
(uint64_t)normalContext,
(uint64_t)systemArgument1,
(uint64_t)systemArgument2,
KeGetCurrentIrql());
// Focused APC wait-commit race self-test. User-mode APC return and async I/O
// behavior are covered by executable smoke tests; keep only the scheduler race
// that cannot be constructed through the public ABI.
// Verifies that one APC normal routine executes in interruptible PASSIVE thread context.
static void KiAssertApcNormalContext(const char* name) {
KCPU* cpu = KeGetCurrentCpu();
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: normal routine ran above PASSIVE_LEVEL\n");
(*counter)++;
KePanic(KE_PANIC_CODE_SELFTEST, "%s ran above PASSIVE_LEVEL\n", name);
if ((__readeflags() & 0x200u) == 0)
KePanic(KE_PANIC_CODE_SELFTEST, "%s ran with interrupts disabled\n", name);
if (!cpu || cpu->InterruptDepth != 0)
KePanic(KE_PANIC_CODE_SELFTEST, "%s ran inside interrupt context depth=%u\n",
name, cpu ? cpu->InterruptDepth : 0xFFFFFFFFu);
}
static void KiApcSelfTestCrossThreadRoutine(void* normalContext,
void* systemArgument1,
void* systemArgument2) {
KI_APC_SELFTEST_STATE* st = (KI_APC_SELFTEST_STATE*)normalContext;
DbgPrint("APC selftest: cross-thread APC delivered arg1=0x%016llX arg2=0x%016llX irql=%u\n",
(uint64_t)systemArgument1,
(uint64_t)systemArgument2,
KeGetCurrentIrql());
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread APC ran above PASSIVE_LEVEL\n");
st->CrossDelivered++;
KeSignalEvent(st->DoneEvent);
}
// Implements the apc Self Test Worker operation.
static void KiApcSelfTestWorker(void* arg) {
KI_APC_SELFTEST_STATE* st = (KI_APC_SELFTEST_STATE*)arg;
DbgPrint("APC selftest: worker started, signaling ready\n");
KeSignalEvent(st->ReadyEvent);
DbgPrint("APC selftest: worker waiting for go event\n");
KSTATUS s = KeWaitForEvent(st->GoEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker wait failed status=%d\n", s);
// KeCommitBlockThread(..., alertable) should deliver pending kernel APCs before this
// wait returns. If that hook is broken, DoneEvent will never be signaled.
DbgPrint("APC selftest: worker resumed after go event, cross=%d\n",
st->CrossDelivered);
if (st->CrossDelivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker resumed but APC was not delivered\n");
KeSignalEvent(st->FinishedEvent);
KeExitThread(KeGetCurrentThread(), 0);
}
typedef struct KI_APC_ALERTABLE_SELFTEST_STATE {
EVENT* ReadyEvent;
EVENT* WaitEvent;
EVENT* FinishedEvent;
THREAD* WorkerThread;
volatile int ApcDelivered;
volatile KSTATUS WaitStatus;
} KI_APC_ALERTABLE_SELFTEST_STATE;
static void KiApcAlertableSelfTestNormalRoutine(void* normalContext,
void* systemArgument1,
void* systemArgument2) {
KI_APC_ALERTABLE_SELFTEST_STATE* st =
(KI_APC_ALERTABLE_SELFTEST_STATE*)normalContext;
DbgPrint("APC selftest: alertable APC delivered arg1=0x%016llX arg2=0x%016llX irql=%u\n",
(uint64_t)systemArgument1,
(uint64_t)systemArgument2,
KeGetCurrentIrql());
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC ran above PASSIVE_LEVEL\n");
st->ApcDelivered++;
}
// Implements the apc Alertable Self Test Worker operation.
static void KiApcAlertableSelfTestWorker(void* arg) {
KI_APC_ALERTABLE_SELFTEST_STATE* st =
(KI_APC_ALERTABLE_SELFTEST_STATE*)arg;
DbgPrint("APC selftest: alertable worker ready, entering alertable wait\n");
KeSignalEvent(st->ReadyEvent);
KSTATUS s = KeWaitForEvent(st->WaitEvent, 1);
st->WaitStatus = s;
DbgPrint("APC selftest: alertable wait returned status=%u delivered=%d\n",
s, st->ApcDelivered);
if (s != NTLSTATUS_KERNEL_APC)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable wait returned wrong status=%u\n", s);
if (st->ApcDelivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC delivery count wrong=%d\n",
st->ApcDelivered);
KeSignalEvent(st->FinishedEvent);
KeExitThread(KeGetCurrentThread(), 0);
}
// Runs kernel Apc Self Test.
static void KiRunKernelApcSelfTest(void) {
DbgPrint("APC selftest: begin\n");
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: called above PASSIVE_LEVEL\n");
THREAD* self = KeGetCurrentThread();
if (!self)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: no current thread\n");
// Test 1: queue APC to current thread at PASSIVE_LEVEL.
{
KAPC apc;
volatile int count = 0;
KeInitializeApc(&apc,
self,
KiApcSelfTestKernelRoutine,
KiApcSelfTestNormalRoutine,
(void*)&count);
if (!KeInsertQueueApc(&apc, (void*)0x11111111, (void*)0x22222222))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: self queue failed\n");
if (count != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: self APC was not delivered immediately, count=%d\n", count);
DbgPrint("APC selftest: self APC passed\n");
}
// Test 2: disable kernel APCs, queue, then re-enable.
{
KAPC apc;
volatile int count = 0;
KeInitializeApc(&apc,
self,
KiApcSelfTestKernelRoutine,
KiApcSelfTestNormalRoutine,
(void*)&count);
KeEnterCriticalRegion();
if (!KeInsertQueueApc(&apc, (void*)0x33333333, (void*)0x44444444))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: deferred queue failed\n");
if (count != 0)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: APC delivered while critical region held, count=%d\n", count);
KeLeaveCriticalRegion();
if (count != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: deferred APC was not delivered after leave, count=%d\n", count);
DbgPrint("APC selftest: critical-region deferral passed\n");
}
// Test 3: queue APC to another blocked kernel thread, then wake it.
{
KI_APC_SELFTEST_STATE st;
KAPC apc;
memset(&st, 0, sizeof(st));
KSTATUS s;
s = KeEventCreate(EventAutoReset, 0, &st.ReadyEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: ReadyEvent create failed %d\n", s);
s = KeEventCreate(EventAutoReset, 0, &st.GoEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: GoEvent create failed %d\n", s);
s = KeEventCreate(EventAutoReset, 0, &st.DoneEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: DoneEvent create failed %d\n", s);
s = KeEventCreate(EventAutoReset, 0, &st.FinishedEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: FinishedEvent create failed %d\n", s);
const KE_THREAD_CREATE_PARAMETERS workerParameters = KE_THREAD_CREATE_NORMAL(PriorityNormal);
s = KeCreateKernelThread((uintptr_t)KiApcSelfTestWorker,
(uintptr_t)&st,
&workerParameters,
&st.WorkerThread);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker create failed %d\n", s);
s = KeWaitForEvent(st.ReadyEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: ready wait failed %d\n", s);
DbgPrint("APC selftest: worker ready, queueing cross-thread APC\n");
KeInitializeApc(&apc,
st.WorkerThread,
KiApcSelfTestKernelRoutine,
KiApcSelfTestCrossThreadRoutine,
(void*)&st);
if (!KeInsertQueueApc(&apc, (void*)0x55555555, (void*)0x66666666))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread queue failed\n");
if (st.CrossDelivered != 0)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread APC delivered before target resumed\n");
KeSignalEvent(st.GoEvent);
s = KeWaitForEvent(st.DoneEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: done wait failed %d\n", s);
if (st.CrossDelivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread delivery count wrong, count=%d\n",
st.CrossDelivered);
// The APC signals DoneEvent before the worker returns from the wait.
// Wait for an explicit worker-owned event before dropping stack-backed
// state and event references. THREAD.ExitEvent is not part of this
// kernel-thread contract on all builds.
s = KeWaitForEvent(st.FinishedEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker finished wait failed %d\n", s);
DbgPrint("APC selftest: cross-thread APC passed\n");
ObDereferenceObject(&st.ReadyEvent->Header);
ObDereferenceObject(&st.GoEvent->Header);
ObDereferenceObject(&st.DoneEvent->Header);
ObDereferenceObject(&st.FinishedEvent->Header);
ObDereferenceObject(&st.WorkerThread->Header);
}
// Test 4: queue APC to a thread blocked in an alertable wait.
// The APC itself must wake the waiter; no event signal is sent.
{
KI_APC_ALERTABLE_SELFTEST_STATE st;
KAPC apc;
memset(&st, 0, sizeof(st));
st.WaitStatus = NTLSTATUS_PENDING;
KSTATUS s;
s = KeEventCreate(EventAutoReset, 0, &st.ReadyEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert ReadyEvent create failed %d\n", s);
s = KeEventCreate(EventAutoReset, 0, &st.WaitEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert WaitEvent create failed %d\n", s);
s = KeEventCreate(EventAutoReset, 0, &st.FinishedEvent);
if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert FinishedEvent create failed %d\n", s);
const KE_THREAD_CREATE_PARAMETERS workerParameters = KE_THREAD_CREATE_NORMAL(PriorityNormal);
s = KeCreateKernelThread((uintptr_t)KiApcAlertableSelfTestWorker,
(uintptr_t)&st,
&workerParameters,
&st.WorkerThread);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable worker create failed %d\n", s);
s = KeWaitForEvent(st.ReadyEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert ready wait failed %d\n", s);
DbgPrint("APC selftest: queueing APC to alertable waiter\n");
KeInitializeApc(&apc,
st.WorkerThread,
KiApcSelfTestKernelRoutine,
KiApcAlertableSelfTestNormalRoutine,
(void*)&st);
if (!KeInsertQueueApc(&apc, (void*)(unsigned long long)0x77777777, (void*)(unsigned long long)0x88888888))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC queue failed\n");
s = KeWaitForEvent(st.FinishedEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert finished wait failed %d\n", s);
if (st.WaitStatus != NTLSTATUS_KERNEL_APC || st.ApcDelivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable result bad status=%u delivered=%d\n",
st.WaitStatus, st.ApcDelivered);
DbgPrint("APC selftest: alertable wait passed\n");
ObDereferenceObject(&st.ReadyEvent->Header);
ObDereferenceObject(&st.WaitEvent->Header);
ObDereferenceObject(&st.FinishedEvent->Header);
ObDereferenceObject(&st.WorkerThread->Header);
}
DbgPrint("APC selftest: PASS\n");
}
// IRP + kernel APC self-test.
typedef struct KI_IRP_APC_SELFTEST_STATE {
EVENT* CompletionEvent;
DEVICE_OBJECT* DiskDevice;
IRP Irp;
KAPC Apc;
uint8_t* Buffer;
volatile int ApcDelivered;
volatile KSTATUS ApcStatus;
volatile size_t ApcInformation;
} KI_IRP_APC_SELFTEST_STATE;
static void KiIrpApcSelfTestKernelRoutine(KAPC* apc,
void** normalRoutine,
void** normalContext,
void** systemArgument1,
void** systemArgument2) {
DbgPrint("IRP/APC selftest: kernel routine apc=0x%016llX irp=0x%016llX status=%u irql=%u\n",
(uint64_t)apc,
(uint64_t)*systemArgument1,
(uint32_t)(uintptr_t)*systemArgument2,
KeGetCurrentIrql());
// Leaves the APC's normal routine and arguments unchanged.
static void KiApcWaitRaceKernelRoutine(KAPC* apc,
void** normalRoutine,
void** normalContext,
void** systemArgument1,
void** systemArgument2) {
(void)apc;
(void)normalRoutine;
(void)normalContext;
(void)systemArgument1;
(void)systemArgument2;
}
static void KiIrpApcSelfTestNormalRoutine(void* normalContext,
void* systemArgument1,
void* systemArgument2) {
KI_IRP_APC_SELFTEST_STATE* st = (KI_IRP_APC_SELFTEST_STATE*)normalContext;
IRP* irp = (IRP*)systemArgument1;
KSTATUS status = (KSTATUS)(uintptr_t)systemArgument2;
DbgPrint("IRP/APC selftest: APC delivered irp=0x%016llX status=%u info=%llu irql=%u\n",
(uint64_t)irp,
status,
(uint64_t)(irp ? irp->Information : 0),
KeGetCurrentIrql());
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: normal routine ran above PASSIVE_LEVEL\n");
if (irp != &st->Irp)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: APC arg1 was not the submitted IRP\n");
st->ApcDelivered++;
st->ApcStatus = status;
st->ApcInformation = irp->Information;
// Records delivery for the prepared-wait race probe.
static void KiApcWaitRaceNormalRoutine(void* normalContext,
void* systemArgument1,
void* systemArgument2) {
(void)systemArgument1;
(void)systemArgument2;
KiAssertApcNormalContext("APC wait-race normal routine");
(*(volatile int*)normalContext)++;
}
// Runs irp Kernel Apc Self Test.
static void KiRunIrpKernelApcSelfTest(const HAL_API* hal) {
DbgPrint("IRP/APC selftest: begin\n");
// Reproduces the prepare-to-commit APC race deterministically.
static void KiRunApcWaitRaceSelfTest(void) {
DbgPrint("APC wait-race selftest: begin\n");
(void)hal;
if (!IoDiskDevicePresent(0)) {
DbgPrint("IRP/APC selftest: SKIP, drive 0 not present\n");
return;
}
THREAD* self = KeGetCurrentThread();
if (!self || KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "APC wait-race selftest: invalid execution context\n");
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: called above PASSIVE_LEVEL\n");
EVENT* waitEvent = (EVENT*)0;
KAPC apc;
volatile int delivered = 0;
KSTATUS status = KeEventCreate(EventAutoReset, 0, &waitEvent);
if (!KSUCCESS(status))
KePanic(KE_PANIC_CODE_SELFTEST, "APC wait-race selftest: event create failed %u\n", status);
KI_IRP_APC_SELFTEST_STATE st;
memset(&st, 0, sizeof(st));
KeInitializeApc(&apc, self, KiApcWaitRaceKernelRoutine,
KiApcWaitRaceNormalRoutine, (void*)&delivered);
KSTATUS s = KeEventCreate(EventAutoReset, 0, &st.CompletionEvent);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: completion event create failed %u\n", s);
uintptr_t flags = KeAcquireSpinlock(&waitEvent->Lock);
if (!KeInsertQueueApc(&apc, (void*)(uintptr_t)0x99999999u,
(void*)(uintptr_t)0xAAAAAAAAu))
KePanic(KE_PANIC_CODE_SELFTEST, "APC wait-race selftest: queue failed\n");
if (delivered != 0)
KePanic(KE_PANIC_CODE_SELFTEST, "APC wait-race selftest: delivered above PASSIVE_LEVEL\n");
st.Buffer = (uint8_t*)MmAllocatePool(512);
if (!st.Buffer)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: no buffer\n");
memset(st.Buffer, 0xCC, 512);
KePrepareBlockThread(self, &waitEvent->Header, 1);
KeListInsertTailChecked(&waitEvent->WaitList, &self->SchedulerLink);
KeSetThreadWaitList(self, &waitEvent->WaitList);
KeReleaseSpinlock(&waitEvent->Lock, flags);
KeInitializeApc(&st.Apc,
KeGetCurrentThread(),
KiIrpApcSelfTestKernelRoutine,
KiIrpApcSelfTestNormalRoutine,
(void*)&st);
status = KeCommitBlockThread(self, 1);
if (status != NTLSTATUS_KERNEL_APC || delivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST,
"APC wait-race selftest: bad result status=%u delivered=%d\n",
status, delivered);
st.DiskDevice = IoReferenceDiskDevice(0);
if (!st.DiskDevice)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: drive 0 disappeared before submit\n");
IoBuildReadWriteIrp(&st.Irp, IRP_MJ_READ, 0, 512, st.Buffer);
st.Irp.CompletionEvent = st.CompletionEvent;
st.Irp.CompletionApc = &st.Apc;
st.Irp.CompletionFn = (IRP_COMPLETION_FN)0;
st.Irp.CompletionCtx = (void*)0;
DbgPrint("IRP/APC selftest: submitting drive=0 lba=0 sectors=1\n");
s = IoSubmitIrp(st.DiskDevice, &st.Irp);
if (s != NTLSTATUS_PENDING)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: IoSubmitIrp returned %u\n", s);
s = KeWaitForEvent(st.CompletionEvent, 0);
if (!KSUCCESS(s))
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: completion wait failed %u\n", s);
// The wait return path should have delivered the pending kernel APC.
if (st.ApcDelivered != 1)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: APC was not delivered after I/O wait, count=%d\n",
st.ApcDelivered);
if (!KSUCCESS(st.Irp.Status) || !KSUCCESS(st.ApcStatus))
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: I/O failed irp=%u apc=%u info=%llu\n",
st.Irp.Status, st.ApcStatus, (uint64_t)st.Irp.Information);
if (st.Irp.Information != 512 || st.ApcInformation != 512)
KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: wrong byte count irp=%llu apc=%llu\n",
(uint64_t)st.Irp.Information, (uint64_t)st.ApcInformation);
DbgPrint("IRP/APC selftest: first bytes %02X %02X %02X %02X, tail %02X %02X\n",
st.Buffer[0], st.Buffer[1], st.Buffer[2], st.Buffer[3],
st.Buffer[510], st.Buffer[511]);
MmFreePool(st.Buffer);
if (st.DiskDevice) IoDereferenceDeviceObject(st.DiskDevice);
ObDereferenceObject(&st.CompletionEvent->Header);
DbgPrint("IRP/APC selftest: PASS\n");
ObDereferenceObject(&waitEvent->Header);
DbgPrint("APC wait-race selftest: PASS\n");
}
// Verifies that the PFN database tracks ownership, references, pins, and contiguous runs.
@@ -1510,7 +1134,8 @@ static void KiRunSynchronizationTimeoutSelfTest(void) {
"SYNC/TIMEOUT selftest: owner acquire failed status=%u\n", status);
THREAD* worker = (THREAD*)0;
const KE_THREAD_CREATE_PARAMETERS parameters = KE_THREAD_CREATE_REALTIME(12);
const KE_THREAD_CREATE_PARAMETERS parameters =
KE_THREAD_CREATE_NAMED_REALTIME(12, "selftest.sync.timeout");
status = KeCreateKernelThread((uintptr_t)KiSynchronizationTimeoutWorker,
(uintptr_t)&state,
&parameters,
@@ -1691,7 +1316,8 @@ static void KiRunRealtimeSchedulerSelfTest(void) {
"SCHED selftest: owner acquire failed status=%u\n", status);
THREAD* chainWorker = (THREAD*)0;
const KE_THREAD_CREATE_PARAMETERS chainParameters = KE_THREAD_CREATE_NORMAL(PriorityNormal);
const KE_THREAD_CREATE_PARAMETERS chainParameters =
KE_THREAD_CREATE_NAMED_NORMAL(PriorityNormal, "selftest.sched.chain");
status = KeCreateKernelThread((uintptr_t)KiSchedulerChainWorker,
(uintptr_t)&state,
&chainParameters,
@@ -1713,7 +1339,8 @@ static void KiRunRealtimeSchedulerSelfTest(void) {
"SCHED selftest: mutex cycle was not rejected status=%u\n", status);
THREAD* realtimeWorker = (THREAD*)0;
const KE_THREAD_CREATE_PARAMETERS realtimeParameters = KE_THREAD_CREATE_REALTIME(16);
const KE_THREAD_CREATE_PARAMETERS realtimeParameters =
KE_THREAD_CREATE_NAMED_REALTIME(16, "selftest.sched.rt");
status = KeCreateKernelThread((uintptr_t)KiSchedulerRealtimeWorker,
(uintptr_t)&state,
&realtimeParameters,
@@ -1895,10 +1522,11 @@ void KiRunEarlyKernelSelfTests(void) {
// Runs kernel Self Tests.
void KiRunKernelSelfTests(const HAL_API* hal) {
(void)hal;
DbgPrint("Kernel selftests: begin\n");
KiRunSynchronizationTimeoutSelfTest();
KiRunRealtimeSchedulerSelfTest();
KiRunKernelApcSelfTest();
KiRunApcWaitRaceSelfTest();
KiRunPfnDatabaseSelfTest();
KiRunDmaSelfTest();
KiRunMemoryMappingSelfTest();
@@ -1907,7 +1535,6 @@ void KiRunKernelSelfTests(const HAL_API* hal) {
KiRunVadSwapSelfTest();
KiRunStringViewSelfTest();
KiRunVolumeRelativePathSelfTest();
KiRunIrpKernelApcSelfTest(hal);
KiRunAsyncFileIoSelfTest();
KiRunTrapFrameSelfTest();
DbgPrint("Kernel selftests: PASS\n");