parallel compile, SMP, swapgs, cleanup, remove useless Reserved fields
This commit is contained in:
1 parent
b17c9ac854
commit
bfe2b55142
42 files changed
+2131
-426
No files matched your search
+89
-20
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user