diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 05121c555c9..16d8613a983 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -662,14 +662,14 @@ VOID MmDeleteVirtualMapping(struct _EPROCESS* Process, BOOL* WasDirty, PPFN_TYPE Page); -VOID MmUpdateStackPageDir(PULONG LocalPageDir, struct _KTHREAD* KThread); - BOOLEAN MmIsDirtyPage(struct _EPROCESS* Process, PVOID Address); VOID MmMarkPageMapped(PFN_TYPE Page); VOID MmMarkPageUnmapped(PFN_TYPE Page); +VOID MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size); + /* wset.c ********************************************************************/ NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages); diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 6632e2efbdd..3481f290bb5 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: process.c,v 1.23 2004/08/15 16:39:05 chorns Exp $ +/* $Id: process.c,v 1.24 2004/08/19 21:47:51 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/process.c @@ -43,7 +43,6 @@ KeAttachProcess (PEPROCESS Process) { KIRQL oldlvl; PETHREAD CurrentThread; - PULONG AttachedProcessPageDir; ULONG PageDir; DPRINT("KeAttachProcess(Process %x)\n",Process); @@ -56,10 +55,6 @@ KeAttachProcess (PEPROCESS Process) KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT); } - KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); - - KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb); - /* The stack of the current process may be located in a page which is not present in the page directory of the process we're attaching to. That would lead to a page fault when this function returns. However, @@ -69,9 +64,11 @@ KeAttachProcess (PEPROCESS Process) To prevent this, make sure the page directory of the process we're attaching to is up-to-date. */ - AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT); - MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb); - ExUnmapPage(AttachedProcessPageDir); + MmUpdatePageDir(Process, (PVOID)CurrentThread->Tcb.StackLimit, MM_STACK_SIZE); + + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); + + KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb); CurrentThread->OldProcess = PsGetCurrentProcess(); CurrentThread->ThreadsProcess = Process; diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 36355794c64..e66458918c1 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: page.c,v 1.70 2004/08/15 16:39:09 chorns Exp $ +/* $Id: page.c,v 1.71 2004/08/19 21:47:51 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/i386/page.c @@ -1150,23 +1150,40 @@ MmGetPhysicalAddress(PVOID vaddr) return p; } - -VOID -MmUpdateStackPageDir(PULONG LocalPageDir, PKTHREAD PThread) +VOID MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size) { - unsigned EntryBase = ADDR_TO_PDE_OFFSET(PThread->StackLimit); - unsigned EntryTop = ADDR_TO_PDE_OFFSET((char*)PThread->InitialStack - PAGE_SIZE); + PULONG Pde; + ULONG StartOffset, EndOffset, Offset; - if (0 == LocalPageDir[EntryBase]) + if (Address < (PVOID)KERNEL_BASE) { - LocalPageDir[EntryBase] = MmGlobalKernelPageDirectory[EntryBase]; + KEBUGCHECK(0); } - if (EntryBase != EntryTop && 0 == LocalPageDir[EntryTop]) + + StartOffset = ADDR_TO_PDE_OFFSET(Address); + EndOffset = ADDR_TO_PDE_OFFSET(Address + Size); + + if (Process != NULL && Process != PsGetCurrentProcess()) { - LocalPageDir[EntryTop] = MmGlobalKernelPageDirectory[EntryTop]; + Pde = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.u.LowPart >> PAGE_SHIFT); + } + else + { + Pde = (PULONG)PAGEDIRECTORY_MAP; + } + for (Offset = StartOffset; Offset <= EndOffset; Offset++) + { + if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)) + { + InterlockedCompareExchange(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0); + } + } + if (Pde != (PULONG)PAGEDIRECTORY_MAP) + { + ExUnmapPage(Pde); } } - + VOID INIT_FUNCTION MmInitGlobalKernelPageDirectory(VOID) {