https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6da93539a96b2ad1c5935…
commit 6da93539a96b2ad1c59350a9e50c665901b7b5cd
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sat Aug 18 12:16:33 2018 +0200
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Aug 18 12:16:33 2018 +0200
[FREELDR] Fix calculation of page lookup table (#761)
On x64 we only map 1GB of pages, so adjust MM_MAX_PAGE accordingly and also respect
that value when searching for the best location of the page lookup table.
CORE-11048 #resolve
---
boot/freeldr/freeldr/include/mm.h | 3 +--
boot/freeldr/freeldr/lib/mm/meminit.c | 30 +++++++++++++++++++-----------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/boot/freeldr/freeldr/include/mm.h b/boot/freeldr/freeldr/include/mm.h
index d29fe6087f..adc13d0ebf 100644
--- a/boot/freeldr/freeldr/include/mm.h
+++ b/boot/freeldr/freeldr/include/mm.h
@@ -58,8 +58,7 @@ typedef struct _FREELDR_MEMORY_DESCRIPTOR
#define MM_PAGE_SIZE 4096
#define MM_PAGE_MASK 0xFFF
#define MM_PAGE_SHIFT 12
-// FIXME: freeldr implementation uses ULONG for page numbers
-#define MM_MAX_PAGE 0xFFFFFFFFFFFFF
+#define MM_MAX_PAGE 0x3FFFF /* freeldr only maps 1 GB */
#define MM_SIZE_TO_PAGES(a) \
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
diff --git a/boot/freeldr/freeldr/lib/mm/meminit.c
b/boot/freeldr/freeldr/lib/mm/meminit.c
index bbf7a571fe..164236c81c 100644
--- a/boot/freeldr/freeldr/lib/mm/meminit.c
+++ b/boot/freeldr/freeldr/lib/mm/meminit.c
@@ -415,13 +415,15 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
{
const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
SIZE_T PageLookupTableSize;
- PFN_NUMBER PageLookupTablePages;
- PFN_NUMBER PageLookupTableStartPage = 0;
+ PFN_NUMBER RequiredPages;
+ PFN_NUMBER CandidateBasePage = 0;
+ PFN_NUMBER CandidatePageCount;
+ PFN_NUMBER PageLookupTableEndPage;
PVOID PageLookupTableMemAddress = NULL;
// Calculate how much pages we need to keep the page lookup table
PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
- PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;
+ RequiredPages = PageLookupTableSize / MM_PAGE_SIZE;
// Search the highest memory block big enough to contain lookup table
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
@@ -429,22 +431,28 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
// Continue, if memory is not free
if (MemoryDescriptor->MemoryType != LoaderFree) continue;
- // Continue, if the block is not big enough?
- if (MemoryDescriptor->PageCount < PageLookupTablePages) continue;
+ // Continue, if the block is not big enough
+ if (MemoryDescriptor->PageCount < RequiredPages) continue;
// Continue, if it is not at a higher address than previous address
- if (MemoryDescriptor->BasePage < PageLookupTableStartPage) continue;
+ if (MemoryDescriptor->BasePage < CandidateBasePage) continue;
// Continue, if the address is too high
- if (MemoryDescriptor->BasePage >= MM_MAX_PAGE) continue;
+ if (MemoryDescriptor->BasePage + RequiredPages >= MM_MAX_PAGE) continue;
// Memory block is more suitable than the previous one
- PageLookupTableStartPage = MemoryDescriptor->BasePage;
- PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
- (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) *
MM_PAGE_SIZE
- - PageLookupTableSize);
+ CandidateBasePage = MemoryDescriptor->BasePage;
+ CandidatePageCount = MemoryDescriptor->PageCount;
}
+ // Calculate the end address for the lookup table
+ PageLookupTableEndPage = min(CandidateBasePage + CandidatePageCount,
+ MM_MAX_PAGE);
+
+ // Calculate the virtual address
+ PageLookupTableMemAddress = (PVOID)((PageLookupTableEndPage * PAGE_SIZE)
+ - PageLookupTableSize);
+
TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n",
PageLookupTableMemAddress);
return PageLookupTableMemAddress;