1683{
1688#if (_MI_PAGING_LEVELS >= 3)
1690#if (_MI_PAGING_LEVELS == 4)
1692#endif
1693#endif
1699 ULONG ProtectionCode;
1706
1707
1709 {
1710#if (_MI_PAGING_LEVELS < 3)
1711
1714#endif
1715
1716 if (
1719#endif
1722#endif
1725 {
1726
1727 DbgPrint(
"MM:***PAGE FAULT AT IRQL > 1 Va %p, IRQL %lx\n",
1730 if (TrapInformation)
1731 {
1733#ifdef _M_IX86
1735 DbgPrint(
"MM:***EAX %p, ECX %p EDX %p\n", TrapFrame->
Eax, TrapFrame->
Ecx, TrapFrame->
Edx);
1736 DbgPrint(
"MM:***EBX %p, ESI %p EDI %p\n", TrapFrame->
Ebx, TrapFrame->
Esi, TrapFrame->
Edi);
1737#elif defined(_M_AMD64)
1739 DbgPrint(
"MM:***RAX %p, RCX %p RDX %p\n", TrapFrame->
Rax, TrapFrame->
Rcx, TrapFrame->
Rdx);
1740 DbgPrint(
"MM:***RBX %p, RSI %p RDI %p\n", TrapFrame->
Rbx, TrapFrame->
Rsi, TrapFrame->
Rdi);
1741#elif defined(_M_ARM)
1743 DbgPrint(
"MM:***R0 %p, R1 %p R2 %p, R3 %p\n", TrapFrame->
R0, TrapFrame->
R1, TrapFrame->
R2, TrapFrame->
R3);
1744 DbgPrint(
"MM:***R11 %p, R12 %p SP %p, LR %p\n", TrapFrame->
R11, TrapFrame->
R12, TrapFrame->
Sp, TrapFrame->
Lr);
1745#endif
1746 }
1747
1748
1750 }
1751
1752
1755
1756
1758 {
1759
1761 if (!(PointerPte->
u.
Long & PTE_READWRITE) &&
1763 {
1764
1769 10);
1770 }
1771 }
1772
1773
1776 }
1777
1778
1780 {
1781
1783
1784#if (_MI_PAGING_LEVELS == 2)
1787#endif
1788
1789
1790 if (
1792
1794#endif
1796
1798#endif
1799
1801 {
1802
1805 FaultCode,
1807 2);
1808 }
1809
1810
1812
1813
1816 {
1817
1818 if (!IsSessionAddress)
1819 {
1820
1824 {
1825
1827 {
1828
1830 if (!(PointerPte->
u.
Long & PTE_READWRITE) &&
1832 {
1833
1838 11);
1839 }
1840 }
1841
1842
1845 {
1850 1);
1851 }
1852 }
1853
1854
1857 }
1858 }
1859#if (_MI_PAGING_LEVELS == 2)
1860
1862 {
1863
1866 {
1867
1870 FaultCode,
1872 6);
1873 }
1874 }
1875#else
1876
1877_WARN(
"Session space stuff is not implemented yet!")
1878
1879#endif
1880
1881
1883 {
1884#if (_MI_PAGING_LEVELS < 3)
1885
1887#endif
1888
1889 goto UserFault;
1890 }
1891
1892
1894
1895
1896 if (!IsSessionAddress)
1897 {
1898
1900 CurrentProcess =
NULL;
1901
1902
1909 {
1910
1912 }
1913 }
1914 else
1915 {
1916
1919
1920
1923 {
1924
1926 }
1927 }
1928
1929
1932
1933
1936 {
1937
1939 {
1940
1942 if (!(
TempPte.u.Long & PTE_READWRITE) &&
1945 {
1946
1947 ASSERT(!IsSessionAddress);
1948
1949
1954 12);
1955 }
1956 }
1957
1958
1961 {
1966 2);
1967 }
1968
1969
1970 if ((IsSessionAddress) &&
1973 {
1974
1976
1977
1979 {
1980
1985 13);
1986 }
1987
1988
1990 }
1991
1992
1995
1996
1998 }
1999
2000
2002 {
2003
2010 {
2011
2014 FaultCode,
2016 4);
2017 }
2018
2019
2021
2022
2023 if ((IsSessionAddress) &&
2025 {
2026
2028 &ProtectionCode,
2029 &Vad);
2031 }
2032 }
2033 else
2034 {
2035
2037
2038
2040 {
2041
2044 FaultCode,
2046 1);
2047 }
2048
2049
2051 {
2052
2055 FaultCode,
2057 0);
2058 }
2059 }
2060
2061
2063 !(ProtoPte) &&
2064 !(IsSessionAddress) &&
2066 {
2067
2070 {
2071
2076 14);
2077 }
2078 }
2079
2080
2083 PointerPte,
2084 ProtoPte,
2086 CurrentProcess,
2087 TrapInformation,
2089
2090
2094
2095
2098 }
2099
2100
2101UserFault:
2104
2105
2107
2109
2110#if (_MI_PAGING_LEVELS == 4)
2111
2113 {
2114
2116
2117
2119
2120
2123 {
2126 }
2127
2128
2130 PointerPxe,
2132 CurrentProcess,
2134
2135
2137 }
2138#endif
2139
2140#if (_MI_PAGING_LEVELS >= 3)
2141
2143 {
2144
2146
2147
2149
2150
2152 {
2154 }
2155
2157 {
2160 }
2161
2162
2164 PointerPpe,
2166 CurrentProcess,
2168
2169
2172 }
2173#endif
2174
2175
2177 {
2178
2180
2181
2182#if MI_TRACE_PFNS
2183 UserPdeFault =
TRUE;
2184#endif
2185
2187 {
2189 }
2190
2192 {
2193#if (_MI_PAGING_LEVELS == 2)
2194
2196#endif
2197
2199
2200
2203 }
2204
2205
2207 PointerPde,
2209 CurrentProcess,
2211#if _MI_PAGING_LEVELS >= 3
2213#endif
2214
2215#if MI_TRACE_PFNS
2216 UserPdeFault =
FALSE;
2217
2218 if (TrapInformation)
2220 else
2222#endif
2223
2226 }
2227 else
2228 {
2229
2231 }
2232
2233
2235
2236
2238 {
2239
2241 {
2242
2244 {
2245 PFN_NUMBER PageFrameIndex, OldPageFrameIndex;
2247
2248 LockIrql = MiAcquirePfnLock();
2249
2251
2254
2255
2258
2259 MiCopyPfn(PageFrameIndex, OldPageFrameIndex);
2260
2261
2267
2268
2272 TempPte.u.Hard.CopyOnWrite = 0;
2273
2275
2276 MiReleasePfnLock(LockIrql);
2277
2278
2281 }
2282
2283
2285 {
2286
2289 }
2290 }
2291
2292
2295 {
2296
2299 }
2300
2301
2304 }
2305
2306
2309 {
2310
2312 PointerPte,
2314 CurrentProcess,
2316
2317#if MI_TRACE_PFNS
2318
2319 if (TrapInformation)
2321 else
2323#endif
2324
2325
2328 }
2329
2330
2332 {
2333
2336 {
2337#if (_MI_PAGING_LEVELS == 2)
2338
2340#endif
2341
2343
2344
2347 }
2348
2349
2350
2351
2352
2358#endif
2359#endif
2360 )
2361 {
2362
2364 }
2365
2366
2368 {
2369
2371
2372
2373 TempPte.u.Soft.Protection = ProtectionCode & ~MM_GUARDPAGE;
2375
2376
2378 ASSERT(CurrentThread->ApcNeeded == 0);
2379
2380
2383
2384
2386 }
2387
2388
2389 if (!ProtoPte)
2390 {
2391
2393 {
2394
2395#ifdef _M_ARM
2396 _WARN(
"This is probably completely broken!");
2398#else
2400#endif
2401 }
2402 else
2403 {
2404
2405 TempPte.u.Soft.Protection = ProtectionCode;
2407 }
2408
2409
2411
2412
2414
2415
2420 if (!PageFrameIndex)
2421 {
2422
2425
2426
2428
2429
2431
2432
2434 }
2435
2436
2438
2439
2441
2442
2444
2445
2447
2448
2450 {
2451
2453 PointerPte,
2455 PageFrameIndex);
2456 }
2457 else
2458 {
2459
2461 PointerPte,
2463 PageFrameIndex);
2464 }
2465
2466
2468
2469
2473
2474
2478 }
2479
2480
2481 ASSERT(ProtectionCode != 0x100);
2482
2483
2485 TempPte.u.Soft.Protection = ProtectionCode;
2488 }
2489 else
2490 {
2491
2494 {
2495
2497 {
2498
2500 &ProtectionCode,
2501 &Vad);
2502 if (!ProtoPte)
2503 {
2507 }
2508 }
2509 else
2510 {
2511
2513
2514
2516 {
2517
2519 }
2520 else
2521 {
2522
2523 ProtectionCode = 0x100;
2525 }
2526 }
2527 }
2528 }
2529
2530
2531 if (ProtectionCode != 0x100)
2532 {
2533
2537 ProtectionCode,
2538 TrapInformation,
2541 {
2542
2543 ASSERT(CurrentThread->ApcNeeded == 0);
2544
2545
2548
2549
2551 {
2552
2554 }
2555
2556
2558 }
2559 }
2560
2561
2564 PointerPte,
2565 ProtoPte,
2567 CurrentProcess,
2568 TrapInformation,
2569 Vad);
2570
2571
2575}
#define KeRaiseIrql(irql, oldIrql)
#define KeLowerIrql(oldIrql)
#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)
#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)
#define MiAddressToPde(x)
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)
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)
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)
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
PFN_NUMBER NumberOfPrivatePages
ULONG OwnsSessionWorkingSetExclusive
ULONG OwnsSessionWorkingSetShared
ULONG OwnsSystemWorkingSetShared
ULONG OwnsProcessWorkingSetShared
ULONG OwnsProcessWorkingSetExclusive
ULONG OwnsSystemWorkingSetExclusive
struct _MM_SESSION_SPACE * GlobalVirtualAddress