mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[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
This commit is contained in:
parent
27c3a4d26a
commit
6da93539a9
2 changed files with 20 additions and 13 deletions
|
@ -58,8 +58,7 @@ typedef struct _FREELDR_MEMORY_DESCRIPTOR
|
||||||
#define MM_PAGE_SIZE 4096
|
#define MM_PAGE_SIZE 4096
|
||||||
#define MM_PAGE_MASK 0xFFF
|
#define MM_PAGE_MASK 0xFFF
|
||||||
#define MM_PAGE_SHIFT 12
|
#define MM_PAGE_SHIFT 12
|
||||||
// FIXME: freeldr implementation uses ULONG for page numbers
|
#define MM_MAX_PAGE 0x3FFFF /* freeldr only maps 1 GB */
|
||||||
#define MM_MAX_PAGE 0xFFFFFFFFFFFFF
|
|
||||||
|
|
||||||
#define MM_SIZE_TO_PAGES(a) \
|
#define MM_SIZE_TO_PAGES(a) \
|
||||||
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
|
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
|
||||||
|
|
|
@ -415,13 +415,15 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
|
||||||
{
|
{
|
||||||
const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
|
||||||
SIZE_T PageLookupTableSize;
|
SIZE_T PageLookupTableSize;
|
||||||
PFN_NUMBER PageLookupTablePages;
|
PFN_NUMBER RequiredPages;
|
||||||
PFN_NUMBER PageLookupTableStartPage = 0;
|
PFN_NUMBER CandidateBasePage = 0;
|
||||||
|
PFN_NUMBER CandidatePageCount;
|
||||||
|
PFN_NUMBER PageLookupTableEndPage;
|
||||||
PVOID PageLookupTableMemAddress = NULL;
|
PVOID PageLookupTableMemAddress = NULL;
|
||||||
|
|
||||||
// Calculate how much pages we need to keep the page lookup table
|
// Calculate how much pages we need to keep the page lookup table
|
||||||
PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
|
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
|
// Search the highest memory block big enough to contain lookup table
|
||||||
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
|
||||||
|
@ -429,22 +431,28 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
|
||||||
// Continue, if memory is not free
|
// Continue, if memory is not free
|
||||||
if (MemoryDescriptor->MemoryType != LoaderFree) continue;
|
if (MemoryDescriptor->MemoryType != LoaderFree) continue;
|
||||||
|
|
||||||
// Continue, if the block is not big enough?
|
// Continue, if the block is not big enough
|
||||||
if (MemoryDescriptor->PageCount < PageLookupTablePages) continue;
|
if (MemoryDescriptor->PageCount < RequiredPages) continue;
|
||||||
|
|
||||||
// Continue, if it is not at a higher address than previous address
|
// 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
|
// 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
|
// Memory block is more suitable than the previous one
|
||||||
PageLookupTableStartPage = MemoryDescriptor->BasePage;
|
CandidateBasePage = MemoryDescriptor->BasePage;
|
||||||
PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
|
CandidatePageCount = MemoryDescriptor->PageCount;
|
||||||
(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
|
|
||||||
- PageLookupTableSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
|
||||||
|
|
||||||
return PageLookupTableMemAddress;
|
return PageLookupTableMemAddress;
|
||||||
|
|
Loading…
Reference in a new issue