parallel compile, SMP, swapgs, cleanup, remove useless Reserved fields

This commit is contained in:
maksw committed 2026-05-30 11:18:46 +02:00
1 parent b17c9ac854
commit bfe2b55142
42 files changed
+2131 -426

No files matched your search

+89 -20
View File
@@ -3,18 +3,48 @@
#include <stdint.h>
#include <string.h>
#include <ntlite/ddi/hal_api.h>
#include <kernel/hal/hal_apic.h>
#include <intrin.h>
#include <kernel/ke_debug.h>
#include <kernel/ke_cpu.h>
#include <kernel/ke_spinlock.h>
#include <kernel/ke_process.h>
#include <kernel/ke_thread.h>
#include <kernel/ke_sched.h>
#include <kernel/mm_virt.h>
#include <common/printf.h>
int _fltused; // fuckass
int _fltused; // MSVC floating-point helper anchor
int gDebugEnabled = 0;
void (*PrintChar)(char, uint32_t, uint32_t);
static volatile long gPanicInProgress = 0;
static volatile long gPanicStoppedCpuCount = 0;
static _Noreturn void KiPanicSecondaryHalt(void) {
_disable();
_InterlockedIncrement(&gPanicStoppedCpuCount);
for (;;) __halt();
}
static int KiPanicIsActive(void) {
return _InterlockedCompareExchange((volatile long*)&gPanicInProgress, 0, 0) != 0;
}
// Returning NMI handler used for SMP control IPIs. Panic NMIs stop the
// target CPU permanently; TLB shootdown NMIs flush and return. A genuinely
// unexpected NMI is not handled here and will fall through to the normal fault
// path in the assembly stub.
__declspec(dllexport) int KeHandleNmiIpi(void) {
if (KiPanicIsActive())
KiPanicSecondaryHalt();
if (MmHandleTlbShootdownNmi())
return 1;
return 0;
}
void KiKernelPutChar(char c) {
PrintChar(c, 0x00FF00, 0x000000);
}
@@ -39,26 +69,48 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) {
// KePanic
__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...) {
// Silence! Stop the world!
// Silence this CPU first.
_disable();
// Print a bright-red banner so the framebuffer is unmistakable.
// We call PrintChar directly so we can set a red foreground.
// (DbgPrint uses green; we want this visually distinct.)
static const char banner[] = "\n*** KERNEL PANIC ***\n";
for (const char* p = banner; *p; p++)
PrintChar(*p, 0xFF2222, 0x000000);
// Only one CPU owns the visible panic report. CPUs that fault while the
// system is already panicking immediately join the stopped set.
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) != 0) {
KiPanicSecondaryHalt();
}
// Print the panic code first, then the caller's message through the normal vprintf path.
printf("Panic code: %d\n", code);
// Stop every other CPU as early as possible. This uses an NMI IPI so it
// still reaches CPUs with IF cleared inside spinlock/high-IRQL regions.
HalApicSendPanicIpi();
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
va_end(va);
if (PrintChar) {
// Print a bright-red banner so the framebuffer is unmistakable.
static const char banner[] = "\n*** KERNEL PANIC ***\n";
const char* p;
KCPU* cpu = KeGetCurrentCpu();
THREAD* thread = KeGetCurrentThread();
// Die!
while (true) __halt();
for (p = banner; *p; p++)
PrintChar(*p, 0xFF2222, 0x000000);
printf("Panic code: %d\n", code);
if (cpu) {
printf("Panic CPU: %u LAPIC=%u",
(unsigned)cpu->CpuIndex,
(unsigned)cpu->LapicId);
if (thread)
printf(" thread=%p tid=%llu",
thread,
(unsigned long long)thread->ThreadId);
printf("\n");
}
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
va_end(va);
}
for (;;) __halt();
}
// KePrintConsole - write user-visible console text in white-on-black.
@@ -434,6 +486,11 @@ _Noreturn void KeBugCheckProcess(int vector, uintptr_t rip, uintptr_t errCode, u
}
__declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* frame) {
// Panic NMIs are broadcast to stop all other CPUs. Do not try to decode
// the interrupted context on a secondary CPU once another CPU owns panic.
if (KiPanicIsActive())
KiPanicSecondaryHalt();
THREAD* thread = KeGetCurrentThread();
PROCESS* proc = thread ? thread->Owner : (PROCESS*)0;
@@ -453,14 +510,26 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr
(unsigned long long)frame->ErrorCode,
(unsigned long long)frame->Cr2);
} else if (KiFaultHasErrorCode(vector)) {
KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx | Code: %04llx\n",
const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip;
KePanic(KE_PANIC_CODE_FAULT,
"PANIC: %s | RIP: %016llx | Code: %04llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n",
name,
(unsigned long long)frame->Rip,
(unsigned long long)frame->ErrorCode);
(unsigned long long)frame->ErrorCode,
(unsigned long long)frame->Cs,
(unsigned long long)frame->Rflags,
(unsigned long long)frame->Rsp,
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]);
} else {
KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx\n",
const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip;
KePanic(KE_PANIC_CODE_FAULT,
"PANIC: %s | RIP: %016llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n",
name,
(unsigned long long)frame->Rip);
(unsigned long long)frame->Rip,
(unsigned long long)frame->Cs,
(unsigned long long)frame->Rflags,
(unsigned long long)frame->Rsp,
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]);
}
}