https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a34d9bcfb62b0e26d5361…
commit a34d9bcfb62b0e26d5361671f4324fb2293f5752
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Thu Apr 1 14:03:25 2021 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Thu Apr 8 15:40:37 2021 +0200
[NTOS:MM] Share "page.c" between i386 & amd64 builds
---
ntoskrnl/include/internal/amd64/mm.h | 7 -
ntoskrnl/mm/amd64/page.c | 621 -----------------------------------
ntoskrnl/ntos.cmake | 2 +-
3 files changed, 1 insertion(+), 629 deletions(-)
diff --git a/ntoskrnl/include/internal/amd64/mm.h b/ntoskrnl/include/internal/amd64/mm.h
index 1afab8fd17b..e62df71cfe0 100644
--- a/ntoskrnl/include/internal/amd64/mm.h
+++ b/ntoskrnl/include/internal/amd64/mm.h
@@ -295,13 +295,6 @@ MI_IS_MAPPED_PTE(PMMPTE PointerPte)
(PointerPte->u.Hard.PageFrameNumber != 0));
}
-FORCEINLINE
-VOID
-MmInitGlobalKernelPageDirectory(VOID)
-{
- /* Nothing to do */
-}
-
FORCEINLINE
BOOLEAN
MiIsPdeForAddressValid(PVOID Address)
diff --git a/ntoskrnl/mm/amd64/page.c b/ntoskrnl/mm/amd64/page.c
deleted file mode 100644
index 3a3c3e4c89a..00000000000
--- a/ntoskrnl/mm/amd64/page.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * COPYRIGHT: GPL, See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/amd64/page.c
- * PURPOSE: Low level memory managment manipulation
- *
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- * ReactOS Portable Systems Group
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-#include <mm/ARM3/miarm.h>
-
-#undef InterlockedExchangePte
-#define InterlockedExchangePte(pte1, pte2) \
- InterlockedExchange64((LONG64*)&pte1->u.Long, pte2.u.Long)
-
-#define PAGE_EXECUTE_ANY
(PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)
-#define PAGE_WRITE_ANY
(PAGE_EXECUTE_READWRITE|PAGE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOPY)
-#define PAGE_WRITECOPY_ANY (PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOPY)
-
-extern MMPTE HyperTemplatePte;
-
-/* GLOBALS *****************************************************************/
-
-const
-ULONG64
-MmProtectToPteMask[32] =
-{
- //
- // These are the base MM_ protection flags
- //
- 0,
- PTE_READONLY | PTE_ENABLE_CACHE,
- PTE_EXECUTE | PTE_ENABLE_CACHE,
- PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
- PTE_READWRITE | PTE_ENABLE_CACHE,
- PTE_WRITECOPY | PTE_ENABLE_CACHE,
- PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
- PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
- //
- // These OR in the MM_NOCACHE flag
- //
- 0,
- PTE_READONLY | PTE_DISABLE_CACHE,
- PTE_EXECUTE | PTE_DISABLE_CACHE,
- PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
- PTE_READWRITE | PTE_DISABLE_CACHE,
- PTE_WRITECOPY | PTE_DISABLE_CACHE,
- PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
- PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
- //
- // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
- //
- 0,
- PTE_READONLY | PTE_ENABLE_CACHE,
- PTE_EXECUTE | PTE_ENABLE_CACHE,
- PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
- PTE_READWRITE | PTE_ENABLE_CACHE,
- PTE_WRITECOPY | PTE_ENABLE_CACHE,
- PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
- PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
- //
- // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
- //
- 0,
- PTE_READONLY | PTE_WRITECOMBINED_CACHE,
- PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
- PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
- PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
- PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
- PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
- PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
-};
-
-const
-ULONG MmProtectToValue[32] =
-{
- PAGE_NOACCESS,
- PAGE_READONLY,
- PAGE_EXECUTE,
- PAGE_EXECUTE_READ,
- PAGE_READWRITE,
- PAGE_WRITECOPY,
- PAGE_EXECUTE_READWRITE,
- PAGE_EXECUTE_WRITECOPY,
- PAGE_NOACCESS,
- PAGE_NOCACHE | PAGE_READONLY,
- PAGE_NOCACHE | PAGE_EXECUTE,
- PAGE_NOCACHE | PAGE_EXECUTE_READ,
- PAGE_NOCACHE | PAGE_READWRITE,
- PAGE_NOCACHE | PAGE_WRITECOPY,
- PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
- PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
- PAGE_NOACCESS,
- PAGE_GUARD | PAGE_READONLY,
- PAGE_GUARD | PAGE_EXECUTE,
- PAGE_GUARD | PAGE_EXECUTE_READ,
- PAGE_GUARD | PAGE_READWRITE,
- PAGE_GUARD | PAGE_WRITECOPY,
- PAGE_GUARD | PAGE_EXECUTE_READWRITE,
- PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
- PAGE_NOACCESS,
- PAGE_WRITECOMBINE | PAGE_READONLY,
- PAGE_WRITECOMBINE | PAGE_EXECUTE,
- PAGE_WRITECOMBINE | PAGE_EXECUTE_READ,
- PAGE_WRITECOMBINE | PAGE_READWRITE,
- PAGE_WRITECOMBINE | PAGE_WRITECOPY,
- PAGE_WRITECOMBINE | PAGE_EXECUTE_READWRITE,
- PAGE_WRITECOMBINE | PAGE_EXECUTE_WRITECOPY
-};
-
-/* PRIVATE FUNCTIONS *******************************************************/
-
-BOOLEAN
-FORCEINLINE
-MiIsHyperspaceAddress(PVOID Address)
-{
- return ((ULONG64)Address >= HYPER_SPACE &&
- (ULONG64)Address <= HYPER_SPACE_END);
-}
-
-VOID
-MiFlushTlb(PMMPTE Pte, PVOID Address, KIRQL OldIrql)
-{
- if (MiIsHyperspaceAddress(Pte))
- {
- MiUnmapPageInHyperSpace(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Pte),
OldIrql);
- }
- else
- {
- __invlpg(Address);
- }
-}
-
-static
-PMMPTE
-MiGetPteForProcess(
- PEPROCESS Process,
- PVOID Address,
- BOOLEAN Create,
- PKIRQL OldIrql
-)
-{
- PMMPTE Pte;
- PMMPDE Pde;
- PMMPPE Ppe;
- PMMPXE Pxe;
-
- *OldIrql = 0;
- /* Make sure the process is correct */
- if (Address < MmSystemRangeStart)
- {
- /* FIXME: Implement this case */
- ASSERT(Process == PsGetCurrentProcess());
- }
- else
- {
- ASSERT((Process == NULL) || (Process == PsGetCurrentProcess()));
- }
-
- Pxe = MiAddressToPxe(Address);
- Ppe = MiAddressToPpe(Address);
- Pde = MiAddressToPde(Address);
- Pte = MiAddressToPte(Address);
-
- if (Create)
- {
- /* Check the PXE */
- if (Pxe->u.Long == 0)
- {
- /* Make it demand zero */
- MI_WRITE_INVALID_PDE(Pxe, DemandZeroPde);
- }
-
- /* Check the PPE */
- if (Ppe->u.Long == 0)
- {
- /* Make it demand zero */
- MI_WRITE_INVALID_PDE(Ppe, DemandZeroPde);
- }
-
- /* Check the PDE */
- if (Pde->u.Long == 0)
- {
- /* Make it demand zero */
- MI_WRITE_INVALID_PDE(Pde, DemandZeroPde);
- }
- }
- else
- {
- /* Check the PXE */
- if (!Pxe->u.Hard.Valid)
- return NULL;
-
- /* Check the PPE */
- if (!Ppe->u.Hard.Valid)
- return NULL;
-
- /* Check the PDE */
- if (!Pde->u.Hard.Valid)
- return NULL;
- }
-
- return Pte;
-}
-
-static
-ULONG64
-MiGetPteValueForProcess(
- PEPROCESS Process,
- PVOID Address)
-{
- PMMPTE Pte;
- ULONG64 PteValue;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
- PteValue = Pte ? Pte->u.Long : 0;
-
- if (MiIsHyperspaceAddress(Pte))
- MiUnmapPageInHyperSpace(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Pte),
OldIrql);
-
- return PteValue;
-}
-
-ULONG
-NTAPI
-MiGetPteProtection(MMPTE Pte)
-{
- ULONG Protect;
-
- if (!Pte.u.Flush.Valid)
- {
- Protect = PAGE_NOACCESS;
- }
- else if (Pte.u.Flush.NoExecute)
- {
- if (Pte.u.Flush.CopyOnWrite)
- Protect = PAGE_WRITECOPY;
- else if (Pte.u.Flush.Write)
- Protect = PAGE_READWRITE;
- else
- Protect = PAGE_READONLY;
- }
- else
- {
- if (Pte.u.Flush.CopyOnWrite)
- Protect = PAGE_EXECUTE_WRITECOPY;
- else if (Pte.u.Flush.Write)
- Protect = PAGE_EXECUTE_READWRITE;
- else
- Protect = PAGE_EXECUTE_READ;
- }
-
- if (Pte.u.Flush.CacheDisable)
- Protect |= PAGE_NOCACHE;
-
- if (Pte.u.Flush.WriteThrough)
- Protect |= PAGE_WRITETHROUGH;
-
- // PAGE_GUARD ?
- return Protect;
-}
-
-static
-VOID
-MiSetPteProtection(PMMPTE Pte, ULONG Protection)
-{
- Pte->u.Flush.CopyOnWrite = (Protection & PAGE_WRITECOPY_ANY) ? 1 : 0;
- Pte->u.Flush.Write = (Protection & PAGE_WRITE_ANY) ? 1 : 0;
- Pte->u.Flush.CacheDisable = (Protection & PAGE_NOCACHE) ? 1 : 0;
- Pte->u.Flush.WriteThrough = (Protection & PAGE_WRITETHROUGH) ? 1 : 0;
-
- // FIXME: This doesn't work. Why?
- Pte->u.Flush.NoExecute = (Protection & PAGE_EXECUTE_ANY) ? 0 : 1;
-}
-
-/* FUNCTIONS ***************************************************************/
-
-PFN_NUMBER
-NTAPI
-MmGetPfnForProcess(PEPROCESS Process,
- PVOID Address)
-{
- MMPTE Pte;
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
- return Pte.u.Hard.Valid ? Pte.u.Hard.PageFrameNumber : 0;
-}
-
-BOOLEAN
-NTAPI
-MmIsPagePresent(PEPROCESS Process, PVOID Address)
-{
- MMPTE Pte;
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
- return (BOOLEAN)Pte.u.Hard.Valid;
-}
-
-BOOLEAN
-NTAPI
-MmIsDisabledPage(PEPROCESS Process, PVOID Address)
-{
- MMPTE Pte;
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
-
- return (Pte.u.Hard.Valid == 0) &&
- (Pte.u.Trans.Transition == 0) &&
- (Pte.u.Hard.PageFrameNumber != 0);
-}
-
-BOOLEAN
-NTAPI
-MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
-{
- MMPTE Pte;
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
- return !Pte.u.Hard.Valid && Pte.u.Soft.Transition;
-}
-
-VOID
-NTAPI
-MmGetPageFileMapping(
- PEPROCESS Process,
- PVOID Address,
- SWAPENTRY* SwapEntry)
-{
- PMMPTE PointerPte;
-
- ASSERT(Process == PsGetCurrentProcess());
-
- PointerPte = MiAddressToPte(Address);
- *SwapEntry = PointerPte->u.Long >> 1;
-}
-
-BOOLEAN
-NTAPI
-MmIsDirtyPage(PEPROCESS Process, PVOID Address)
-{
- MMPTE Pte;
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
- return Pte.u.Hard.Valid && Pte.u.Hard.Dirty;
-}
-
-ULONG
-NTAPI
-MmGetPageProtect(PEPROCESS Process, PVOID Address)
-{
- MMPTE Pte;
-
- Pte.u.Long = MiGetPteValueForProcess(Process, Address);
-
- return MiGetPteProtection(Pte);
-}
-
-VOID
-NTAPI
-MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
-{
- PMMPTE Pte;
- MMPTE NewPte;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
- ASSERT(Pte != NULL);
-
- NewPte = *Pte;
-
- MiSetPteProtection(&NewPte, flProtect);
-
- InterlockedExchangePte(Pte, NewPte);
-
- MiFlushTlb(Pte, Address, OldIrql);
-}
-
-VOID
-NTAPI
-MmSetCleanPage(PEPROCESS Process, PVOID Address)
-{
- PMMPTE Pte;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
- if (!Pte)
- {
- KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
- }
-
- /* Ckear the dirty bit */
- if (InterlockedBitTestAndReset64((PVOID)Pte, 6))
- {
- if (!MiIsHyperspaceAddress(Pte))
- __invlpg(Address);
- }
-
- MiFlushTlb(Pte, Address, OldIrql);
-}
-
-VOID
-NTAPI
-MmSetDirtyPage(PEPROCESS Process, PVOID Address)
-{
- PMMPTE Pte;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
- if (!Pte)
- {
- KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
- }
-
- /* Ckear the dirty bit */
- if (InterlockedBitTestAndSet64((PVOID)Pte, 6))
- {
- if (!MiIsHyperspaceAddress(Pte))
- __invlpg(Address);
- }
-
- MiFlushTlb(Pte, Address, OldIrql);
-}
-
-VOID
-NTAPI
-MmDeleteVirtualMapping(
- PEPROCESS Process,
- PVOID Address,
- BOOLEAN* WasDirty,
- PPFN_NUMBER Page)
-{
- PFN_NUMBER Pfn;
- PMMPTE Pte;
- MMPTE OldPte;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
-
- if (Pte)
- {
- /* Atomically set the entry to zero and get the old value. */
- OldPte.u.Long = InterlockedExchange64((LONG64*)&Pte->u.Long, 0);
-
- if (OldPte.u.Hard.Valid)
- {
- Pfn = OldPte.u.Hard.PageFrameNumber;
- }
- else
- Pfn = 0;
- }
- else
- {
- OldPte.u.Long = 0;
- Pfn = 0;
- }
-
- /* Return information to the caller */
- if (WasDirty)
- *WasDirty = (BOOLEAN)OldPte.u.Hard.Dirty;
-
- if (Page)
- *Page = Pfn;
-
- MiFlushTlb(Pte, Address, OldIrql);
-}
-
-VOID
-NTAPI
-MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
- SWAPENTRY* SwapEntry)
-{
- PMMPTE Pte;
- KIRQL OldIrql;
-
- Pte = MiGetPteForProcess(Process, Address, FALSE, &OldIrql);
- if (Pte == NULL)
- {
- *SwapEntry = 0;
- return;
- }
-
- if (Pte->u.Trans.Valid || !Pte->u.Trans.Transition)
- {
- DPRINT1("Pte %x (want not 1 and 0x800)\n", Pte);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- *SwapEntry = Pte->u.Long >> 1;
- MI_ERASE_PTE(Pte);
-
- if (MiIsHyperspaceAddress(Pte))
- MiUnmapPageInHyperSpace(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Pte),
OldIrql);
-}
-
-NTSTATUS
-NTAPI
-MmCreatePageFileMapping(PEPROCESS Process,
- PVOID Address,
- SWAPENTRY SwapEntry)
-{
- PMMPTE Pte;
- MMPTE PteValue;
- KIRQL OldIrql;
-
- if (Process == NULL && Address < MmSystemRangeStart)
- {
- DPRINT1("No process\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (Process != NULL && Address >= MmSystemRangeStart)
- {
- DPRINT1("Setting kernel address with process context\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- if (SwapEntry & (1ull << 63))
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /* Allocate a PTE */
- Pte = MiGetPteForProcess(Process, Address, TRUE, &OldIrql);
- if (Pte == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- NT_ASSERT(Pte->u.Long == 0);
- PteValue.u.Long = SwapEntry << 1;
- MI_WRITE_INVALID_PTE(Pte, PteValue);
-
- if (MiIsHyperspaceAddress(Pte))
- MiUnmapPageInHyperSpace(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Pte),
OldIrql);
-
- return STATUS_UNSUCCESSFUL;
-}
-
-
-NTSTATUS
-NTAPI
-MmCreateVirtualMappingUnsafe(
- PEPROCESS Process,
- PVOID Address,
- ULONG PageProtection,
- PPFN_NUMBER Pages,
- ULONG PageCount)
-{
- ULONG i;
- MMPTE TmplPte, *Pte;
-
- ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
-
- /* Check if the range is valid */
- if ((Process == NULL && Address < MmSystemRangeStart) ||
- (Process != NULL && Address > MmHighestUserAddress))
- {
- DPRINT1("Address 0x%p is invalid for process %p\n", Address, Process);
- ASSERT(FALSE);
- }
-
- TmplPte.u.Long = 0;
- TmplPte.u.Hard.Valid = 1;
- MiSetPteProtection(&TmplPte, PageProtection);
-
- TmplPte.u.Flush.Owner = (Address < MmHighestUserAddress) ? 1 : 0;
-
-//__debugbreak();
-
- for (i = 0; i < PageCount; i++)
- {
- KIRQL OldIrql;
-
- TmplPte.u.Hard.PageFrameNumber = Pages[i];
-
- Pte = MiGetPteForProcess(Process, Address, TRUE, &OldIrql);
-
-DPRINT("MmCreateVirtualMappingUnsafe, Address=%p, TmplPte=%p, Pte=%p\n",
- Address, TmplPte.u.Long, Pte);
-
- if (InterlockedExchangePte(Pte, TmplPte))
- {
- KeInvalidateTlbEntry(Address);
- }
-
- if (MiIsHyperspaceAddress(Pte))
- MiUnmapPageInHyperSpace(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Pte),
OldIrql);
-
- Address = (PVOID)((ULONG64)Address + PAGE_SIZE);
- }
-
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-MmCreateVirtualMapping(PEPROCESS Process,
- PVOID Address,
- ULONG Protect,
- PPFN_NUMBER Pages,
- ULONG PageCount)
-{
- ULONG i;
-
- ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
-
- for (i = 0; i < PageCount; i++)
- {
- if (!MmIsPageInUse(Pages[i]))
- {
- DPRINT1("Page %x not in use\n", Pages[i]);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- }
-
- return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
-}
-
-/* EOF */
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index d3349f9f808..c392bcd95ec 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -328,6 +328,7 @@ elseif(ARCH STREQUAL "amd64")
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall_asm.S)
list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/config/i386/cmhardwr.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/mm/i386/page.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kd64/amd64/kdx64.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/context.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/cpu.c
@@ -339,7 +340,6 @@ elseif(ARCH STREQUAL "amd64")
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/spinlock.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
- ${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/procsup.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c