reactos/ntoskrnl/mm/mmfault.c

279 lines
7.3 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mmfault.c
* PURPOSE: Kernel memory managment functions
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
[CACHE] The cache manager rewrite I started years ago has finally appeared in ReactOS' trunk and although at this point it's not quite perfectly integrated, it's enough to boot up the bootcd or livecd. To check out the more mature original, check out arty-newcc-reactos, branch arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit to not give up on it, and was able to reach out and be an advocate when i really wasn't able to. Others agree that the time has come to begin removing the old cache manager. I expect the remaining problems in the version going to trunk will be taken care of relatively quickly. The motivation for this effort lies in the particularly hairy relationship between ReactOS' cache manager and data sections. This code completely removes page sharing between cache manager and section and reimagines cache manager as being a facility layered on the memory manager, not really caring about individual pages, but simply managing data section objects where caching might occur. It took me about 2 years to do the first pass of this rewrite and most of this year to fix some lingering issues, properly implement demand paging in ReactOS (code which didn't come with this patch in a recognizable form), and finish getting the PrivateCacheMap and SharedCacheMap relationship correct. Currently, the new ntoskrnl/cache directory contains an own implementation of data file sections. After things have settled down, we can begin to deprecate and remove the parts of ReactOS' section implementation that depend on a close relationship with cache manager. Eventually, I think that the extra code added to ntoskrnl/cache/section will be removed and ReactOS' own sections will replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache path. Note also, that this makes all cache manager (and new section parts) use wide file offsets. If my section code were to take over other parts of the ReactOS memory manager, they would also benefit from these improvements. I invite anyone who wants to to peek at this code and fix whatever bugs can be found. svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
#ifdef NEWCC
#include "../cache/section/newmm.h"
#endif
#define NDEBUG
#include <debug.h>
#define MODULE_INVOLVED_IN_ARM3
#include "ARM3/miarm.h"
/* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS
NTAPI
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
MmpAccessFault(KPROCESSOR_MODE Mode,
ULONG_PTR Address,
BOOLEAN FromMdl)
{
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
BOOLEAN Locked = FromMdl;
DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
return(STATUS_UNSUCCESSFUL);
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
Status = MmAccessFaultSectionView(AddressSpace,
MemoryArea,
(PVOID)Address,
Locked);
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
Status = STATUS_ACCESS_VIOLATION;
break;
[CACHE] The cache manager rewrite I started years ago has finally appeared in ReactOS' trunk and although at this point it's not quite perfectly integrated, it's enough to boot up the bootcd or livecd. To check out the more mature original, check out arty-newcc-reactos, branch arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit to not give up on it, and was able to reach out and be an advocate when i really wasn't able to. Others agree that the time has come to begin removing the old cache manager. I expect the remaining problems in the version going to trunk will be taken care of relatively quickly. The motivation for this effort lies in the particularly hairy relationship between ReactOS' cache manager and data sections. This code completely removes page sharing between cache manager and section and reimagines cache manager as being a facility layered on the memory manager, not really caring about individual pages, but simply managing data section objects where caching might occur. It took me about 2 years to do the first pass of this rewrite and most of this year to fix some lingering issues, properly implement demand paging in ReactOS (code which didn't come with this patch in a recognizable form), and finish getting the PrivateCacheMap and SharedCacheMap relationship correct. Currently, the new ntoskrnl/cache directory contains an own implementation of data file sections. After things have settled down, we can begin to deprecate and remove the parts of ReactOS' section implementation that depend on a close relationship with cache manager. Eventually, I think that the extra code added to ntoskrnl/cache/section will be removed and ReactOS' own sections will replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache path. Note also, that this makes all cache manager (and new section parts) use wide file offsets. If my section code were to take over other parts of the ReactOS memory manager, they would also benefit from these improvements. I invite anyone who wants to to peek at this code and fix whatever bugs can be found. svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
#ifdef NEWCC
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.
if (!FromMdl)
MmUnlockAddressSpace(AddressSpace);
Status = MmAccessFaultCacheSection(Mode, Address, Locked);
if (!FromMdl)
MmLockAddressSpace(AddressSpace);
break;
#endif
default:
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
Status = STATUS_ACCESS_VIOLATION;
break;
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
}
NTSTATUS
NTAPI
MmNotPresentFault(KPROCESSOR_MODE Mode,
ULONG_PTR Address,
BOOLEAN FromMdl)
{
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
BOOLEAN Locked = FromMdl;
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address);
return(STATUS_UNSUCCESSFUL);
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("Address: %x\n", Address);
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
/*
* Call the memory area specific fault handler
*/
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
Status = MmNotPresentFaultSectionView(AddressSpace,
MemoryArea,
(PVOID)Address,
Locked);
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
MemoryArea,
(PVOID)Address,
Locked);
break;
[CACHE] The cache manager rewrite I started years ago has finally appeared in ReactOS' trunk and although at this point it's not quite perfectly integrated, it's enough to boot up the bootcd or livecd. To check out the more mature original, check out arty-newcc-reactos, branch arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit to not give up on it, and was able to reach out and be an advocate when i really wasn't able to. Others agree that the time has come to begin removing the old cache manager. I expect the remaining problems in the version going to trunk will be taken care of relatively quickly. The motivation for this effort lies in the particularly hairy relationship between ReactOS' cache manager and data sections. This code completely removes page sharing between cache manager and section and reimagines cache manager as being a facility layered on the memory manager, not really caring about individual pages, but simply managing data section objects where caching might occur. It took me about 2 years to do the first pass of this rewrite and most of this year to fix some lingering issues, properly implement demand paging in ReactOS (code which didn't come with this patch in a recognizable form), and finish getting the PrivateCacheMap and SharedCacheMap relationship correct. Currently, the new ntoskrnl/cache directory contains an own implementation of data file sections. After things have settled down, we can begin to deprecate and remove the parts of ReactOS' section implementation that depend on a close relationship with cache manager. Eventually, I think that the extra code added to ntoskrnl/cache/section will be removed and ReactOS' own sections will replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache path. Note also, that this makes all cache manager (and new section parts) use wide file offsets. If my section code were to take over other parts of the ReactOS memory manager, they would also benefit from these improvements. I invite anyone who wants to to peek at this code and fix whatever bugs can be found. svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
#ifdef NEWCC
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.
if (!FromMdl)
MmUnlockAddressSpace(AddressSpace);
Status = MmNotPresentFaultCacheSection(Mode, Address, Locked);
if (!FromMdl)
MmLockAddressSpace(AddressSpace);
break;
#endif
default:
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
Status = STATUS_ACCESS_VIOLATION;
break;
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
}
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
NTSTATUS
NTAPI
MmAccessFault(IN BOOLEAN StoreInstruction,
IN PVOID Address,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation)
{
PMEMORY_AREA MemoryArea = NULL;
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Cute little hack for ROS */
if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)
{
#ifdef _M_IX86
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Check for an invalid page directory in kernel mode */
if (Mmi386MakeKernelPageTableGlobal(Address))
{
/* All is well with the world */
return STATUS_SUCCESS;
}
#endif
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
}
/* Is there a ReactOS address space yet? */
if (MmGetKernelAddressSpace())
{
/* Check if this is an ARM3 memory area */
MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address);
if (!(MemoryArea) && (Address <= MM_HIGHEST_USER_ADDRESS))
{
/* Could this be a VAD fault from user-mode? */
MemoryArea = MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address);
}
}
/* Is this an ARM3 memory area, or is there no address space yet? */
if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) ||
(!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
(!MmGetKernelAddressSpace()))
{
/* This is an ARM3 fault */
DPRINT("ARM3 fault %p\n", MemoryArea);
return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
}
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Keep same old ReactOS Behaviour */
if (StoreInstruction)
{
/* Call access fault */
return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
}
else
{
/* Call not present */
return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
}
}