1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: BSD-3-Clause (https://spdx.org/licenses/BSD-3-Clause) 4 * FILE: ntoskrnl/mm/i386/procsup.c 5 * PURPOSE: Process handling for i386 architecture 6 * PROGRAMMERS: Jérôme Gardou 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include <ntoskrnl.h> 12 #define NDEBUG 13 #include <debug.h> 14 15 #define MODULE_INVOLVED_IN_ARM3 16 #include <mm/ARM3/miarm.h> 17 18 BOOLEAN 19 MiArchCreateProcessAddressSpace( 20 _In_ PEPROCESS Process, 21 _In_ PULONG_PTR DirectoryTableBase) 22 { 23 PFN_NUMBER PdeIndex = DirectoryTableBase[0] >> PAGE_SHIFT; 24 PFN_NUMBER HyperIndex = DirectoryTableBase[1] >> PAGE_SHIFT; 25 PMMPTE PointerPte; 26 MMPTE PdePte, TempPte; 27 PMMPTE PteTable; 28 ULONG PdeOffset; 29 KIRQL OldIrql; 30 31 /* Get a PTE */ 32 PointerPte = MiReserveSystemPtes(1, SystemPteSpace); 33 if (!PointerPte) 34 return FALSE; 35 PteTable = MiPteToAddress(PointerPte); 36 37 /* Build a page table for hyper space */ 38 MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, 39 PointerPte, 40 MM_READWRITE, 41 HyperIndex); 42 43 /* Set it dirty and map it */ 44 MI_MAKE_DIRTY_PAGE(&PdePte); 45 MI_WRITE_VALID_PTE(PointerPte, PdePte); 46 47 /* Now write the PTE/PDE entry for the working set list index itself */ 48 TempPte = ValidKernelPteLocal; 49 TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage; 50 PdeOffset = MiAddressToPteOffset(MmWorkingSetList); 51 PteTable[PdeOffset] = TempPte; 52 53 /* Now we map the page directory */ 54 MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, 55 PointerPte, 56 MM_READWRITE, 57 PdeIndex); 58 59 /* Set it dirty and map it */ 60 MI_MAKE_DIRTY_PAGE(&PdePte); 61 *PointerPte = PdePte; 62 /* We changed the page! */ 63 __invlpg(PteTable); 64 65 /* Now get the page directory (which we'll double map, so call it a page table) */ 66 PteTable = MiPteToAddress(PointerPte); 67 68 /* Copy all the kernel mappings */ 69 PdeOffset = MiGetPdeOffset(MmSystemRangeStart); 70 RtlCopyMemory(&PteTable[PdeOffset], 71 MiAddressToPde(MmSystemRangeStart), 72 PAGE_SIZE - PdeOffset * sizeof(MMPTE)); 73 74 /* Now write the PTE/PDE entry for hyperspace itself */ 75 TempPte = ValidKernelPteLocal; 76 TempPte.u.Hard.PageFrameNumber = HyperIndex; 77 PdeOffset = MiGetPdeOffset(HYPER_SPACE); 78 PteTable[PdeOffset] = TempPte; 79 80 /* Sanity check */ 81 PdeOffset++; 82 ASSERT(MiGetPdeOffset(MmHyperSpaceEnd) >= PdeOffset); 83 84 /* Now do the x86 trick of making the PDE a page table itself */ 85 PdeOffset = MiGetPdeOffset(PTE_BASE); 86 TempPte.u.Hard.PageFrameNumber = PdeIndex; 87 PteTable[PdeOffset] = TempPte; 88 89 /* Let go of the system PTE */ 90 MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace); 91 92 /* Insert us into the Mm process list */ 93 OldIrql = MiAcquireExpansionLock(); 94 InsertTailList(&MmProcessList, &Process->MmProcessLinks); 95 MiReleaseExpansionLock(OldIrql); 96 97 return TRUE; 98 } 99