00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "ki.h"
00027
#include "ps.h"
00028
#include "..\..\mm\mi.h"
00029
#include <inbv.h>
00030
00031 extern BOOLEAN
PsWatchEnabled;
00032
extern VOID ExpInterlockedPopEntrySListResume();
00033
00034
#if DBG
00035
00036
typedef struct _MMFAULT_HISTORY {
00037 ULONGLONG Iip;
00038 ULONGLONG Ifa;
00039 ULONGLONG Iipa;
00040 ULONGLONG TrapFrame;
00041 } MMFAULT_HISTORY;
00042
00043 ULONG MmHistoryIndx = 0;
00044
00045 MMFAULT_HISTORY MmFaultHistory[8];
00046
00047 ULONGLONG MmUserInstMemoryFaultCount = 0;
00048 ULONGLONG MmUserDataMemoryFaultCount = 0;
00049 ULONGLONG MmKernInstMemoryFaultCount = 0;
00050 ULONGLONG MmKernDataMemoryFaultCount = 0;
00051
00052
#endif
00053
00054
00055 BOOLEAN
00056 KiMemoryFault (
00057 IN PKTRAP_FRAME TrapFrame
00058 )
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 {
00075 PEXCEPTION_RECORD ExceptionRecord;
00076 BOOLEAN StoreInstruction;
00077 PVOID VirtualAddress;
00078
NTSTATUS Status;
00079
00080
00081
00082
00083
00084
if (TrapFrame->StISR & (1i64 << ISR_W)) {
00085 StoreInstruction =
TRUE;
00086 }
else {
00087 StoreInstruction =
FALSE;
00088 }
00089
00090 VirtualAddress = (PVOID)TrapFrame->StIFA;
00091
00092
if (TrapFrame->StISR & (1i64 << ISR_X)) {
00093
00094
#if _MERCED_A0_
00095
if ((TrapFrame->StIPSR & (1i64 << PSR_IS)) == 0) {
00096 VirtualAddress = (PVOID)TrapFrame->StIIP;
00097 }
00098
#endif
00099
00100
00101
00102
00103 StoreInstruction = 2;
00104 }
00105
00106
00107
#if DBG
00108
00109 _disable();
00110
00111
if (MmHistoryIndx < 8) {
00112 MmFaultHistory[MmHistoryIndx].Iip = TrapFrame->StIIP;
00113 MmFaultHistory[MmHistoryIndx].Ifa = TrapFrame->StIFA;
00114 MmFaultHistory[MmHistoryIndx].Iipa = TrapFrame->StIIPA;
00115 MmFaultHistory[MmHistoryIndx].TrapFrame = (ULONGLONG)TrapFrame;
00116 MmHistoryIndx += 1;
00117 }
else if (MmHistoryIndx == 8) {
00118 MmHistoryIndx = 0;
00119 }
else {
00120
KeBugCheck(MmHistoryIndx);
00121 }
00122
00123
if (VirtualAddress < MM_SYSTEM_RANGE_START) {
00124
00125
if (StoreInstruction == 2) {
00126 MmUserInstMemoryFaultCount += 1;
00127 }
else {
00128 MmUserDataMemoryFaultCount += 1;
00129 }
00130
00131 }
else {
00132
00133
if (StoreInstruction == 2) {
00134 MmKernInstMemoryFaultCount += 1;
00135 }
else {
00136 MmKernDataMemoryFaultCount += 1;
00137 }
00138 }
00139
00140 _enable();
00141
00142
#endif
00143
00144
#if defined(_MIALT4K_)
00145
if (((ULONG_PTR)VirtualAddress <=
_MAX_WOW64_ADDRESS) &&
00146 (
PsGetCurrentProcess()->Wow64Process !=
NULL)) {
00147
00148
Status =
MmX86Fault(StoreInstruction, VirtualAddress,
00149 (
KPROCESSOR_MODE)TrapFrame->PreviousMode, TrapFrame);
00150
00151 }
else
00152
#endif
00153
{
00154
00155
Status =
MmAccessFault(StoreInstruction, VirtualAddress,
00156 (
KPROCESSOR_MODE)TrapFrame->PreviousMode, TrapFrame);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
if (
Status >= 0) {
00167
00168
if (
PsWatchEnabled) {
00169
PsWatchWorkingSet(
Status,
00170 (PVOID)TrapFrame->StIIP,
00171 (PVOID)VirtualAddress);
00172 }
00173
00174
00175
00176
00177
00178
KdSetOwedBreakpoints();
00179
00180
return FALSE;
00181
00182 }
else if (
KeInvalidAccessAllowed(TrapFrame)) {
00183
00184 TrapFrame->StIIP = ((PPLABEL_DESCRIPTOR)
ExpInterlockedPopEntrySListResume)->EntryPoint;
00185
00186 }
else if (TrapFrame->StISR & (1i64 << ISR_SP)) {
00187
00188
00189
00190
00191
00192 TrapFrame->StIPSR |= (1i64 << PSR_ED);
00193
00194
return FALSE;
00195
00196 }
00197
00198
00199
00200
00201
00202
00203 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00204 ExceptionRecord->ExceptionCode =
Status;
00205 ExceptionRecord->ExceptionAddress =
00206 (PVOID)RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00207 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00208
00209 ExceptionRecord->ExceptionFlags = 0;
00210 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00211
00212 ExceptionRecord->NumberParameters = 5;
00213 ExceptionRecord->ExceptionInformation[0] = (ULONG_PTR)StoreInstruction;
00214 ExceptionRecord->ExceptionInformation[1] = (ULONG_PTR)VirtualAddress;
00215 ExceptionRecord->ExceptionInformation[2] = (ULONG_PTR)
Status;
00216 ExceptionRecord->ExceptionInformation[3] = (ULONG_PTR)TrapFrame->StIIPA;
00217 ExceptionRecord->ExceptionInformation[4] = (ULONG_PTR)TrapFrame->StISR;
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
switch (
Status) {
00233
00234
case STATUS_ACCESS_VIOLATION:
00235
case STATUS_GUARD_PAGE_VIOLATION:
00236
case STATUS_STACK_OVERFLOW:
00237
case STATUS_IN_PAGE_ERROR:
00238
00239
break;
00240
00241
default:
00242
00243 ExceptionRecord->ExceptionCode = STATUS_IN_PAGE_ERROR;
00244
break;
00245
00246
case STATUS_IN_PAGE_ERROR | 0x10000000:
00247
00248
00249
00250
00251
00252
00253
KeBugCheckEx(
IRQL_NOT_LESS_OR_EQUAL,
00254 (ULONG_PTR)VirtualAddress,
00255 (ULONG_PTR)KeGetCurrentIrql(),
00256 (ULONG_PTR)StoreInstruction,
00257 (ULONG_PTR)TrapFrame->StIIP);
00258
00259
00260
00261
00262
break;
00263 }
00264
00265
return TRUE;
00266 }
00267
00268 typedef struct _BREAK_INST {
00269
union {
00270
struct {
00271 ULONGLONG
qp: 6;
00272 ULONGLONG
imm20: 20;
00273 ULONGLONG
x: 1;
00274 ULONGLONG
x6: 6;
00275 ULONGLONG
x3: 3;
00276 ULONGLONG
i: 1;
00277 ULONGLONG
Op: 4;
00278 ULONGLONG
Rsv: 23;
00279 } i_field;
00280 ULONGLONG
Ulong64;
00281 } u;
00282 }
BREAK_INST;
00283
00284
00285 ULONG
00286 KiExtractImmediate (
00287 IN ULONGLONG Iip,
00288 IN ULONG SlotNumber
00289 )
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 {
00310 PULONGLONG BundleAddress;
00311 ULONGLONG BundleLow;
00312 ULONGLONG BundleHigh;
00313
BREAK_INST BreakInst;
00314 ULONG Imm21;
00315
00316 BundleAddress = (PULONGLONG)Iip;
00317
00318 BundleLow = *BundleAddress;
00319 BundleHigh = *(BundleAddress+1);
00320
00321
00322
00323
00324
00325
switch (SlotNumber) {
00326
case 0:
00327 BreakInst.
u.Ulong64 = BundleLow >> 5;
00328
break;
00329
00330
case 1:
00331 BreakInst.
u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
00332
break;
00333
00334
case 2:
00335 BreakInst.
u.Ulong64 = (BundleHigh >> 23);
00336
break;
00337 }
00338
00339
00340
00341
00342
00343 Imm21 = (ULONG)(BreakInst.
u.i_field.i<<20) | (ULONG)(BreakInst.
u.i_field.imm20);
00344
00345
return Imm21;
00346 }
00347
00348 BOOLEAN
00349 KiOtherBreakException (
00350 IN PKTRAP_FRAME TrapFrame
00351 )
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 {
00371 PEXCEPTION_RECORD ExceptionRecord;
00372 ULONG BreakImmediate;
00373 ISR Isr;
00374
00375 BreakImmediate = (ULONG)(TrapFrame->StIIM);
00376
00377
00378
00379
00380
if (BreakImmediate == 0) {
00381 Isr.ull = TrapFrame->StISR;
00382 BreakImmediate =
KiExtractImmediate(TrapFrame->StIIP,
00383 (ULONG)Isr.sb.isr_ei);
00384 TrapFrame->StIIM = BreakImmediate;
00385 }
00386
00387
00388
00389
00390
00391 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00392 ExceptionRecord->ExceptionAddress =
00393 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00394 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00395
00396 ExceptionRecord->ExceptionFlags = 0;
00397 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00398
00399 ExceptionRecord->NumberParameters = 5;
00400 ExceptionRecord->ExceptionInformation[0] = 0;
00401 ExceptionRecord->ExceptionInformation[1] = 0;
00402 ExceptionRecord->ExceptionInformation[2] = 0;
00403 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00404 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00405
00406
switch (BreakImmediate) {
00407
00408
case KERNEL_BREAKPOINT:
00409
case USER_BREAKPOINT:
00410
case INTEGER_OVERFLOW_BREAKPOINT:
00411
case DIVIDE_OVERFLOW_BREAKPOINT:
00412
case DIVIDE_BY_ZERO_BREAKPOINT:
00413
case RANGE_CHECK_BREAKPOINT:
00414
case STACK_OVERFLOW_BREAKPOINT:
00415
case MULTIPLY_OVERFLOW_BREAKPOINT:
00416
case DEBUG_PRINT_BREAKPOINT:
00417
case DEBUG_PROMPT_BREAKPOINT:
00418
case DEBUG_STOP_BREAKPOINT:
00419
case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
00420
case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
00421
case BREAKIN_BREAKPOINT:
00422 ExceptionRecord->ExceptionCode = STATUS_BREAKPOINT;
00423 ExceptionRecord->ExceptionInformation[0] = BreakImmediate;
00424
break;
00425
00426
default:
00427
#if DBG
00428
InbvDisplayString (
"KiOtherBreakException: Unknown break code.\n");
00429
#endif // DBG
00430
ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
00431
break;
00432 }
00433
00434
return TRUE;
00435 }
00436
00437 BOOLEAN
00438 KiGeneralExceptions (
00439 IN PKTRAP_FRAME TrapFrame
00440 )
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 {
00494 BOOLEAN StoreInstruction =
FALSE;
00495 ULONG IsrCode;
00496 PEXCEPTION_RECORD ExceptionRecord;
00497
00498
00499
00500
00501
00502 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00503 ExceptionRecord->ExceptionAddress =
00504 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00505 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00506
00507 ExceptionRecord->ExceptionFlags = 0;
00508 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00509
00510 ExceptionRecord->NumberParameters = 5;
00511 ExceptionRecord->ExceptionInformation[0] = 0;
00512 ExceptionRecord->ExceptionInformation[1] = 0;
00513 ExceptionRecord->ExceptionInformation[2] = 0;
00514 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00515 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00516
00517 IsrCode = (LONG)((TrapFrame->StISR >> ISR_CODE) & ISR_CODE_MASK);
00518
00519
00520
00521
00522
00523
switch (IsrCode >> 4) {
00524
00525
case ISR_PRIV_OP:
00526
case ISR_PRIV_REG:
00527
00528 ExceptionRecord->ExceptionCode = STATUS_PRIVILEGED_INSTRUCTION;
00529
break;
00530
00531
case ISR_RESVD_REG:
00532
00533
00534
00535
00536
00537
if (TrapFrame->StISR & (1i64 << ISR_W)) {
00538
00539 StoreInstruction =
TRUE;
00540
00541 }
else if (TrapFrame->StISR & (1i64 << ISR_X)) {
00542
00543
00544
00545
00546
00547 StoreInstruction = 2;
00548 }
00549
00550 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
00551 ExceptionRecord->ExceptionInformation[0] = (ULONG_PTR)StoreInstruction;
00552 ExceptionRecord->ExceptionInformation[1] = (ULONG_PTR)TrapFrame->StIFA;
00553 ExceptionRecord->ExceptionInformation[2] = (ULONG_PTR)STATUS_ACCESS_VIOLATION;
00554
break;
00555
00556
case ISR_ILLEGAL_OP:
00557
case ISR_ILLEGAL_ISA:
00558
00559 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
00560
break;
00561
00562
case ISR_ILLEGAL_HAZARD:
00563
00564
00565
00566
00567
00568 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
00569
break;
00570
00571
default:
00572
00573
if (TrapFrame->PreviousMode ==
KernelMode) {
00574
KeBugCheckEx(0xFFFFFFFF,
00575 (ULONG_PTR)TrapFrame->StISR,
00576 (ULONG_PTR)TrapFrame->StIIP,
00577 (ULONG_PTR)TrapFrame,
00578 0
00579 );
00580 }
00581
00582
break;
00583 }
00584
00585
return TRUE;
00586 }
00587
00588
00589 BOOLEAN
00590 KiNatExceptions (
00591 IN PKTRAP_FRAME TrapFrame
00592 )
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 {
00625 BOOLEAN StoreInstruction =
FALSE;
00626 ULONG IsrCode;
00627 PEXCEPTION_RECORD ExceptionRecord;
00628
00629
00630
00631
00632
00633 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00634 ExceptionRecord->ExceptionAddress =
00635 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00636 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00637
00638 ExceptionRecord->ExceptionFlags = 0;
00639 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00640
00641 ExceptionRecord->NumberParameters = 5;
00642 ExceptionRecord->ExceptionInformation[0] = 0;
00643 ExceptionRecord->ExceptionInformation[1] = 0;
00644 ExceptionRecord->ExceptionInformation[2] = 0;
00645 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00646 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00647
00648 IsrCode = (LONG)((TrapFrame->StISR >> ISR_CODE) & ISR_CODE_MASK);
00649
00650
00651
00652
00653
00654
switch (IsrCode >> 4) {
00655
00656
case ISR_NAT_REG:
00657
00658
#if 0
00659
if (TrapFrame->PreviousMode ==
KernelMode) {
00660
00661
DbgPrint(
"FATAL ERROR: Kernel hit a Nat Consumpation Fault!\n");
00662
KeBugCheckEx(0xFFFFFFFF,
00663 (ULONG_PTR)TrapFrame->StISR,
00664 (ULONG_PTR)TrapFrame->StIIP,
00665 (ULONG_PTR)TrapFrame,
00666 0
00667 );
00668
00669
00670 }
00671
#endif // 0
00672
00673 ExceptionRecord->ExceptionCode = STATUS_REG_NAT_CONSUMPTION;
00674
break;
00675
00676
case ISR_NAT_PAGE:
00677
00678
00679
00680
00681
00682
00683 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
00684
break;
00685
00686
default:
00687
00688
if (TrapFrame->PreviousMode ==
KernelMode) {
00689
KeBugCheckEx(0xFFFFFFFF,
00690 (ULONG_PTR)TrapFrame->StISR,
00691 (ULONG_PTR)TrapFrame->StIIP,
00692 (ULONG_PTR)TrapFrame,
00693 0
00694 );
00695 }
00696
00697
break;
00698 }
00699
00700
return TRUE;
00701 }
00702
00703
00704 BOOLEAN
00705 KiSingleStep (
00706 IN PKTRAP_FRAME TrapFrame
00707 )
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 {
00733 PEXCEPTION_RECORD ExceptionRecord;
00734 ULONG IpsrRi;
00735
00736
00737
00738
00739
00740 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00741
00742
00743
00744
00745 IpsrRi = (ULONG)(TrapFrame->StIPSR >> PSR_RI) & 0x3;
00746
00747 ExceptionRecord->ExceptionAddress =
00748 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP, IpsrRi);
00749
00750 ExceptionRecord->ExceptionFlags = 0;
00751 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00752
00753 ExceptionRecord->NumberParameters = 5;
00754 ExceptionRecord->ExceptionInformation[0] = 0;
00755 ExceptionRecord->ExceptionInformation[1] = 0;
00756 ExceptionRecord->ExceptionInformation[2] = 0;
00757 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00758 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00759
00760 ExceptionRecord->ExceptionCode = STATUS_SINGLE_STEP;
00761
00762
return TRUE;
00763 }
00764
00765 BOOLEAN
00766 KiFloatFault (
00767 IN PKTRAP_FRAME TrapFrame
00768 )
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 {
00804 PEXCEPTION_RECORD ExceptionRecord;
00805
00806
00807
00808
00809
00810 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00811 ExceptionRecord->ExceptionAddress =
00812 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00813 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00814
00815 ExceptionRecord->ExceptionFlags = 0;
00816 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00817
00818 ExceptionRecord->NumberParameters = 5;
00819 ExceptionRecord->ExceptionInformation[0] = 0;
00820 ExceptionRecord->ExceptionInformation[1] = 0;
00821 ExceptionRecord->ExceptionInformation[2] = 0;
00822 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00823 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00824
00825 ExceptionRecord->ExceptionCode = STATUS_FLOAT_MULTIPLE_FAULTS;
00826
00827
return TRUE;
00828 }
00829
00830 BOOLEAN
00831 KiFloatTrap (
00832 IN PKTRAP_FRAME TrapFrame
00833 )
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 {
00867 PEXCEPTION_RECORD ExceptionRecord;
00868 ULONGLONG SavedISR = TrapFrame->StISR;
00869
00870
00871
00872
00873
00874 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
00875 ExceptionRecord->ExceptionAddress =
00876 (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
00877 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
00878
00879 ExceptionRecord->ExceptionFlags = 0;
00880 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
00881
00882 ExceptionRecord->NumberParameters = 5;
00883 ExceptionRecord->ExceptionInformation[0] = 0;
00884 ExceptionRecord->ExceptionInformation[1] = 0;
00885 ExceptionRecord->ExceptionInformation[2] = 0;
00886 ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
00887 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00888
00889 ExceptionRecord->ExceptionCode = STATUS_FLOAT_MULTIPLE_TRAPS;
00890
00891
00892
00893
00894
00895
if (SavedISR & (1i64 << ISR_SS_TRAP)) {
00896
return KiSingleStep(TrapFrame);
00897 }
00898
00899
return TRUE;
00900 }
00901
00902
00903
#pragma warning( disable : 4715 ) // not all control paths return a value
00904
00905 EXCEPTION_DISPOSITION
00906 KiSystemServiceHandler (
00907 IN PEXCEPTION_RECORD ExceptionRecord,
00908 IN FRAME_POINTERS EstablisherFrame,
00909 IN OUT PCONTEXT ContextRecord,
00910 IN OUT PDISPATCHER_CONTEXT DispatcherContext
00911 )
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 {
00977 CONTEXT Context;
00978
PKTHREAD Thread;
00979 PKTRAP_FRAME TrapFrame;
00980 ULONG_PTR ExceptionAddress;
00981
00982
extern ULONG KiSystemServiceStartOffset;
00983
extern ULONG KiSystemServiceEndOffset;
00984
extern ULONG KiSystemServiceExitOffset;
00985
00986
if (IS_UNWINDING(ExceptionRecord->ExceptionFlags)) {
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
if (ExceptionRecord->ExceptionFlags &
EXCEPTION_TARGET_UNWIND) {
00998
return ExceptionContinueSearch;
00999 }
else {
01000
01001 Thread =
KeGetCurrentThread();
01002
if (Thread->
PreviousMode ==
KernelMode) {
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 TrapFrame = (PKTRAP_FRAME) ContextRecord->IntT0;
01014 Thread->
PreviousMode = (
KPROCESSOR_MODE)TrapFrame->PreviousMode;
01015
return ExceptionContinueSearch;
01016
01017 }
else {
01018
01019
01020
01021
01022
01023
KeBugCheck(
SYSTEM_UNWIND_PREVIOUS_USER);
01024 }
01025 }
01026 }
else {
01027
01028 ULONG IsrCode;
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 ExceptionAddress = (ULONG_PTR)ExceptionRecord->ExceptionAddress;
01039
if ((ExceptionAddress < MM_EPC_VA+KiSystemServiceStartOffset) ||
01040 (ExceptionAddress >= MM_EPC_VA+KiSystemServiceEndOffset))
01041 {
01042
if (
KeGetCurrentThread()->PreviousMode ==
UserMode) {
01043
01044
01045
01046
01047
01048
KeBugCheck(
SYSTEM_SERVICE_EXCEPTION);
01049
01050 }
else {
01051
01052
01053
01054
01055
01056
return ExceptionContinueSearch;
01057 }
01058 }
else {
01059 IsrCode = (ULONG)((ExceptionRecord->ExceptionInformation[4] >> ISR_CODE) & ISR_CODE_MASK) >> 4;
01060
if ( (IsrCode == ISR_NAT_REG) || (IsrCode == ISR_NAT_PAGE) ) {
01061
DbgPrint(
"WARNING: Kernel hit a Nat Consumpation Fault\n");
01062
DbgPrint(
"WARNING: At %p\n", ExceptionRecord->ExceptionAddress);
01063 }
01064
#pragma warning( disable : 4312 ) // disabling warning on PVOID casting for the ExceptionCode
01065
RtlUnwind2(EstablisherFrame,
01066 (PVOID)(MM_EPC_VA+KiSystemServiceExitOffset),
01067
NULL, (PVOID)ExceptionRecord->ExceptionCode, &Context);
01068
#pragma warning ( default: 4312 )
01069
}
01070 }
01071
01072
01073 }
01074
01075
#pragma warning( default : 4715 )
01076
01077
01078 BOOLEAN
01079 KiUnalignedFault (
01080 IN PKTRAP_FRAME TrapFrame
01081 )
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 {
01103 PEXCEPTION_RECORD ExceptionRecord;
01104 PVOID VirtualAddress;
01105
01106 VirtualAddress = (PVOID)TrapFrame->StIFA;
01107
01108 ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
01109 ExceptionRecord->ExceptionAddress =
01110 (PVOID)RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
01111 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
01112
01113 ExceptionRecord->ExceptionFlags = 0;
01114 ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
01115
01116 ExceptionRecord->NumberParameters = 5;
01117 ExceptionRecord->ExceptionInformation[0] = (ULONG_PTR)0;
01118 ExceptionRecord->ExceptionInformation[1] = (ULONG_PTR)VirtualAddress;
01119 ExceptionRecord->ExceptionInformation[2] = (ULONG_PTR)0;
01120 ExceptionRecord->ExceptionInformation[3] = (ULONG_PTR)TrapFrame->StIIPA;
01121 ExceptionRecord->ExceptionInformation[4] = (ULONG_PTR)TrapFrame->StISR;
01122
01123 ExceptionRecord->ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
01124
01125
return TRUE;
01126 }
01127
01128
01129
VOID
01130 KiAdvanceInstPointer(
01131 IN PKTRAP_FRAME TrapFrame
01132 )
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 {
01151
01152 ULONGLONG PsrRi;
01153
01154 PsrRi = ((TrapFrame->StIPSR >> PSR_RI) & 3i64) + 1;
01155
01156
if (PsrRi == 3) {
01157
01158 PsrRi = 0;
01159 TrapFrame->StIIP += 16;
01160
01161 }
01162
01163 TrapFrame->StIPSR &= ~(3i64 << PSR_RI);
01164 TrapFrame->StIPSR |= (PsrRi << PSR_RI);
01165
01166
return;
01167 }
01168
01169
#if _MERCED_A0_
01170
01171
typedef struct _CHECK_INST {
01172
union {
01173
struct {
01174 ULONGLONG qp: 6;
01175 ULONGLONG imm7: 7;
01176 ULONGLONG r2: 7;
01177 ULONGLONG imm13:13;
01178 ULONGLONG x3: 3;
01179 ULONGLONG s: 1;
01180 ULONGLONG Op: 4;
01181 ULONGLONG Rsv: 23;
01182 } i;
01183 ULONGLONG Ulong64;
01184 } u;
01185 } CHECK_INST;
01186
01187 BOOLEAN
01188 KiEmulateSpeculationFault(
01189 IN PKTRAP_FRAME TrapFrame
01190 )
01191 {
01192 PULONGLONG BundleAddress;
01193 ULONGLONG BundleLow;
01194 ULONGLONG BundleHigh;
01195 ULONG SlotNumber;
01196 CHECK_INST CheckInst;
01197 ISR Isr;
01198 ULONGLONG Imm24;
01199
01200 BundleAddress = (PULONGLONG)TrapFrame->StIIP;
01201
01202 BundleLow = *BundleAddress;
01203 BundleHigh = *(BundleAddress+1);
01204
01205 Isr.ull = TrapFrame->StISR;
01206 SlotNumber = (ULONG)Isr.sb.isr_ei;
01207
01208
01209
01210
01211
01212
switch (SlotNumber) {
01213
case 0:
01214 CheckInst.u.Ulong64 = BundleLow >> 5;
01215
break;
01216
01217
case 1:
01218 CheckInst.u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
01219
break;
01220
01221
case 2:
01222 CheckInst.u.Ulong64 = (BundleHigh >> 23);
01223
break;
01224 }
01225
01226
01227
01228
01229
01230 Imm24 = ((CheckInst.u.i.imm13 << 7)|(CheckInst.u.i.imm7)) << 4;
01231
01232
if (CheckInst.u.i.s == 1) {
01233
01234 Imm24 = 0xFFFFFFFFFF000000|Imm24;
01235
01236 }
01237
01238 TrapFrame->StIIP += Imm24;
01239
01240 TrapFrame->StIPSR &= ~(3i64 << PSR_RI);
01241
01242
return FALSE;
01243 }
01244
#endif