Rewrite the broken MmFindGap* functions. They were first searching for a gap between the already allocated memory areas and only after that trying to find a gap below or above these areas. This bug helped with 2 things. 1. Not overwriting the kernel mapping, because no memory area was defined for it and 2. allow csrss to map video memory at virtual adress 0x000a0000. The former is fixed by adding the appropriate memory area, the latter is hacked away, by making the addressing range start at 0x00100000. Also use MmHighestUserAddress instead of MmSystemRangestart - 1. Simplyfy overcomplicated code. Fix a DPRINT

svn path=/branches/ros-amd64-bringup/; revision=44327
This commit is contained in:
Timo Kreuzer 2009-11-30 00:24:55 +00:00
parent 8a4f13825c
commit 2fdf38accf
2 changed files with 48 additions and 82 deletions

View file

@ -469,13 +469,12 @@ MmFindGapBottomUp(
ULONG_PTR Length, ULONG_PTR Length,
ULONG_PTR Granularity) ULONG_PTR Granularity)
{ {
PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; // HACK: csrss really wants to map video memory at 0x000a0000 - 0x00100000, so keep that free
PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? (PVOID)0x00100000 : MmSystemRangeStart;
PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
(PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; MmHighestUserAddress : (PVOID)MAXULONG_PTR;
PVOID AlignedAddress; PVOID AlignedAddress;
PMEMORY_AREA Node; PMEMORY_AREA Root, Node;
PMEMORY_AREA FirstNode;
PMEMORY_AREA PreviousNode;
MmVerifyMemoryAreas(AddressSpace); MmVerifyMemoryAreas(AddressSpace);
@ -484,42 +483,28 @@ MmFindGapBottomUp(
AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity); AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity);
/* Special case for empty tree. */ Root = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
{
if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
{
DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
return AlignedAddress;
}
DPRINT("MmFindGapBottomUp: 0\n");
return 0;
}
/* Go to the node with lowest address in the tree. */ /* Go to the node with lowest address in the tree. */
FirstNode = Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); if (Root)
Node = MmIterateFirstNode(Root);
else
Node = NULL;
/* Traverse the tree from left to right. */ while (Node)
PreviousNode = Node;
for (;;)
{ {
Node = MmIterateNextNode(Node);
if (Node == NULL)
break;
AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
if (Node->StartingAddress > AlignedAddress && if (Node->StartingAddress > AlignedAddress &&
(ULONG_PTR)Node->StartingAddress - (ULONG_PTR)AlignedAddress >= Length) (ULONG_PTR)Node->StartingAddress >= (ULONG_PTR)AlignedAddress + Length)
{ {
DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress); DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
return AlignedAddress; return AlignedAddress;
} }
PreviousNode = Node; AlignedAddress = MM_ROUND_UP(Node->EndingAddress, Granularity);
Node = MmIterateNextNode(Node);
} }
/* Check if there is enough space after the last memory area. */ /* Check if there is enough space after the last memory area. */
AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
if ((ULONG_PTR)HighestAddress > (ULONG_PTR)AlignedAddress && if ((ULONG_PTR)HighestAddress > (ULONG_PTR)AlignedAddress &&
(ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length) (ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
{ {
@ -527,15 +512,6 @@ MmFindGapBottomUp(
return AlignedAddress; return AlignedAddress;
} }
/* Check if there is enough space before the first memory area. */
AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity);
if (FirstNode->StartingAddress > AlignedAddress &&
(ULONG_PTR)FirstNode->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
{
DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
return AlignedAddress;
}
DPRINT("MmFindGapBottomUp: 0\n"); DPRINT("MmFindGapBottomUp: 0\n");
return 0; return 0;
} }
@ -549,73 +525,47 @@ MmFindGapTopDown(
{ {
PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
(PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; MmHighestUserAddress : (PVOID)MAXULONG_PTR;
PVOID AlignedAddress; PVOID AlignedAddress;
PMEMORY_AREA Node; PMEMORY_AREA Root, Node;
PMEMORY_AREA PreviousNode;
MmVerifyMemoryAreas(AddressSpace); MmVerifyMemoryAreas(AddressSpace);
DPRINT("LowestAddress: %p HighestAddress: %p\n", DPRINT("LowestAddress: %p HighestAddress: %p\n",
LowestAddress, HighestAddress); LowestAddress, HighestAddress);
AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)HighestAddress - Length + 1, Granularity); AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)HighestAddress - Length, Granularity);
/* Check for overflow. */ /* Check for overflow. */
if (AlignedAddress > HighestAddress) if (AlignedAddress > HighestAddress)
return NULL; return NULL;
/* Special case for empty tree. */ Root = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
{
if (AlignedAddress >= LowestAddress)
{
DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
return AlignedAddress;
}
DPRINT("MmFindGapTopDown: 0\n");
return 0;
}
/* Go to the node with highest address in the tree. */ /* Go to the node with highest address in the tree. */
Node = MmIterateLastNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); if (Root)
Node = MmIterateLastNode(Root);
/* Check if there is enough space after the last memory area. */ else
if (Node->EndingAddress <= AlignedAddress) Node = NULL;
{
DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
return AlignedAddress;
}
/* Traverse the tree from left to right. */ /* Traverse the tree from left to right. */
PreviousNode = Node; while (Node)
for (;;)
{ {
Node = MmIteratePrevNode(Node);
if (Node == NULL)
break;
AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)PreviousNode->StartingAddress - Length + 1, Granularity);
/* Check for overflow. */
if (AlignedAddress > PreviousNode->StartingAddress)
return NULL;
if (Node->EndingAddress <= AlignedAddress) if (Node->EndingAddress <= AlignedAddress)
{ {
DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
return AlignedAddress; return AlignedAddress;
} }
PreviousNode = Node; AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)Node->StartingAddress - Length, Granularity);
}
AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)PreviousNode->StartingAddress - Length + 1, Granularity);
/* Check for overflow. */ /* Check for overflow. */
if (AlignedAddress > PreviousNode->StartingAddress) if (AlignedAddress > Node->StartingAddress)
return NULL; return NULL;
Node = MmIteratePrevNode(Node);
}
if (AlignedAddress >= LowestAddress) if (AlignedAddress >= LowestAddress)
{ {
DPRINT("MmFindGapTopDown: %p\n", AlignedAddress); DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
@ -944,6 +894,7 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace,
if ((*BaseAddress) == 0 && !FixedAddress) if ((*BaseAddress) == 0 && !FixedAddress)
{ {
tmpLength = PAGE_ROUND_UP(Length); tmpLength = PAGE_ROUND_UP(Length);
__debugbreak();
*BaseAddress = MmFindGap(AddressSpace, *BaseAddress = MmFindGap(AddressSpace,
tmpLength, tmpLength,
Granularity, Granularity,

View file

@ -1,4 +1,4 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/mm/mminit.c * FILE: ntoskrnl/mm/mminit.c
@ -77,6 +77,21 @@ MiInitSystemMemoryAreas()
NTSTATUS Status; NTSTATUS Status;
BoundaryAddressMultiple.QuadPart = 0; BoundaryAddressMultiple.QuadPart = 0;
//
// Create the memory area to define the loader mappings
//
BaseAddress = (PVOID)KSEG0_BASE;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
&BaseAddress,
MmBootImageSize,
PAGE_EXECUTE_READWRITE,
&MArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
// //
// Create the memory area to define the PTE base // Create the memory area to define the PTE base
// //
@ -284,8 +299,8 @@ MiDbgDumpAddressSpace(VOID)
// Print the memory layout // Print the memory layout
// //
DPRINT1(" 0x%p - 0x%p\t%s\n", DPRINT1(" 0x%p - 0x%p\t%s\n",
MmSystemRangeStart, KSEG0_BASE,
(ULONG_PTR)MmSystemRangeStart + MmBootImageSize, (ULONG_PTR)KSEG0_BASE + MmBootImageSize,
"Boot Loaded Image"); "Boot Loaded Image");
DPRINT1(" 0x%p - 0x%p\t%s\n", DPRINT1(" 0x%p - 0x%p\t%s\n",
MmPagedPoolBase, MmPagedPoolBase,