kernel
Loading...
Searching...
No Matches
handlers.c
Go to the documentation of this file.
1/*
2 * PROJECT: MatanelOS Kernel
3 * LICENSE: NONE
4 * PURPOSE: Implementation of handler functions for interrupts.
5 */
6
7#include "../../includes/mh.h"
8#include "../../includes/me.h"
9#include "../../includes/mg.h"
10#include "../../includes/ps.h"
11#include "../../includes/md.h"
13
14#define PRINT_ALL_REGS_AND_HALT(ctxptr, intfrptr) \
15 do { \
16 gop_printf(COLOR_RED, \
17 "RAX=%p RBX=%p RCX=%p RDX=%p\n" \
18 "RSI=%p RDI=%p RBP=%p RSP=%p\n" \
19 "R8 =%p R9 =%p R10=%p R11=%p\n" \
20 "R12=%p R13=%p R14=%p R15=%p\n" \
21 "RIP=%p RFLAGS=%p\n", \
22 (ctxptr)->rax, (ctxptr)->rbx, (ctxptr)->rcx, (ctxptr)->rdx, \
23 (ctxptr)->rsi, (ctxptr)->rdi, (ctxptr)->rbp, (intfrptr)->rsp, \
24 (ctxptr)->r8, (ctxptr)->r9, (ctxptr)->r10, (ctxptr)->r11, \
25 (ctxptr)->r12, (ctxptr)->r13, (ctxptr)->r14, (ctxptr)->r15, \
26 (intfrptr)->rip, (intfrptr)->rflags); \
27 __hlt(); \
28 } while (0)
29
30// NOTE TO SELF: DO NOT PUT TRACELAST_FUNC HERE, THESE ARE INTERRUPT/EXCEPTION HANDLERS!
31
32
33extern uint32_t cursor_x;
34extern uint32_t cursor_y;
36
37static void MiHandleTimer(bool schedulerEnabled, PTRAP_FRAME trap) {
39
40 // Do not decrement if a schedule is already pending.
41 if (cpu->schedulePending) return;
42
43 // If scheduler is locked or no thread is running, return.
44 if (!schedulerEnabled || !cpu->currentThread) return;
45
46 PITHREAD currentThread = cpu->currentThread;
47
48 // Atomic decrement, if there is still time, return.
49 if (__sync_sub_and_fetch(&currentThread->TimeSlice, 1) > 0) {
50 return;
51 }
52
53 // Time slice has expired
54 // Reset Quantum
55 currentThread->TimeSlice = currentThread->TimeSliceAllocated;
56
57 // Save the thread's context.
58 currentThread->TrapRegisters = *trap;
59
60 // Request schedule.
61 cpu->schedulePending = true;
62}
63
64extern void lapic_eoi(void);
65
66void MiLapicInterrupt(bool schedulerEnabled, PTRAP_FRAME trap) {
67 MiHandleTimer(schedulerEnabled, trap);
68 lapic_eoi(); // Signal end of interrupt.
69}
70
72 void
73)
74
75/*++
76
77 Routine description : Handles an interprocessor interupt.
78
79 Arguments:
80
81 None. (arguments to IPI's are taken from the PROCESSOR struct, accessed in MeGetCurrentProcessor)
82
83 Return Values:
84
85 None.
86
87--*/
88
89{
92 uint64_t addr = cpu->IpiParameter.debugRegs.address;
93 CPU_ACTION action = cpu->IpiAction;
94 int idx = find_available_debug_reg();
95 switch (action) {
96 case CPU_ACTION_STOP:
97 // explicit action to halt, since we are in an interrupt, unless an NMI somehow comes, we will stay stopped.
98 // clear the flag before we halt so BSP can continue iterations
99 cpu->IpiSeq = 0;
102 __cli();
103 for (;;) __hlt();
106 break;
108 gop_printf(COLOR_RED, "[CPU-IPI] Hello from CPU ID: %d\n", cpu->lapic_ID);
109 break;
111 if (idx == -1) break;
116 break;
118 for (int i = 0; i < 4; i++) {
119 if ((uint64_t)MeGetCurrentProcessor()->DebugEntry[i].Address == addr) {
120 __write_dr(i, 0);
121
122 /* Clear DR7 bits for this index (local enable and RW/LEN group) */
123 uint64_t dr7 = __read_dr(7);
124 /* clear local enable bit */
125 dr7 &= ~(1ULL << (i * 2));
126 /* clear RW/LEN 4-bit group */
127 uint64_t mask = 0xFULL << (16 + 4 * i);
128 dr7 &= ~mask;
129 __write_dr(7, dr7);
130
131 /* Clear status DR6 too */
132 __write_dr(6, 0);
135 break;
136 }
137 }
139 // This is a NO-OP, since DPCs WILL be executed when we just return.
140 // unused.
141 break;
144 break;
145 }
146
148 cpu->IpiSeq = 0;
150
151 // End of Interrupt for LAPIC is signaled at function return.
152}
153
154void
156 IN PTRAP_FRAME trap
157)
158
159/*++
160
161 Routine description : Handles a page fault that occured in the current CPU.
162
163 Arguments:
164
165 Pointer to the current TRAP_FRAME.
166
167 Return Values:
168
169 None. Function would bugcheck/return if conditions are met.
170
171--*/
172
173{
174 uint64_t fault_addr;
175 // cr2 holds the faulty address that caused the page fault.
176
177 __asm__ __volatile__ (
178 "movq %%cr2, %0"
179 : "=r"(fault_addr)
180 );
181
182 /*++
183
184 Page fault bugcheck parameters:
185
186 Parameter 1: Memory address referenced. (CR2)
187 Parameter 2: (decimal) 0 - Read Operation, 2 - Write Operation, 10 - Execute operation
188 Parameter 3: Address that referenced memory (RIP)
189 Parameter 4: CPU Error code pushed.
190
191 --*/
192
193
194 PRIVILEGE_MODE PreviousMode = MeGetPreviousMode();
195 MTSTATUS status = MmAccessFault(trap->error_code, fault_addr, PreviousMode, trap);
196#ifdef DEBUG
197 gop_printf(COLOR_RED, "I have returned from MmAccessFault with status %x\n", status);
198#endif
199
200 if (MT_FAILURE(status)) {
201 // If MmAccessFault returned a failire (e.g MT_ACCESS_VIOLATION), but hasn't bugchecked, we check for exception handlers in the current thread
202 // If there are no exceptions handlers (for user mode, we check the FS exception (todo TEB)) (for kernel mode we check the section by linker script)
203 // - For user mode, thread termination, for kernel mode - bugcheck with KMODE_EXCEPTION_NOT_HANDLED.
204
205 // Set thread last exception status.
206 PsGetCurrentThread()->LastStatus = status;
207
208 if (PreviousMode == UserMode) {
209#if 0
210 if (false);
211 /* Unimplemented yet.
212 if (ExpIsExceptionHandlerPresent(PsGetCurrentThread())) {
213 ExpDispatchException(trap);
214 return;
215 }
216 */
217 else {
218#endif
219 // Terminate thread that caused violation.
221 // We arent allowed to continue.
223 return;
224#if 0
225 }
226#endif
227 }
228 else {
229 // Kernel mode, we see if we have an exception handler for this.
230 uint64_t HandlerAddress = ExpFindKernelModeExceptionHandler(trap->rip);
231 if (HandlerAddress != 0) {
232 // We found an exception handler! We return to it now.
233 trap->rip = HandlerAddress;
234 return;
235 }
236 }
237
238 // No handler found for the kernel mode violation, we bugcheck.
241 (void*)(uintptr_t)status,
242 (void*)fault_addr,
243 (void*)trap->rip,
244 (void*)trap->error_code
245 );
246 }
247
248 // MmAccessFault returned MT_SUCCESS, that means it handled the fault (filled the PTE, etc.), we return to original instruction and re-run.
249 return;
250}
251
253void
255 IN PTRAP_FRAME trap
256)
257
258/*++
259
260 Routine description : Handles a double fault exception that has happened on the current CPU.
261
262 Arguments:
263
264 Pointer to the current TRAP_FRAME.
265
266 Return Values:
267
268 None. This function will never return to caller.
269
270--*/
271
272{
273 /*++
274
275 Double Fault bugcheck parameters:
276
277 Parameter 1: Address at the time of the fault.
278 Parameter 2,3,4: NULL.
279
280 --*/
281
282 MeBugCheckEx(DOUBLE_FAULT, (void*)(uintptr_t)trap->rip, NULL, NULL, NULL);
283}
284
285void
287 PTRAP_FRAME trap
288)
289
290/*++
291
292 Routine description : Handles a divide by zero on the current CPU.
293
294 Arguments:
295
296 Pointer to the current TRAP_FRAME.
297
298 Return Values:
299
300 None. This function currently does not return to caller.
301
302--*/
303
304{
305
306 /*++
307
308 Divide By Zero bugcheck parameters:
309
310 Parameter 1: Address at the time of the fault.
311 Parameter 2,3,4: NULL.
312
313 --*/
314
315 // When user mode processes and threads are fully established, this should generate an ACCESS_VIOLATION. TODO
316 if (MeGetPreviousMode() == UserMode) {
318 // We arent allowed to continue.
320 }
321
322 MeBugCheckEx(DIVIDE_BY_ZERO, (void*)(uintptr_t)trap->rip, NULL, NULL, NULL);
323
324}
325
326void
328 PTRAP_FRAME trap
329)
330
331/*++
332
333 Routine description : Handles a debug trap (either a single step from a debugger, or a debug register has been hit)
334
335 Arguments:
336
337 Pointer to the current TRAP_FRAME.
338
339 Return Values:
340
341 None.
342
343--*/
344
345{
346#ifndef GDB
347 /* read debug status */
348 uint64_t dr6 = __read_dr(6);
349
350 if (dr6 & 0xF) {
351 /* For each possible debug register 0..3 check B0..B3 */
352 for (int i = 0; i < 4; ++i) {
353 if (dr6 & (1ULL << i)) {
354 /* If a callback is registered, call it. Provide both address and context. */
355 if (MeGetCurrentProcessor()->DebugEntry[i].Callback) {
356 DBG_CALLBACK_INFO info = {
358 .trap = trap,
359 .BreakIdx = i,
360 .Dr6 = dr6
361 };
362
363 /* Call the user-registered callback. It receives &info (void*). */
365 }
366 else {
367 /* no callback registered for this DRx: print for debug and continue */
368 gop_printf(0xFFFFFF00, "DEBUG: DR%d fired at addr %p but no callback\n", i, (void*)__read_dr(i));
369 }
370 }
371 }
372
373 /* Clear the status bits in DR6 so INT1 won't fire again for the same event.
374 Writing zero clears B0..B3 and other status bits per Intel spec. */
375 __write_dr(6, 0);
376 return;
377 }
378 else if (dr6 & (1 << 14)) {
379 // Single Step. -- Ignore for now, we don't have a custom debugger yet, and QEMU sets its own.
380 return;
381 }
382#else
384 __write_DR(6, 0);
385 return;
386#endif
387}
388
390void
392 PTRAP_FRAME trap
393)
394
395/*++
396
397 Routine description : Handles an NMI (Non Maskable Interrupt), generated by the CPU.
398
399 Arguments:
400
401 Pointer to the current TRAP_FRAME.
402
403 Return Values:
404
405 None. This function will never return.
406
407--*/
408
409{
410 /*++
411
412 NMI bugcheck parameters:
413
414 No Parameters.
415
416 --*/
419}
420
422 PTRAP_FRAME trap
423)
424
425/*++
426
427 Routine description : Handles a breakpoint instruction (INT3)
428
429 Arguments:
430
431 Pointer to the current TRAP_FRAME.
432
433 Return Values:
434
435 None.
436
437--*/
438
439
440{
441 gop_printf(COLOR_RED, "**INT3 Breakpoint hit at: %p. PreviousMode: %d**\n", (void*)(uintptr_t)trap->rip, MeGetPreviousMode());
442}
443
445 MeBugCheckEx(OVERFLOW, (void*)trap->rip, NULL, NULL, NULL);
446}
447
449 // bugcheck too, this is kernel mode.
450 MeBugCheckEx(BOUNDS_CHECK, (void*)trap->rip, NULL, NULL, NULL);
451}
452
454 MeBugCheckEx(INVALID_OPCODE, (void*)trap->rip, NULL, NULL, NULL);
455}
456
458 // rarely triggered, if a floating point chip is not integrated, or is not attached, bugcheck.
459 MeBugCheckEx(NO_COPROCESSOR, (void*)trap->rip, NULL, NULL, NULL);
460}
461
463 // quite literally impossible in protected or long mode, since CPU's don't generate this exception on these modes, but if they did, bugcheck, severe code.
464 MeBugCheckEx(COPROCESSOR_SEGMENT_OVERRUN, (void*)trap->rip, NULL, NULL, NULL);
465}
466
468 // a tss is when the CPU hardware switches (usually does not happen, since OS'es implement switching in software, like process timer context switch, all in software)
469 // if it did happen though, we bugcheck.
470 MeBugCheckEx(INVALID_TSS, (void*)trap->rip, NULL, NULL, NULL);
471}
472
474 // this happens when the CPU loads a segment that points to a valid descriptor, that is marked as "not present" (that the present bit is 0), which means it's swapped out to disk.
475 // we don't have disk paging right now, we don't even have a current user mode or stable memory for now, so we just bugcheck.
476 MeBugCheckEx(SEGMENT_SELECTOR_NOTPRESENT, (void*)trap->rip, NULL, NULL, NULL);
477}
478
480 // this happens when the stack pointer (esp, rsp, sp on 16 bit) moves OUTSIDE the bounds of the current stack segment, this is different from a stack overflow at the software level, this is a hardware level exception.
481 // segment limits on protected mode usually gets switched off, so if this happens just bugcheck.
482 MeBugCheckEx(STACK_SEGMENT_OVERRUN, (void*)trap->rip, NULL, NULL, NULL);
483}
484
486 PETHREAD Thread = PsGetCurrentThread();
487 if (MeGetPreviousMode() == KernelMode) {
488 // important exception, view error code and bugcheck with it
489 // its also a very useless exception, as a general protection fault is the most
490 // general thing in the world, like the word general was made for this fault
491 // why? because it supplies 0 information at what could be a plathera of violations the thread could have done.
492 // we have to examine the RIP to actually see wtf did it.
493 // (hi guys im the cpu and i supply the segment where this happened, i hope its useful and all!!!)
494 MeBugCheckEx(GENERAL_PROTECTION_FAULT, (void*)(uintptr_t)trap->rip, (void*)(uintptr_t)trap->error_code, NULL, NULL);
495 }
496
497 // User thread (and mode), we send an exception.
498 // TODO Exceptions.
499 // For now, terminate the user thread.
501
502 // Enable access to user mode memory so we dont page fault on accessing its RIP.
503 if (MI_IS_CANONICAL_ADDR((uintptr_t)trap->rip)) {
504 __stac();
505 if (ExpIsPrivilegedInstruction((uint8_t*)trap->rip)) {
507 }
508 else {
509 Status = MT_ACCESS_VIOLATION; // Access violation, its probably a non canonical address.
510 }
511 __clac();
512 }
513
514 // Terminate the thread, todo exp.
515 // We must not return to the thread, at all.
516 Thread->InternalThread.TimeSlice = 1;
519 gop_printf(COLOR_RED, "[TERMINATE-#GPF] Terminating thread (%s) %p for %lx | RIP: %p\n", (Thread->SystemThread) ? "Kernel Mode" : "User Mode", Thread, (unsigned long)Status, (void*)(uintptr_t)trap->rip);
520 PsTerminateThread(Thread, Status);
521}
522
525 // this occurs when a floating point operation has an error, (even division by zero floating point will get here), or underflow/overflow
526 gop_printf(0xFFFF0000, "Error: Floating Point error, have you done a correct calculation?\n");
527}
528
530 // 3 conditions must be met in-order for this to even reach.
531 // CR0.AM (Alignment Mask) must be set to 1.
532 // EFLAGS.AC (Alignment Check) must be set to 1.
533 // CPL (user mode or kernel mode) must be set to 3. (user mode only)
534 // If all are 1 and a stack alignment occurs (when doing char* ptr = kmalloc(64, 16); then writing like this *((uint32_t*)ptr) = 0xdeadbeef; // It's an unaligned write, writing more than there is.
535 // for now, bugcheck.
536 MeBugCheckEx(ALIGNMENT_CHECK, (void*)trap->rip, NULL, NULL, NULL);
537}
538
540 // creepy.
541 // This happens when the machine has a SEVERE problem, memory faults, CPU internal fault, all of that, the cpu registers this.
542 // obviously bugcheck.
543 MeBugCheckEx(SEVERE_MACHINE_CHECK, (void*)trap->rip, NULL, NULL, NULL);
544}
545
#define NORETURN
Definition annotations.h:14
#define IN
Definition annotations.h:8
FORCEINLINE uint64_t InterlockedAndU64(volatile uint64_t *target, uint64_t value)
Definition atomic.h:140
FORCEINLINE uint64_t InterlockedOrU64(volatile uint64_t *target, uint64_t value)
Definition atomic.h:150
NORETURN void MeBugCheck(IN enum _BUGCHECK_CODES BugCheckCode)
Definition bugcheck.c:220
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
Definition bugcheck.c:245
uint32_t cursor_y
Definition gop.c:44
GOP_PARAMS gop_local
Definition gop.c:223
uint32_t cursor_x
Definition gop.c:44
PROCESSOR * PPROCESSOR
Definition core.h:48
ITHREAD * PITHREAD
Definition core.h:36
TRAP_FRAME * PTRAP_FRAME
Definition core.h:56
ETHREAD * PETHREAD
Definition core.h:44
int find_available_debug_reg(void)
struct _GOP_PARAMS GOP_PARAMS
uint64_t ExpFindKernelModeExceptionHandler(uint64_t Rip)
Definition exception.c:114
MTSTATUS MmAccessFault(IN uint64_t FaultBits, IN uint64_t VirtualAddress, IN PRIVILEGE_MODE PreviousMode, IN PTRAP_FRAME TrapFrame)
Definition fault.c:28
void gop_printf(uint32_t color, const char *fmt,...)
Definition gop.c:633
void MiBreakpoint(PTRAP_FRAME trap)
Definition handlers.c:421
void MiNoCoprocessor(PTRAP_FRAME trap)
Definition handlers.c:457
void MiBoundsCheck(PTRAP_FRAME trap)
Definition handlers.c:448
NORETURN void MiNonMaskableInterrupt(PTRAP_FRAME trap)
Definition handlers.c:391
void MiAlignmentCheck(PTRAP_FRAME trap)
Definition handlers.c:529
void MiDebugTrap(PTRAP_FRAME trap)
Definition handlers.c:327
void lapic_eoi(void)
Definition apic.c:136
void MiInvalidTss(IN PTRAP_FRAME trap)
Definition handlers.c:467
void MiInvalidOpcode(PTRAP_FRAME trap)
Definition handlers.c:453
void MiStackSegmentOverrun(PTRAP_FRAME trap)
Definition handlers.c:479
void MiCoprocessorSegmentOverrun(PTRAP_FRAME trap)
Definition handlers.c:462
void MiMachineCheck(PTRAP_FRAME trap)
Definition handlers.c:539
void MiPageFault(IN PTRAP_FRAME trap)
Definition handlers.c:155
NORETURN void MiDoubleFault(IN PTRAP_FRAME trap)
Definition handlers.c:254
void MiLapicInterrupt(bool schedulerEnabled, PTRAP_FRAME trap)
Definition handlers.c:66
void MiGeneralProtectionFault(PTRAP_FRAME trap)
Definition handlers.c:485
void MiDivideByZero(PTRAP_FRAME trap)
Definition handlers.c:286
void MiFloatingPointError(PTRAP_FRAME trap)
Definition handlers.c:523
void MiOverflow(PTRAP_FRAME trap)
Definition handlers.c:444
void MiInterprocessorInterrupt(void)
Definition handlers.c:71
void MiSegmentSelectorNotPresent(PTRAP_FRAME trap)
Definition handlers.c:473
bool ExpIsPrivilegedInstruction(uint8_t *Ip)
Definition instruction.c:4
FORCEINLINE uint64_t __read_dr(int reg)
Definition intrin.h:124
FORCEINLINE void invlpg(void *m)
Definition intrin.h:205
FORCEINLINE void __hlt(void)
Definition intrin.h:65
#define UNREFERENCED_PARAMETER(x)
Definition intrin.h:29
FORCEINLINE void __write_dr(int reg, uint64_t val)
Definition intrin.h:139
FORCEINLINE void __cli(void)
Definition intrin.h:43
FORCEINLINE void __write_cr3(uint64_t val)
Definition intrin.h:98
FORCEINLINE void __stac(void)
Definition intrin.h:48
FORCEINLINE uint64_t __read_cr3(void)
Definition intrin.h:93
FORCEINLINE void __clac(void)
Definition intrin.h:53
@ OVERFLOW
Definition me.h:73
@ SEVERE_MACHINE_CHECK
Definition me.h:87
@ COPROCESSOR_SEGMENT_OVERRUN
Definition me.h:78
@ NO_COPROCESSOR
Definition me.h:76
@ KMODE_EXCEPTION_NOT_HANDLED
Definition me.h:118
@ DIVIDE_BY_ZERO
Definition me.h:69
@ ALIGNMENT_CHECK
Definition me.h:86
@ NON_MASKABLE_INTERRUPT
Definition me.h:71
@ INVALID_OPCODE
Definition me.h:75
@ INVALID_TSS
Definition me.h:79
@ DOUBLE_FAULT
Definition me.h:77
@ STACK_SEGMENT_OVERRUN
Definition me.h:81
@ GENERAL_PROTECTION_FAULT
Definition me.h:82
@ SEGMENT_SELECTOR_NOTPRESENT
Definition me.h:80
@ BOUNDS_CHECK
Definition me.h:74
struct _DBG_CALLBACK_INFO DBG_CALLBACK_INFO
FORCEINLINE PPROCESSOR MeGetCurrentProcessor(void)
Definition me.h:369
FORCEINLINE PRIVILEGE_MODE MeGetPreviousMode(void)
Definition me.h:568
@ CPU_DOING_IPI
Definition me.h:224
#define COLOR_RED
Colors definitions for easier access.
Definition mg.h:30
@ CPU_ACTION_DO_DEFERRED_ROUTINES
Definition mh.h:94
@ CPU_ACTION_WRITE_DEBUG_REGS
Definition mh.h:92
@ CPU_ACTION_STOP
Definition mh.h:89
@ CPU_ACTION_CLEAR_DEBUG_REGS
Definition mh.h:93
@ CPU_ACTION_FLUSH_CR3
Definition mh.h:95
@ CPU_ACTION_PERFORM_TLB_SHOOTDOWN
Definition mh.h:91
@ CPU_ACTION_PRINT_ID
Definition mh.h:90
uint64_t Address
Definition mh.h:4
enum _CPU_ACTION CPU_ACTION
#define MI_IS_CANONICAL_ADDR(va)
Definition mm.h:219
#define MmFullBarrier()
Definition mm.h:250
enum _PRIVILEGE_MODE PRIVILEGE_MODE
@ KernelMode
Definition mm.h:371
@ UserMode
Definition mm.h:372
#define MT_PRIVILEGED_INSTRUCTION
Definition mtstatus.h:134
#define MT_FAILURE(Status)
Definition mtstatus.h:16
int32_t MTSTATUS
Definition mtstatus.h:12
#define MT_INTEGER_DIVIDE_BY_ZERO
Definition mtstatus.h:136
#define MT_ACCESS_VIOLATION
Definition mtstatus.h:131
DebugCallback Callback
Definition me.h:146
void * Address
Definition me.h:145
uint64_t address
Definition mh.h:390
uint64_t dr7
Definition mh.h:389
DebugCallback callback
Definition mh.h:391
struct _ITHREAD InternalThread
Definition ps.h:183
bool SystemThread
Definition ps.h:200
MTSTATUS LastStatus
Definition ps.h:199
struct _PAGE_PARAMETERS pageParams
Definition mh.h:400
struct _DEBUG_REGISTERS debugRegs
Definition mh.h:399
enum _TimeSliceTicks TimeSlice
Definition me.h:272
struct _TRAP_FRAME TrapRegisters
Definition me.h:267
enum _TimeSliceTicks TimeSliceAllocated
Definition me.h:273
uint64_t addressToInvalidate
Definition mh.h:395
volatile IPI_PARAMS IpiParameter
Definition me.h:302
struct _DEBUG_ENTRY DebugEntry[4]
Definition me.h:336
uint32_t lapic_ID
Definition me.h:288
struct _ITHREAD * currentThread
Definition me.h:285
volatile uint64_t flags
Definition me.h:294
volatile uint64_t IpiSeq
Definition me.h:300
enum _CPU_ACTION IpiAction
Definition me.h:301
bool schedulePending
Definition me.h:295
uint64_t rip
Definition me.h:160
uint64_t error_code
Definition me.h:159
MTSTATUS PsTerminateThread(IN PETHREAD Thread, IN MTSTATUS ExitStatus)
Definition thread.c:284
PETHREAD PsGetCurrentThread(void)
Definition thread.c:279