Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ia32trap.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Module Name: 00004 00005 ia32trap.c 00006 00007 Abstract: 00008 00009 This module contains iA32 trap handling code. 00010 Only used by kernel. 00011 00012 Fault can ONLY be initiated from user mode code. There is no support 00013 for iA32 code in the kernel mode. 00014 00015 For common pratice, we always return to the caller (lower level fault 00016 handler) and have the system do a normal ia64 exception dispatch. The 00017 wow64 code takes that exception and passes it back to the ia32 code 00018 as needed. 00019 00020 Revision History: 00021 00022 1 Feb. 1999 Initial Version 00023 00024 --*/ 00025 00026 // Get all the iadebugging stuff for now. 00027 #define IADBG 1 00028 00029 #include "ki.h" 00030 #include "ia32def.h" 00031 00032 BOOLEAN KiUnalignedFault (IN PKTRAP_FRAME TrapFrame); 00033 00034 00035 VOID 00036 KiIA32CommonArgs ( 00037 IN PKTRAP_FRAME Frame, 00038 IN ULONG ExceptionCode, 00039 IN PVOID ExceptionAddress, 00040 IN ULONG_PTR Argument0, 00041 IN ULONG_PTR Argument1, 00042 IN ULONG_PTR Argument2 00043 ) 00044 /*++ 00045 00046 Routine Description 00047 This routine sets up the ExceptionFrame 00048 00049 Arguments: 00050 Frame - Supply a pointer to an iA32 TrapFrame 00051 00052 ExceptionCode - Supplies a Exception Code 00053 00054 ExceptionAddress - Supplies a pointer to user exception address 00055 00056 Argument0, Argument1, Argument2 - Possible ExceptionInformation 00057 00058 Return: 00059 Nothing 00060 --*/ 00061 { 00062 PEXCEPTION_RECORD ExceptionRecord; 00063 00064 ExceptionRecord = (PEXCEPTION_RECORD)&Frame->ExceptionRecord; 00065 00066 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL; 00067 00068 ExceptionRecord->ExceptionCode = ExceptionCode; 00069 ExceptionRecord->ExceptionFlags = 0; 00070 ExceptionRecord->ExceptionAddress = ExceptionAddress; 00071 ExceptionRecord->NumberParameters = 5; 00072 00073 ExceptionRecord->ExceptionInformation[0] = Argument0; 00074 ExceptionRecord->ExceptionInformation[1] = Argument1; 00075 ExceptionRecord->ExceptionInformation[2] = Argument2; 00076 ExceptionRecord->ExceptionInformation[3] = (ULONG_PTR)Frame->StIIPA; 00077 ExceptionRecord->ExceptionInformation[4] = (ULONG_PTR)Frame->StISR; 00078 } 00079 00080 BOOLEAN 00081 KiIA32ExceptionDivide( 00082 IN PKTRAP_FRAME Frame 00083 ) 00084 /*++ 00085 00086 Routine Description: 00087 iA-32_Exception(Divide) - fault 00088 00089 Handle divide error fault. 00090 00091 Called from iA32_Exception() with 00092 ISR.vector : 0 00093 00094 The divide error fault occurs if a DIV or IDIV instructions is 00095 executed with a divisor of 0, or if the quotient is too big to 00096 fit in the result operand. 00097 00098 An INTEGER DIVIDED BY ZERO exception will be raised for the fault. 00099 The Faults can only come from user mode. 00100 00101 Arguments: 00102 Frame - Supply a pointer to an iA32 TrapFrame 00103 00104 Return value: 00105 00106 --*/ 00107 { 00108 // 00109 // Setup exception and back to caller 00110 // 00111 00112 KiIA32CommonArgs(Frame, 00113 Ki386CheckDivideByZeroTrap(Frame), 00114 (PVOID) EIP(Frame), 00115 0, 0, 0); 00116 return TRUE; 00117 } 00118 00119 BOOLEAN 00120 KiIA32ExceptionDebug( 00121 IN PKTRAP_FRAME Frame 00122 ) 00123 /*++ 00124 Routine Description: 00125 iA-32_Exception(Debug) 00126 00127 Called from iA32_Exception() with 00128 ISR.Vector = 1 00129 00130 Depend on ISR.Code 00131 0: It is Code BreakPoint Trap 00132 TrapCode: Can be Concurrent Single Step | 00133 Taken Branch | Data BreakPoint Trap 00134 Handler needs to decode ISR.Code to distinguish 00135 Note: EFlag isn't saved yet, so write directly to ar.24 00136 00137 Arguments: 00138 Frame - Supply a pointer to an iA32 TrapFrame 00139 00140 Return Value: 00141 No return 00142 00143 --*/ 00144 { 00145 ULONGLONG EFlag; 00146 00147 #if defined(IADBG) 00148 IF_IA32TRAP_DEBUG( DEBUG ) 00149 DbgPrint( "IA32 Debug: Eip %x\n", EIP(Frame) ); 00150 #endif // IADBG 00151 // Turn off the TF bit 00152 EFlag = __getReg(CV_IA64_AR24); 00153 EFlag &= ~EFLAGS_TF_BIT; 00154 __setReg(CV_IA64_AR24, EFlag); 00155 00156 KiIA32CommonArgs(Frame, 00157 STATUS_WX86_SINGLE_STEP, 00158 (PVOID) EIP(Frame), 00159 0, 0, 0); 00160 return TRUE; 00161 } 00162 00163 BOOLEAN 00164 KiIA32ExceptionBreak( 00165 IN PKTRAP_FRAME Frame 00166 ) 00167 /*++ 00168 00169 Routine Description: 00170 iA-32_Exception(Break) - Trap 00171 00172 BreakPoint instruction (INT 3) trigged a trap. 00173 Note: EFlag isn't saved yet, so write directly to ar.24 00174 Arguments: 00175 Frame - Supply a pointer to an iA32 TrapFrame 00176 00177 Return Value: 00178 00179 --*/ 00180 { 00181 ULONGLONG EFlag; 00182 00183 #if defined(IADBG) 00184 IF_IA32TRAP_DEBUG( BREAK ) 00185 DbgPrint( "IA32 Break: Eip %x\n", EIP(Frame) ); 00186 #endif // IADBG 00187 // Turn off the TF bit 00188 EFlag = __getReg(CV_IA64_AR24); 00189 EFlag &= ~EFLAGS_TF_BIT; 00190 __setReg(CV_IA64_AR24, EFlag); 00191 00192 KiIA32CommonArgs(Frame, 00193 STATUS_WX86_BREAKPOINT, 00194 (PVOID) EIP(Frame), 00195 BREAKPOINT_BREAK, 00196 ECX(Frame), 00197 EDX(Frame)); 00198 return TRUE; 00199 } 00200 00201 BOOLEAN 00202 KiIA32ExceptionOverflow( 00203 IN PKTRAP_FRAME Frame 00204 ) 00205 /*++ 00206 Routine Description: 00207 iA-32_Exception(Overflow) - Trap 00208 ISR.Vector = 4 00209 00210 Handle INTO overflow 00211 00212 Eip - point to the address that next to the one causing INTO 00213 00214 Occurres when INTO instruction as well as EFlags.OF is ON 00215 Trap only initiated from user mode 00216 00217 Arguments: 00218 Frame - Supply a pointer to an iA32 TrapFrame 00219 00220 Return Value: 00221 00222 --*/ 00223 { 00224 #if defined(IADBG) 00225 IF_IA32TRAP_DEBUG( OVERFLOW ) 00226 DbgPrint( "IA32 OverFlow: Eip %x\n", EIP(Frame) ); 00227 #endif // IADBG 00228 00229 // 00230 // All error, generate exception and Eip point to INTO instruction 00231 // 00232 00233 KiIA32CommonArgs(Frame, 00234 STATUS_INTEGER_OVERFLOW, 00235 (PVOID) (EIP(Frame) - 1), 00236 0, 0, 0); 00237 return TRUE; 00238 } 00239 00240 00241 BOOLEAN 00242 KiIA32ExceptionBound( 00243 IN PKTRAP_FRAME Frame 00244 ) 00245 /*++ 00246 00247 Routine Description: 00248 iA-32_Exception(Bound) - Fault 00249 00250 Handle Bound check fault 00251 ISR.Vector = 5 00252 Eip - point to BOUND instruction 00253 00254 The bound check fault occurs if a BOUND instruction finds that 00255 the tested value is outside the specified range. 00256 00257 For bound check fault, an ARRAY BOUND EXCEEDED exception will be raised. 00258 00259 Arguments: 00260 Frame - Supply a pointer to an iA32 TrapFrame 00261 00262 Return Value: 00263 00264 --*/ 00265 { 00266 #if defined(IADBG) 00267 IF_IA32TRAP_DEBUG( BOUND ) 00268 DbgPrint( "IA32 Bound: Eip %x\n", EIP(Frame) ); 00269 #endif // IADBG 00270 // 00271 // All error, generate exception with Eip point to BOUND instruction 00272 // 00273 KiIA32CommonArgs(Frame, 00274 STATUS_ARRAY_BOUNDS_EXCEEDED, 00275 (PVOID) EIP(Frame), 00276 0, 0, 0); 00277 return TRUE; 00278 } 00279 00280 00281 ULONG 00282 IA32CheckOpcode( 00283 IN PKTRAP_FRAME Frame 00284 ) 00285 /*++ 00286 00287 Routine Description: 00288 00289 To identify the Opcode violation state 00290 00291 Arguments: 00292 00293 Frame: Pointer to iA32 TrapFrame in the stack 00294 00295 Return Value: 00296 Exception code 00297 00298 --*/ 00299 { 00300 ULONG i; 00301 UCHAR OpCodeByte0; 00302 UCHAR OpCodeByte1; 00303 UCHAR OpCodeByte2; 00304 00305 00306 OpCodeByte0 = (UCHAR) Frame->StIIM & 0xff; 00307 OpCodeByte1 = (UCHAR) (Frame->StIIM >> 8) & 0xff; 00308 OpCodeByte2 = (UCHAR) (Frame->StIIM >> 16) & 0xff; 00309 00310 switch (OpCodeByte0) { 00311 case MI_HLT: 00312 return (STATUS_PRIVILEGED_INSTRUCTION); 00313 break; 00314 00315 case MI_TWO_BYTE: 00316 if (OpCodeByte1 == MI_LTR_LLDT || 00317 OpCodeByte2 == MI_LGDT_LIDT_LMSW) { 00318 00319 OpCodeByte2 &= MI_MODRM_MASK; // get bit 3-5 of ModRM byte 00320 00321 if (OpCodeByte2==MI_LLDT_MASK || OpCodeByte2==MI_LTR_MASK || 00322 OpCodeByte2==MI_LGDT_MASK || OpCodeByte2==MI_LIDT_MASK || 00323 OpCodeByte2==MI_LMSW_MASK) { 00324 return (STATUS_PRIVILEGED_INSTRUCTION); 00325 } else { 00326 return (STATUS_ACCESS_VIOLATION); 00327 } 00328 00329 } else { 00330 if (OpCodeByte1 & MI_SPECIAL_MOV_MASK) { 00331 // 00332 // mov may have special_mov_mask 00333 // but they are not 2 bytes OpCode 00334 // 00335 return (STATUS_PRIVILEGED_INSTRUCTION); 00336 } else { 00337 // 00338 // Do we need to further check if it is INVD, INVLPG ... ? 00339 // 00340 return (STATUS_ACCESS_VIOLATION); 00341 } 00342 } 00343 break; 00344 00345 default: 00346 // 00347 // All other 00348 // 00349 return (STATUS_ILLEGAL_INSTRUCTION); 00350 break; 00351 } 00352 } 00353 00354 BOOLEAN 00355 KiIA32InterceptInstruction( 00356 IN PKTRAP_FRAME Frame 00357 ) 00358 /*++ 00359 00360 Routine Description: 00361 iA-32_Exception(InstructionIntercept Opcode) 00362 00363 Program entry for either 00364 1. IA-32 Invalid Opcode Fault #6, or 00365 2. IA-32 interceptions(Inst) 00366 00367 Execution of unimplemented IA-32 opcodes, illegal opcodes or sensitive 00368 privileged IA32 operating system instructions results this interception. 00369 00370 Possible Opcodes: 00371 Privileged Opcodes: CLTS, HLT, INVD, INVLPG, LIDT, LMSW, LTR, 00372 mov to/from CRs, DRs 00373 RDMSR, RSM, SMSW, WBINVD, WRMSR 00374 00375 Arguments: 00376 00377 Frame - Supply a pointer to an iA32 TrapFrame 00378 00379 Return Value: 00380 00381 --*/ 00382 { 00383 #if defined(IADBG) 00384 IF_IA32TRAP_DEBUG( INSTRUCTION ) 00385 DbgPrint( "IA32 Instruction: Eip %x\n", EIP(Frame) ); 00386 #endif // IADBG 00387 00388 switch ( IA32CheckOpcode(Frame) ) { 00389 case STATUS_PRIVILEGED_INSTRUCTION: 00390 KiIA32CommonArgs(Frame, 00391 STATUS_PRIVILEGED_INSTRUCTION, 00392 (PVOID) EIP(Frame), 00393 0, 0, 0); 00394 break; 00395 case STATUS_ACCESS_VIOLATION: 00396 KiIA32CommonArgs(Frame, 00397 STATUS_ACCESS_VIOLATION, 00398 (PVOID) EIP(Frame), 00399 0, -1, 0); 00400 break; 00401 case STATUS_ILLEGAL_INSTRUCTION: 00402 KiIA32CommonArgs(Frame, 00403 STATUS_ILLEGAL_INSTRUCTION, 00404 (PVOID) EIP(Frame), 00405 0, -1, 0); 00406 break; 00407 default: 00408 KeBugCheckEx(TRAP_CAUSE_UNKNOWN, (ULONG_PTR)Frame, IA32CheckOpcode(Frame), 0, 1); 00409 // Should never get here... 00410 return FALSE; 00411 break; 00412 } 00413 return TRUE; 00414 } 00415 00416 BOOLEAN 00417 KiIA32ExceptionNoDevice( 00418 IN PKTRAP_FRAME Frame 00419 ) 00420 /*++ 00421 00422 Routine Description: 00423 00424 iA-32_Exception(Coprocessor Not Available) - fault 00425 00426 This routine is called from iA32_Exception() with 00427 ISR.Vector = 7 00428 00429 Note: 00430 At this time, the AR registers have not been saved. This 00431 includes, CFLAGS (AR.27), EFLAGS (AR.24), FCR (AR.21), 00432 FSR (AR.28), FIR (AR.29) and FDR (AR.30). 00433 00434 Not handling MMX and KNI exceptions yet. 00435 00436 Arguments: 00437 00438 Frame - iA32 TrapFrame that was saved in the memory stack 00439 00440 Return Value: 00441 00442 --*/ 00443 { 00444 ULONG ErrorCode; 00445 ULONG FirOffset, FdrOffset; 00446 ULONG FpState; 00447 // For these 2 registers, we only care about the lower 32-bits 00448 ULONG FcrRegister, FsrRegister; 00449 00450 #if defined(IADBG) 00451 IF_IA32TRAP_DEBUG( NODEVICE ) 00452 DbgPrint( "IA32 NoDevice: Eip %x\n", EIP(Frame) ); 00453 #endif // IADBG 00454 00455 FcrRegister = (ULONG) (__getReg(CV_IA64_AR21) & 0xFFFFFFFF); 00456 FsrRegister = (ULONG) (__getReg(CV_IA64_AR28) & 0xFFFFFFFF); 00457 FirOffset = (ULONG) (__getReg(CV_IA64_AR29) & 0xFFFFFFFF); 00458 FdrOffset = (ULONG) (__getReg(CV_IA64_AR30) & 0xFFFFFFFF); 00459 00460 // 00461 // According to the floating error priority, 00462 // we test what is the cause of the NPX error 00463 // and raise an appropriate exception 00464 // 00465 FpState = ~(FcrRegister & 00466 (FSW_INVALID_OPERATION | FSW_DENORMAL | 00467 FSW_ZERO_DIVIDE | FSW_OVERFLOW | 00468 FSW_UNDERFLOW | FSW_PRECISION)) & (FsrRegister & FSW_ERR_MASK); 00469 00470 00471 // 00472 // Was an invalid operation fault? 00473 // 00474 00475 if (FpState & FSW_INVALID_OPERATION) { 00476 00477 if (FpState & FSW_STACK_FAULT) { 00478 KiIA32CommonArgs(Frame, 00479 STATUS_FLOAT_STACK_CHECK, 00480 (PVOID) FirOffset, 00481 0, FdrOffset, 0); 00482 return TRUE; 00483 } else { 00484 KiIA32CommonArgs(Frame, 00485 STATUS_FLOAT_INVALID_OPERATION, 00486 (PVOID) FirOffset, 00487 0, 0, 0); 00488 return TRUE; 00489 } 00490 00491 } else { 00492 00493 if (FpState & FSW_ZERO_DIVIDE) 00494 ErrorCode = STATUS_FLOAT_DIVIDE_BY_ZERO; 00495 else { if (FpState & FSW_DENORMAL) 00496 ErrorCode = STATUS_FLOAT_INVALID_OPERATION; 00497 else { if (FpState & FSW_OVERFLOW) 00498 ErrorCode = STATUS_FLOAT_OVERFLOW; 00499 else { if (FpState & FSW_UNDERFLOW) 00500 ErrorCode = STATUS_FLOAT_UNDERFLOW; 00501 else { if (FpState & FSW_PRECISION) 00502 ErrorCode = STATUS_FLOAT_INEXACT_RESULT; 00503 else 00504 ErrorCode = 0; 00505 } 00506 } 00507 } 00508 } 00509 } 00510 00511 if (ErrorCode) { 00512 KiIA32CommonArgs(Frame, 00513 STATUS_FLOAT_INEXACT_RESULT, 00514 (PVOID) FirOffset, 00515 0, 0, 0); 00516 return TRUE; 00517 } else { 00518 00519 // 00520 // FpState indicates no error, then something is wrong 00521 // Panic the system !!! 00522 // 00523 00524 KeBugCheckEx(TRAP_CAUSE_UNKNOWN, (ULONG_PTR)Frame, 0, 0, 2); 00525 } 00526 00527 // Should never get here... 00528 return FALSE; 00529 } 00530 00531 BOOLEAN 00532 KiIA32ExceptionSegmentNotPresent( 00533 IN PKTRAP_FRAME Frame 00534 ) 00535 /*++ 00536 00537 Routine Description: 00538 iA-32_Exception(Not Present) - fault 00539 00540 Handle Segment Not Present fault. 00541 ISR.Vector = 11 00542 00543 This exception occurs when the processor finds the P bit 0 00544 when accessing an otherwise valid descriptor that is not to 00545 be loaded in SS register. 00546 00547 Arguments: 00548 00549 Frame - iA32 TrapFrame that was saved in the memory stack 00550 00551 Return Value: 00552 00553 --*/ 00554 { 00555 KIRQL OldIrql; 00556 USHORT ErrorCode; 00557 00558 #if defined(IADBG) 00559 IF_IA32TRAP_DEBUG( NOTPRESENT ) 00560 DbgPrint( "IA32 NotPresent: Eip %x\n", EIP(Frame) ); 00561 #endif // IADBG 00562 00563 // 00564 // Generate Exception for all other errors 00565 // 00566 00567 KiIA32CommonArgs(Frame, 00568 STATUS_ACCESS_VIOLATION, 00569 (PVOID) EIP(Frame), 00570 0, ISRCode(Frame) | RPL_MASK, 0); 00571 return TRUE; 00572 } 00573 00574 BOOLEAN 00575 KiIA32ExceptionStack( 00576 IN PKTRAP_FRAME Frame 00577 ) 00578 /*++ 00579 00580 Routine Description: 00581 iA-32_Exception(Stack) - fault 00582 00583 ISR.Vector = 12 00584 00585 This exception occurs when the processor detects certain problem 00586 with the segment addressed by the SS segment register: 00587 00588 1. A limit violation in the segment addressed by the SS (error 00589 code = 0) 00590 2. A limit vioalation in the inner stack during an interlevel 00591 call or interrupt (error code = selector for the inner stack) 00592 3. If the descriptor to be loaded into SS has its present bit 0 00593 (error code = selector for the not-present segment) 00594 00595 The exception only occurred from user mode 00596 00597 Arguments: 00598 00599 Frame - iA32 TrapFrame that was saved in the memory stack 00600 00601 Return Value: 00602 00603 --*/ 00604 { 00605 USHORT Code; 00606 00607 #if defined(IADBG) 00608 IF_IA32TRAP_DEBUG( STACK ) 00609 DbgPrint( "IA32 Stack: Eip %x\n", EIP(Frame) ); 00610 #endif // IADBG 00611 00612 // 00613 // Dispatch Exception to user 00614 // 00615 00616 Code = ISRCode(Frame); 00617 00618 // 00619 // Code may contain the faulting selector 00620 // 00621 KiIA32CommonArgs(Frame, 00622 STATUS_ACCESS_VIOLATION, 00623 (PVOID) EIP(Frame), 00624 Code ? (Code | RPL_MASK) : ESP(Frame), 00625 Code ? EXCEPT_UNKNOWN_ACCESS : EXCEPT_LIMIT_ACCESS, 00626 0); 00627 return TRUE; 00628 } 00629 00630 BOOLEAN 00631 KiIA32ExceptionInvalidOp( 00632 IN PKTRAP_FRAME Frame 00633 ) 00634 /*++ 00635 00636 Routine Description: 00637 iA-32_Exception(Invalid Opcode) - fault 00638 00639 PKTRAP_FRAME Frame 00640 Eip : virtual iA-32 instruction address 00641 ISR.vector : 6 00642 00643 Note: 00644 Only MMX and KNI instructions can cause this fault based 00645 on values in CR0 and CR4 00646 00647 Arguments: 00648 00649 Frame - iA32 TrapFrame that was saved in the memory stack 00650 00651 Return Value: 00652 --*/ 00653 { 00654 #if defined(IADBG) 00655 IF_IA32TRAP_DEBUG( INSTRUCTION ) 00656 DbgPrint( "IA32 Invalid Opcode: Eip %x\n", EIP(Frame) ); 00657 #endif // IADBG 00658 00659 KiIA32CommonArgs(Frame, 00660 STATUS_ILLEGAL_INSTRUCTION, 00661 (PVOID) EIP(Frame), 00662 0, 0, 0); 00663 return TRUE; 00664 } 00665 00666 BOOLEAN 00667 KiIA32ExceptionGPFault( 00668 IN PKTRAP_FRAME Frame 00669 ) 00670 /*++ 00671 00672 Routine Description: 00673 iA-32_Exception(General Protection) - fault 00674 00675 PKTRAP_FRAME Frame 00676 Eip : virtual iA-32 instruction address 00677 ISR.vector : 13 00678 ISR.code : ErrorCode 00679 00680 Note: 00681 Previlidged instructions are intercepted, 00682 see KiIA32InterceptInstruction 00683 00684 Arguments: 00685 00686 Frame - iA32 TrapFrame that was saved in the memory stack 00687 00688 Return Value: 00689 00690 --*/ 00691 { 00692 #if defined(IADBG) 00693 IF_IA32TRAP_DEBUG( GPFAULT ) 00694 DbgPrint( "IA32 GpFault: Eip %x\n", EIP(Frame) ); 00695 #endif // IADBG 00696 00697 KiIA32CommonArgs(Frame, 00698 STATUS_ACCESS_VIOLATION, 00699 (PVOID) EIP(Frame), 00700 0, 0, 0); 00701 return TRUE; 00702 } 00703 00704 00705 00706 BOOLEAN 00707 KiIA32ExceptionKNI( 00708 IN PKTRAP_FRAME Frame 00709 ) 00710 /*++ 00711 00712 iA32_Exception(KNI) - Fault 00713 00714 Unmasked KNI IA32 Error. 00715 ISR.Vector = 19 00716 00717 --*/ 00718 { 00719 #if defined(IADBG) 00720 IF_IA32TRAP_DEBUG( FPFAULT ) 00721 DbgPrint( "IA32 KNI Fault: Eip %x\n", EIP(Frame) ); 00722 #endif // IADBG 00723 return(KiIA32ExceptionNoDevice(Frame)); 00724 } 00725 00726 00727 BOOLEAN 00728 KiIA32ExceptionFPFault( 00729 IN PKTRAP_FRAME Frame 00730 ) 00731 /*++ 00732 00733 iA32_Exception(Floating Point) - Fault 00734 00735 Handle Coprocessor Error. 00736 ISR.Vector = 16 00737 00738 This exception is used on 486 or above only. For i386, it uses 00739 IRQ 13 instead. 00740 00741 JMPE instruction should flush all FP delayed exception, and the traps 00742 will goto Device Not Available trap 00743 00744 --*/ 00745 { 00746 #if defined(IADBG) 00747 IF_IA32TRAP_DEBUG( FPFAULT ) 00748 DbgPrint( "IA32 FpFault: Eip %x\n", EIP(Frame) ); 00749 #endif // IADBG 00750 return(KiIA32ExceptionNoDevice(Frame)); 00751 } 00752 00753 00754 BOOLEAN 00755 KiIA32ExceptionAlignmentFault( 00756 IN PKTRAP_FRAME Frame 00757 ) 00758 /*++ 00759 00760 iA32_Exception(Alignment Check) - fault 00761 00762 Handle alignment faults. 00763 ISR.Vector = 17 00764 00765 This exception occurs when an unaligned data access is made by a thread 00766 with alignment checking turned on. 00767 00768 This fault occurred when unaligned access on EM PSR.AC is ON 00769 Note that iA32 EFLAFS.AC, CR0.AM and CPL!=3 does not unmask the fault. 00770 00771 So, for now, let the ia64 alignment handler handle this... 00772 00773 --*/ 00774 { 00775 #if defined(IADBG) 00776 IF_IA32TRAP_DEBUG( ALIGNMENT ) 00777 DbgPrint( "IA32 Alignment: Eip %x\n", EIP(Frame) ); 00778 #endif // IADBG 00779 00780 // 00781 // BUGBUG: We should really turn off psr.ac for an ia32 process... 00782 // 00783 return KiUnalignedFault(Frame); 00784 } 00785 00786 00787 BOOLEAN 00788 KiIA32InterruptVector( 00789 IN PKTRAP_FRAME Frame 00790 ) 00791 /*++ 00792 00793 iA32_Interrupt(Vector #) - trap 00794 00795 Handle INTnn trap 00796 00797 Under EM system mode, iA32 INT instruction forces a mandatory iA-32 00798 interrupt trap through iA-32 Interrupt(SoftWare Interrupt) 00799 00800 --*/ 00801 { 00802 #if defined(IADBG) 00803 IF_IA32TRAP_DEBUG( INTNN ) 00804 DbgPrint( "IA32 Intnn: Eip %x INT 0x%xH\n", EIP(Frame), ISRVector(Frame)); 00805 #endif // IADBG 00806 KiIA32CommonArgs(Frame, 00807 STATUS_PRIVILEGED_INSTRUCTION, 00808 (PVOID) EIP(Frame), 00809 0, 0, 0); 00810 return TRUE; 00811 } 00812 00813 00814 BOOLEAN 00815 KiIA32InterceptGate( 00816 IN PKTRAP_FRAME Frame 00817 ) 00818 /*++ 00819 00820 Routine Description: 00821 00822 iA32_Intercept(Gate) - trap 00823 00824 If an iA32 control transfer is initiated through a GDT or LDT descriptor 00825 that results in an either a promotion of privilege level (interlevel Call 00826 or Jump Gate and IRET) or an iA32 task switch (TSS segment or Gate), 00827 the intercept trap is generated. 00828 00829 Possible instructions intercepted: 00830 CALL, RET, IRET, IRETD and JMP 00831 00832 Handling 00833 No CaLL, RET, JMP, IRET, IRETD are allowed in any mode, 00834 STATUS_ACCESS_VIOLATION is returned 00835 00836 Arguments: 00837 Frame - iA32 TrapFrame that was saved in the memory stack 00838 00839 Return Value: 00840 00841 --*/ 00842 { 00843 #if defined(IADBG) 00844 IF_IA32TRAP_DEBUG( GATE ) 00845 DbgPrint( "IA32 Gate: Eip %x GateSelector %x OpcodeId %x\n", 00846 EIP(Frame), 00847 (ULONG) (Frame->IFA & 0xff), 00848 (ULONG) (ISRCode(Frame) >> 14)); 00849 #endif // IADBG 00850 00851 // 00852 // all error fall through here 00853 // 00854 KiIA32CommonArgs(Frame, 00855 STATUS_ILLEGAL_INSTRUCTION, 00856 (PVOID) EIP(Frame), 00857 0, 0, 0); 00858 return TRUE; 00859 } 00860 00861 /*++ 00862 00863 iA32_intercept(System Flag) - trap 00864 00865 Possible Causes: 00866 1. if CFLAG.ii==1 and EFLAG.if changes state 00867 2. Generated after either EFLAG.ac, tf or rf changes state 00868 if no IOPL or CPL to modify bits then no interception. 00869 3. if CFLG.nm==1 then successful execution of IRET also intercepted 00870 00871 Possible instructions: 00872 CLI, POPF, POFD, STI and IRET 00873 00874 Currently, we set both CFLAG.ii and nm to 0, so that we will only possiblly 00875 get case #2. But in EM/NT, it should always come from user land which 00876 we hard-set EFLAG.IOPL to 0, so there if we do get case #2, then it is user 00877 play around EFLAG.IOPL through JMPE. We should fail it. 00878 00879 --*/ 00880 00881 BOOLEAN 00882 KiIA32InterceptSystemFlag( 00883 IN PKTRAP_FRAME Frame 00884 ) 00885 { 00886 #if defined(IADBG) 00887 IF_IA32TRAP_DEBUG( FLAG ) 00888 DbgPrint( "IA32 FLAG: Eip %x Old EFlag: %x OpcodeId %x\n", 00889 EIP(Frame), 00890 (ULONG) (Frame->IIM & 0xff), 00891 (ULONG) (ISRCode(Frame) >> 14)); 00892 #endif // IADBG 00893 KiIA32CommonArgs(Frame, 00894 STATUS_ILLEGAL_INSTRUCTION, 00895 (PVOID) EIP(Frame), 00896 0, 0, 0); 00897 return TRUE; 00898 } 00899 00900 BOOLEAN 00901 KiIA32InterceptLock( 00902 IN PKTRAP_FRAME Frame 00903 ) 00904 /*++ 00905 00906 Routine Description: 00907 iA32_Intercept(Lock) - trap 00908 00909 Lock intercepts occurred if platform or firmware code has disabled locked 00910 transactions and atomic memory update requires a processor external 00911 indication 00912 00913 Arguments: 00914 Frame - Point to iA32 TrapFrame 00915 00916 Return: 00917 00918 --*/ 00919 { 00920 #if defined(IADBG) 00921 IF_IA32TRAP_DEBUG( LOCK ) 00922 DbgPrint( "IA32 LOCK: Eip %x\n", EIP(Frame) ); 00923 #endif // IADBG 00924 00925 // 00926 // BUGBUG: Delay implementation of this handler 00927 // Should we bug check instead so we know when we're running 00928 // on a platform that needs this? 00929 // 00930 KiIA32CommonArgs(Frame, 00931 STATUS_PRIVILEGED_INSTRUCTION, 00932 (PVOID) EIP(Frame), 00933 0, 0, 0); 00934 return TRUE; 00935 } 00936 00937 BOOLEAN 00938 KiIA32ExceptionPanic( 00939 IN PKTRAP_FRAME Frame 00940 ) 00941 { 00942 // 00943 // Panic the system 00944 // 00945 00946 KeBugCheckEx(TRAP_CAUSE_UNKNOWN, 00947 (ULONG_PTR)Frame, 00948 ISRVector(Frame), 00949 0, 0); 00950 // Should never get here... 00951 return FALSE; 00952 } 00953 00954 00955 00956 BOOLEAN (*KiIA32ExceptionDispatchTable[])(PKTRAP_FRAME) = { 00957 KiIA32ExceptionDivide, 00958 KiIA32ExceptionDebug, 00959 KiIA32ExceptionPanic, 00960 KiIA32ExceptionBreak, 00961 KiIA32ExceptionOverflow, 00962 KiIA32ExceptionBound, 00963 KiIA32ExceptionInvalidOp, 00964 KiIA32ExceptionNoDevice, 00965 KiIA32ExceptionPanic, 00966 KiIA32ExceptionPanic, 00967 KiIA32ExceptionPanic, 00968 KiIA32ExceptionSegmentNotPresent, 00969 KiIA32ExceptionStack, 00970 KiIA32ExceptionGPFault, 00971 KiIA32ExceptionPanic, 00972 KiIA32ExceptionPanic, 00973 KiIA32ExceptionFPFault, 00974 KiIA32ExceptionAlignmentFault, 00975 KiIA32ExceptionPanic, 00976 KiIA32ExceptionKNI 00977 }; 00978 00979 BOOLEAN (*KiIA32InterceptionDispatchTable[])(PKTRAP_FRAME) = { 00980 KiIA32InterceptInstruction, 00981 KiIA32InterceptGate, 00982 KiIA32InterceptSystemFlag, 00983 KiIA32InterceptLock 00984 }; 00985 00986 BOOLEAN 00987 KiIA32InterceptionVectorHandler( 00988 IN PKTRAP_FRAME Frame 00989 ) 00990 /*++ 00991 00992 Routine Description: 00993 00994 KiIA32InterceptionVectorHandler 00995 00996 Called by first label KiIA32InterceptionVector() to handle further iA32 00997 interception processing. 00998 00999 Arguments: 01000 01001 Frame - iA32 TrapFrame that was saved in the memory stack 01002 01003 Return Value: 01004 TRUE - go to dispatch exception 01005 FALSE - Exception was handled, do an RFI 01006 01007 --*/ 01008 { 01009 #if defined(IADBG) 01010 IF_IA32TRAP_DEBUG( INTERCEPTION ) 01011 DbgPrint("IA32 Interception: ISRVector %x Frame %x\n", ISRVector(Frame), Frame); 01012 #endif // IADBG 01013 01014 ASSERT(UserMode == Frame->PreviousMode); 01015 01016 // 01017 // Make sure we have an entry in the table for this interception 01018 // 01019 if (ISRVector(Frame) <= sizeof(KiIA32InterceptionDispatchTable)>>2) 01020 return (*KiIA32InterceptionDispatchTable[ISRVector(Frame)])(Frame); 01021 else 01022 return (KiIA32ExceptionPanic(Frame)); 01023 } 01024 01025 BOOLEAN 01026 KiIA32ExceptionVectorHandler( 01027 IN PKTRAP_FRAME Frame 01028 ) 01029 /*++ 01030 01031 Routine Description: 01032 01033 KiIA32ExceptionVectorHandler 01034 01035 Called by first label KiIA32ExceptionVector() to handle further iA32 01036 interception processing. 01037 01038 Arguments: 01039 01040 Frame - iA32 TrapFrame that was saved in the memory stack 01041 01042 Return Value: 01043 TRUE - go to dispatch exception 01044 FALSE - Exception was handled, do an RFI 01045 01046 --*/ 01047 { 01048 #if defined(IADBG) 01049 IF_IA32TRAP_DEBUG( EXCEPTION ) 01050 DbgPrint("IA32 Exception: ISRVector %x Frame %x\n", ISRVector(Frame), Frame); 01051 #endif // IADBG 01052 01053 ASSERT(UserMode == Frame->PreviousMode); 01054 // 01055 // Make sure we have an entry in the table for this exception 01056 // 01057 if (ISRVector(Frame) <= sizeof(KiIA32ExceptionDispatchTable)>>2) 01058 return (*KiIA32ExceptionDispatchTable[ISRVector(Frame)])(Frame); 01059 else 01060 return(KiIA32ExceptionPanic(Frame)); 01061 } 01062 01063 BOOLEAN 01064 KiIA32InterruptionVectorHandler( 01065 IN PKTRAP_FRAME Frame 01066 ) 01067 /*++ 01068 01069 Routine Description: 01070 01071 KiIA32InterruptionVectorHandler 01072 01073 Called by first label KiIA32InterruptionVector() to handle further iA32 01074 interruption processing. Only get here on INT xx instructions 01075 01076 Arguments: 01077 01078 Frame - iA32 TrapFrame that was saved in the memory stack 01079 01080 Return Value: 01081 TRUE - go to dispatch exception 01082 FALSE - Exception was handled, do an RFI 01083 01084 --*/ 01085 { 01086 #if defined(IADBG) 01087 IF_IA32TRAP_DEBUG( INTERRUPTION ) 01088 DbgPrint("IA32 Interruption: ISRVector %x Frame %x\n", ISRVector(Frame), Frame); 01089 #endif // IADBG 01090 01091 ASSERT(UserMode == Frame->PreviousMode); 01092 01093 // 01094 // Follow the ia32 way of INT xx as an Access Violation 01095 // 01096 // INT 3 should be handled via a debug exception and should 01097 // never get here... 01098 // 01099 ASSERT(3 != ISRVector(Frame)); 01100 01101 KiIA32CommonArgs(Frame, 01102 STATUS_ACCESS_VIOLATION, 01103 (PVOID) EIP(Frame), 01104 0, 0, 0); 01105 return TRUE; 01106 }

Generated on Sat May 15 19:40:19 2004 for test by doxygen 1.3.7