From 0067e2c1a56a09beec0e744a6c8fd4710b59f75f Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Sun, 12 Jul 2009 13:06:41 +0000 Subject: [PATCH] =?UTF-8?q?-=20Fix=20several=20problems=20with=20the=20Sys?= =?UTF-8?q?tem=20PTE=20implementation,=20including=20the=20lack=20of=20loc?= =?UTF-8?q?ks.=20=20=20-=20I=20also=20didn't=20fully=20like=20the=20idea?= =?UTF-8?q?=20of=20sticking=20"-1"=20into=20a=205-bit=20wide=20bitfield=20?= =?UTF-8?q?--=20instead=20just=20stuff=20it=20as=200xFFFFF=20with=20a=20ty?= =?UTF-8?q?pecast.=20=20=20=20=20-=20This=20seems=20to=20be=20NT's=20MM=5F?= =?UTF-8?q?EMPTY=5FLIST=20that=20shows=20up=20in=20a=20couple=20of=20ASSER?= =?UTF-8?q?Ts=20on=20the=20checked=20build.=20-=20This=20fixes=20several?= =?UTF-8?q?=20random=20crashes=20seen=20on=20my=20test=20boxes=20when=20ma?= =?UTF-8?q?pping=20MDLs=20and=20using=20NP=20expansion=20VA.=20-=20Dedicat?= =?UTF-8?q?ed=20to=20Br=C3=BCno.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=41934 --- reactos/ntoskrnl/mm/ARM3/syspte.c | 44 +++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/syspte.c b/reactos/ntoskrnl/mm/ARM3/syspte.c index 6a5164831ca..df076d084e7 100644 --- a/reactos/ntoskrnl/mm/ARM3/syspte.c +++ b/reactos/ntoskrnl/mm/ARM3/syspte.c @@ -33,6 +33,7 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType, IN ULONG Alignment) { + KIRQL OldIrql; PMMPTE PointerPte, NextPte, PreviousPte; ULONG_PTR ClusterSize; @@ -41,11 +42,23 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, // ASSERT(Alignment <= PAGE_SIZE); + // + // Lock the system PTE space + // + OldIrql = KeAcquireQueuedSpinLock(LockQueueSystemSpaceLock); + // // Get the first free cluster and make sure we have PTEs available // PointerPte = &MmFirstFreeSystemPte[SystemPtePoolType]; - if (PointerPte->u.List.NextEntry == -1) return NULL; + if (PointerPte->u.List.NextEntry == ((ULONG)0xFFFFF)) + { + // + // Fail + // + KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); + return NULL; + } // // Now move to the first free system PTE cluster @@ -96,6 +109,7 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, // Decrement the free count and move to the next starting PTE // MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes; + KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); PointerPte += (ClusterSize - NumberOfPtes); break; } @@ -126,7 +140,14 @@ MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes, // // We couldn't find what you wanted -- is this the last cluster? // - if (PointerPte->u.List.NextEntry == -1) return NULL; + if (PointerPte->u.List.NextEntry == ((ULONG)0xFFFFF)) + { + // + // Fail + // + KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); + return NULL; + } // // Go to the next cluster @@ -164,20 +185,27 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType) { + KIRQL OldIrql; ULONG_PTR ClusterSize, CurrentSize; PMMPTE CurrentPte, NextPte, PointerPte; // - // Check to make sure the PTE address is within bounds. + // Check to make sure the PTE address is within bounds // ASSERT(NumberOfPtes != 0); ASSERT(StartingPte >= MmSystemPtesStart[SystemPtePoolType]); ASSERT(StartingPte <= MmSystemPtesEnd[SystemPtePoolType]); // - // Zero PTEs. + // Zero PTEs // - RtlZeroMemory(StartingPte, NumberOfPtes * sizeof (MMPTE)); + RtlZeroMemory(StartingPte, NumberOfPtes * sizeof(MMPTE)); + CurrentSize = (ULONG_PTR)(StartingPte - MmSystemPteBase); + + // + // Acquire the system PTE lock + // + OldIrql = KeAcquireQueuedSpinLock(LockQueueSystemSpaceLock); // // Increase availability @@ -187,7 +215,6 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte, // // Get the free cluster and start going through them // - CurrentSize = (ULONG_PTR)(StartingPte - MmSystemPteBase); CurrentPte = &MmFirstFreeSystemPte[SystemPtePoolType]; while (TRUE) { @@ -201,7 +228,7 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte, // Sanity check // ASSERT(((StartingPte + NumberOfPtes) <= PointerPte) || - (CurrentPte->u.List.NextEntry == -1)); + (CurrentPte->u.List.NextEntry == ((ULONG)0xFFFFF))); // // Get the next cluster in case it's the one @@ -312,6 +339,7 @@ MiReleaseSystemPtes(IN PMMPTE StartingPte, // // We released the PTEs into their cluster (and optimized the list) // + KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql); break; } @@ -350,7 +378,7 @@ MiInitializeSystemPtes(IN PMMPTE StartingPte, // // Make the first entry free and link it // - StartingPte->u.List.NextEntry = -1; + StartingPte->u.List.NextEntry = ((ULONG)0xFFFFF); MmFirstFreeSystemPte[PoolType].u.Long = 0; MmFirstFreeSystemPte[PoolType].u.List.NextEntry = StartingPte - MmSystemPteBase;