1712{
1717#if (_MI_PAGING_LEVELS >= 3)
1719#if (_MI_PAGING_LEVELS == 4)
1721#endif
1722#endif
1728 ULONG ProtectionCode;
1735
1736
1738 {
1739#if (_MI_PAGING_LEVELS < 3)
1740
1743#endif
1744
1745 if (
1748#endif
1751#endif
1754 {
1755
1756 DbgPrint(
"MM:***PAGE FAULT AT IRQL > 1 Va %p, IRQL %lx\n",
1759 if (TrapInformation)
1760 {
1762#ifdef _M_IX86
1764 DbgPrint(
"MM:***EAX %p, ECX %p EDX %p\n", TrapFrame->
Eax, TrapFrame->
Ecx, TrapFrame->
Edx);
1765 DbgPrint(
"MM:***EBX %p, ESI %p EDI %p\n", TrapFrame->
Ebx, TrapFrame->
Esi, TrapFrame->
Edi);
1766#elif defined(_M_AMD64)
1768 DbgPrint(
"MM:***RAX %p, RCX %p RDX %p\n", TrapFrame->
Rax, TrapFrame->
Rcx, TrapFrame->
Rdx);
1769 DbgPrint(
"MM:***RBX %p, RSI %p RDI %p\n", TrapFrame->
Rbx, TrapFrame->
Rsi, TrapFrame->
Rdi);
1770#elif defined(_M_ARM)
1772 DbgPrint(
"MM:***R0 %p, R1 %p R2 %p, R3 %p\n", TrapFrame->
R0, TrapFrame->
R1, TrapFrame->
R2, TrapFrame->
R3);
1773 DbgPrint(
"MM:***R11 %p, R12 %p SP %p, LR %p\n", TrapFrame->
R11, TrapFrame->
R12, TrapFrame->
Sp, TrapFrame->
Lr);
1774#endif
1775 }
1776
1777
1779 }
1780
1781
1784
1785
1787 {
1788
1790 if (!(PointerPte->
u.
Long & PTE_READWRITE) &&
1792 {
1793
1798 10);
1799 }
1800 }
1801
1802
1805 }
1806
1807
1809 {
1810
1812
1813#if (_MI_PAGING_LEVELS == 2)
1816#endif
1817
1818
1819 if (
1821
1823#endif
1825
1827#endif
1828
1830 {
1831
1834 FaultCode,
1836 2);
1837 }
1838
1839
1841
1842
1845 {
1846
1847 if (!IsSessionAddress)
1848 {
1849
1853 {
1854
1856 {
1857
1859 if (!(PointerPte->
u.
Long & PTE_READWRITE) &&
1861 {
1862
1867 11);
1868 }
1869 }
1870
1871
1874 {
1879 1);
1880 }
1881 }
1882
1883
1886 }
1887 }
1888#if (_MI_PAGING_LEVELS == 2)
1889
1891 {
1892
1895 {
1896
1899 FaultCode,
1901 6);
1902 }
1903 }
1904#else
1905
1906_WARN(
"Session space stuff is not implemented yet!")
1907
1908#endif
1909
1910
1912 {
1913#if (_MI_PAGING_LEVELS < 3)
1914
1916#endif
1917
1918 goto UserFault;
1919 }
1920
1921
1923
1924
1925 if (!IsSessionAddress)
1926 {
1927
1929 CurrentProcess =
NULL;
1930
1931
1938 {
1939
1941 }
1942 }
1943 else
1944 {
1945
1948
1949
1952 {
1953
1955 }
1956 }
1957RetryKernel:
1958
1961
1962
1965 {
1966
1968 {
1969
1971 if (!(
TempPte.u.Long & PTE_READWRITE) &&
1974 {
1975
1976 ASSERT(!IsSessionAddress);
1977
1978
1983 12);
1984 }
1985 }
1986
1987
1990 {
1995 2);
1996 }
1997
1998
1999 if ((IsSessionAddress) &&
2002 {
2003
2005
2006
2008 {
2009
2014 13);
2015 }
2016
2017
2019 }
2020
2021
2024
2025
2027 }
2028
2029
2031 {
2032
2039 {
2040
2043 FaultCode,
2045 4);
2046 }
2047
2048
2050
2051
2052 if ((IsSessionAddress) &&
2054 {
2055
2057 &ProtectionCode,
2058 &Vad);
2060 }
2061 }
2062 else
2063 {
2064
2066
2067
2069 {
2070
2073 FaultCode,
2075 1);
2076 }
2077
2078
2080 {
2081
2084 FaultCode,
2086 0);
2087 }
2088 }
2089
2090
2092 !(ProtoPte) &&
2093 !(IsSessionAddress) &&
2095 {
2096
2099 {
2100
2105 14);
2106 }
2107 }
2108
2109
2112 PointerPte,
2113 ProtoPte,
2115 CurrentProcess,
2116 TrapInformation,
2118
2119
2123
2125 {
2127 goto RetryKernel;
2128 }
2129
2130
2133 }
2134
2135
2136UserFault:
2139
2140
2142
2144
2145#if (_MI_PAGING_LEVELS == 4)
2146
2148 {
2149
2151
2152
2154
2155
2158 {
2161 }
2162
2163
2165 PointerPxe,
2167 CurrentProcess,
2170 {
2171 goto ExitUser;
2172 }
2173
2174
2176 }
2177#endif
2178
2179#if (_MI_PAGING_LEVELS >= 3)
2180
2182 {
2183
2185
2186
2188
2189
2191 {
2193 }
2194
2196 {
2199 }
2200
2201
2203 PointerPpe,
2205 CurrentProcess,
2208 {
2209 goto ExitUser;
2210 }
2211
2212
2215 }
2216#endif
2217
2218
2220 {
2221
2223
2224
2225#if MI_TRACE_PFNS
2226 UserPdeFault =
TRUE;
2227#endif
2228
2230 {
2232 }
2233
2235 {
2236#if (_MI_PAGING_LEVELS == 2)
2237
2239#endif
2240
2242
2243
2246 }
2247
2248
2250 PointerPde,
2252 CurrentProcess,
2255 {
2256 goto ExitUser;
2257 }
2258
2259#if _MI_PAGING_LEVELS >= 3
2261#endif
2262
2263#if MI_TRACE_PFNS
2264 UserPdeFault =
FALSE;
2265
2266 if (TrapInformation)
2268 else
2270#endif
2271
2274 }
2275 else
2276 {
2277
2279 }
2280
2281
2283
2284
2286 {
2287
2289 {
2290
2292 {
2293 PFN_NUMBER PageFrameIndex, OldPageFrameIndex;
2295
2296 LockIrql = MiAcquirePfnLock();
2297
2299
2302
2303
2305 if (PageFrameIndex == 0)
2306 {
2307 MiReleasePfnLock(LockIrql);
2309 goto ExitUser;
2310 }
2312
2313 MiCopyPfn(PageFrameIndex, OldPageFrameIndex);
2314
2315
2321
2322
2326 TempPte.u.Hard.CopyOnWrite = 0;
2327
2329
2330 MiReleasePfnLock(LockIrql);
2331
2332
2335 }
2336
2337
2339 {
2340
2343 }
2344 }
2345
2346#if _MI_HAS_NO_EXECUTE
2347
2350 {
2351
2353 {
2354
2359 }
2360
2361
2364 }
2365#endif
2366
2367
2370 }
2371
2372
2375 {
2376
2378 PointerPte,
2380 CurrentProcess,
2383 {
2384 goto ExitUser;
2385 }
2386
2387#if MI_TRACE_PFNS
2388
2389 if (TrapInformation)
2391 else
2393#endif
2394
2395
2398 }
2399
2400
2402 {
2403
2406 {
2407#if (_MI_PAGING_LEVELS == 2)
2408
2410#endif
2411
2413
2414
2417 }
2418
2419
2420
2421
2422
2428#endif
2429#endif
2430 )
2431 {
2432
2434 }
2435
2436
2438 {
2439
2441
2442
2443 TempPte.u.Soft.Protection = ProtectionCode & ~MM_GUARDPAGE;
2445
2446
2448 ASSERT(CurrentThread->ApcNeeded == 0);
2449
2450
2453
2454
2456 }
2457
2458
2459 if (!ProtoPte)
2460 {
2461
2463 {
2464
2465#ifdef _M_ARM
2466 _WARN(
"This is probably completely broken!");
2468#else
2470#endif
2471 }
2472 else
2473 {
2474
2475 TempPte.u.Soft.Protection = ProtectionCode;
2477 }
2478
2479
2481
2482
2483
2484
2485
2490 if (!PageFrameIndex)
2491 {
2492
2494
2495
2497
2498 if (PageFrameIndex == 0)
2499 {
2501 goto ExitUser;
2502 }
2503
2504
2506
2507
2509 }
2510
2511
2513
2514
2516
2517
2519
2520
2522
2523
2525 {
2526
2528 PointerPte,
2530 PageFrameIndex);
2531 }
2532 else
2533 {
2534
2536 PointerPte,
2538 PageFrameIndex);
2539 }
2540
2541
2543
2544
2548
2549
2553 }
2554
2555
2556 ASSERT(ProtectionCode != 0x100);
2557
2558
2560 TempPte.u.Soft.Protection = ProtectionCode;
2563 }
2564 else
2565 {
2566
2569 {
2570
2572 {
2573
2575 &ProtectionCode,
2576 &Vad);
2577 if (!ProtoPte)
2578 {
2582 }
2583 }
2584 else
2585 {
2586
2588
2589
2591 {
2592
2594 }
2595 else
2596 {
2597
2598 ProtectionCode = 0x100;
2600 }
2601 }
2602 }
2603 }
2604
2605
2606 if (ProtectionCode != 0x100)
2607 {
2608
2612 ProtectionCode,
2613 TrapInformation,
2616 {
2617
2618 ASSERT(CurrentThread->ApcNeeded == 0);
2619
2620
2623
2624
2626 {
2627
2629 }
2630
2631
2633 }
2634 }
2635
2636
2639 PointerPte,
2640 ProtoPte,
2642 CurrentProcess,
2643 TrapInformation,
2644 Vad);
2645
2646ExitUser:
2647
2648
2651
2653 {
2654
2656 {
2660 }
2661 else
2662 {
2664 }
2665
2666 goto UserFault;
2667 }
2668
2670}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
#define KeRaiseIrql(irql, oldIrql)
#define KeLowerIrql(oldIrql)
#define KeDelayExecutionThread(mode, foo, t)
#define KeGetCurrentThread
#define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address)
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
BOOLEAN MmProtectFreedNonPagedPool
FORCEINLINE BOOLEAN MiIsUserPte(PVOID Address)
#define MI_IS_SESSION_PTE(Pte)
#define MM_INVALID_PROTECTION
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
FORCEINLINE VOID MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde, IN MMPDE InvalidPde)
FORCEINLINE BOOLEAN MiIsUserPde(PVOID Address)
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
#define MI_IS_PFN_DELETED(x)
#define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address)
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
struct _EPROCESS * PEPROCESS
#define MI_IS_PAGE_EXECUTABLE(x)
#define MI_IS_WRITE_ACCESS(FaultCode)
#define MM_PTE_SOFTWARE_PROTECTION_BITS
#define MI_IS_INSTRUCTION_FETCH(FaultCode)
#define _MI_PAGING_LEVELS
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
#define MiProtoPteToPte(x)
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
#define MI_IS_PAGE_LARGE(x)
#define MiAddressToPde(x)
VOID NTAPI MmRebalanceMemoryConsumers(VOID)
ULONG MmSizeOfNonPagedPoolInBytes
PVOID MmNonPagedPoolExpansionStart
MMSUPPORT MmSystemCacheWs
PVOID MmNonPagedPoolStart
#define STATUS_PAGE_FAULT_COPY_ON_WRITE
#define STATUS_IN_PAGE_ERROR
static PMMPTE NTAPI MiCheckVirtualAddress(IN PVOID VirtualAddress, OUT PULONG ProtectCode, OUT PMMVAD *ProtoVad)
VOID NTAPI MmRebalanceMemoryConsumersAndWait(VOID)
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
static NTSTATUS NTAPI MiCheckForUserStackOverflow(IN PVOID Address, IN PVOID TrapInformation)
NTSTATUS NTAPI MiDispatchFault(IN ULONG FaultCode, IN PVOID Address, IN PMMPTE PointerPte, IN PMMPTE PointerProtoPte, IN BOOLEAN Recursive, IN PEPROCESS Process, IN PVOID TrapInformation, IN PMMVAD Vad)
static LARGE_INTEGER TinyTime
PFN_NUMBER NumberOfPrivatePages
EX_PUSH_LOCK AddressCreationLock
ULONG OwnsSessionWorkingSetExclusive
ULONG OwnsSessionWorkingSetShared
ULONG OwnsSystemWorkingSetShared
ULONG OwnsProcessWorkingSetShared
ULONG OwnsProcessWorkingSetExclusive
ULONG OwnsSystemWorkingSetExclusive
struct _MM_SESSION_SPACE * GlobalVirtualAddress