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

View file

@ -1,4 +1,4 @@
/*
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/mm/mminit.c
@ -77,6 +77,21 @@ MiInitSystemMemoryAreas()
NTSTATUS Status;
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
//
@ -284,8 +299,8 @@ MiDbgDumpAddressSpace(VOID)
// Print the memory layout
//
DPRINT1(" 0x%p - 0x%p\t%s\n",
MmSystemRangeStart,
(ULONG_PTR)MmSystemRangeStart + MmBootImageSize,
KSEG0_BASE,
(ULONG_PTR)KSEG0_BASE + MmBootImageSize,
"Boot Loaded Image");
DPRINT1(" 0x%p - 0x%p\t%s\n",
MmPagedPoolBase,