[BOOTLIB]: Implement MmMdTruncateDescriptors

[BOOTLIB]: Implement MmPaTruncateMemory and call it during paging initialization to remove > 4GB memory.c
[BOOTLIB]: Implement BlpMmInitializeConstraints if those BCD options are used.

svn path=/trunk/; revision=74542
This commit is contained in:
Alex Ionescu 2017-05-14 00:39:30 +00:00
parent 920b985227
commit d4534e81e1
4 changed files with 165 additions and 10 deletions

View file

@ -2088,6 +2088,13 @@ MmMdAddDescriptorToList (
_In_ ULONG Flags _In_ ULONG Flags
); );
NTSTATUS
MmMdTruncateDescriptors (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
_In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
_In_ ULONGLONG BasePage
);
VOID VOID
MmMdRemoveDescriptorFromList ( MmMdRemoveDescriptorFromList (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
@ -2123,6 +2130,11 @@ MmMdFreeDescriptor (
/* PAGE ALLOCATOR ROUTINES ***************************************************/ /* PAGE ALLOCATOR ROUTINES ***************************************************/
NTSTATUS
MmPaTruncateMemory (
_In_ ULONGLONG BasePage
);
NTSTATUS NTSTATUS
BlMmAllocatePhysicalPages( BlMmAllocatePhysicalPages(
_Inout_ PPHYSICAL_ADDRESS Address, _Inout_ PPHYSICAL_ADDRESS Address,

View file

@ -408,6 +408,82 @@ MmMdInitByteGranularDescriptor (
return MemoryDescriptor; return MemoryDescriptor;
} }
NTSTATUS
MmMdTruncateDescriptors (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
_In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
_In_ ULONGLONG BasePage
)
{
PLIST_ENTRY ListHead, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor;
ULONGLONG FoundEndPage;
/* Search the descriptor list */
ListHead = MdList->First;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Get the current descriptor */
Descriptor = CONTAINING_RECORD(NextEntry,
BL_MEMORY_DESCRIPTOR,
ListEntry);
/* Go to the next entry in case we have to remove */
NextEntry = NextEntry->Flink;
/* Don't touch anything else but free RAM */
if (((Descriptor->Type >> BL_MEMORY_CLASS_SHIFT) == BlSystemClass) &&
(Descriptor->Type != BlConventionalMemory))
{
continue;
}
/* Check if this page is within the descriptor's region */
FoundEndPage = Descriptor->BasePage + Descriptor->PageCount;
if (BasePage > Descriptor->BasePage)
{
/* Check if it doesn't go beyond the descriptor */
if (BasePage < FoundEndPage)
{
/* Create a new descriptor to describe this region */
EfiPrintf(L"Truncating descriptor type %lx base: %llx end: %llx\r\n",
Descriptor->Type, Descriptor->BasePage, FoundEndPage);
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
Descriptor->Type,
BasePage,
0,
FoundEndPage - BasePage);
if (!NewDescriptor)
{
return STATUS_NO_MEMORY;
}
/* Cut off this descriptor to make it shorter */
Descriptor->PageCount = BasePage - Descriptor->BasePage;
/* Add the region to the new list */
MmMdAddDescriptorToList(NewList,
NewDescriptor,
BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG);
}
}
else
{
/* This whole descriptor covers the truncated area */
EfiPrintf(L"Truncating descriptor type %lx base: %llx end: %llx\r\n",
Descriptor->Type, Descriptor->BasePage, FoundEndPage);
MmMdRemoveDescriptorFromList(MdList, Descriptor);
MmMdAddDescriptorToList(NewList,
Descriptor,
BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG);
}
}
/* All good if we got here */
return STATUS_SUCCESS;
}
BOOLEAN BOOLEAN
MmMdpTruncateDescriptor ( MmMdpTruncateDescriptor (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,

View file

@ -939,10 +939,8 @@ MmDefInitializeTranslation (
Mmx86SelfMapBase.QuadPart = 0; Mmx86SelfMapBase.QuadPart = 0;
MmArchReferencePage = NULL; MmArchReferencePage = NULL;
/* Truncate all memory above 4GB so that we don't use it @TODO: FIXME */ /* Truncate all memory above 4GB so that we don't use it */
EfiPrintf(L"Warning: not truncating > 4GB memory. Don't boot with more than 4GB of RAM!\r\n"); Status = MmPaTruncateMemory(0x100000);
//Status = MmPaTruncateMemory(0x100000);
Status = STATUS_SUCCESS;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
goto Quickie; goto Quickie;

View file

@ -47,13 +47,72 @@ BL_MEMORY_DESCRIPTOR_LIST MmMdlMappingTrackers;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS
MmPaTruncateMemory (
_In_ ULONGLONG BasePage
)
{
NTSTATUS Status;
/* Increase nesting depth */
++MmDescriptorCallTreeCount;
/* Set the maximum page to the truncated request */
if (BasePage < PapMaximumPhysicalPage)
{
PapMaximumPhysicalPage = BasePage;
}
/* Truncate mapped and allocated memory */
Status = MmMdTruncateDescriptors(&MmMdlMappedAllocated,
&MmMdlTruncatedMemory,
BasePage);
if (NT_SUCCESS(Status))
{
/* Truncate unmapped and allocated memory */
Status = MmMdTruncateDescriptors(&MmMdlUnmappedAllocated,
&MmMdlTruncatedMemory,
BasePage);
if (NT_SUCCESS(Status))
{
/* Truncate mapped and unallocated memory */
Status = MmMdTruncateDescriptors(&MmMdlMappedUnallocated,
&MmMdlTruncatedMemory,
BasePage);
if (NT_SUCCESS(Status))
{
/* Truncate unmapped and unallocated memory */
Status = MmMdTruncateDescriptors(&MmMdlUnmappedUnallocated,
&MmMdlTruncatedMemory,
BasePage);
if (NT_SUCCESS(Status))
{
/* Truncate reserved memory */
Status = MmMdTruncateDescriptors(&MmMdlReservedAllocated,
&MmMdlTruncatedMemory,
BasePage);
}
}
}
}
/* Restore the nesting depth */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return Status;
}
NTSTATUS NTSTATUS
BlpMmInitializeConstraints ( BlpMmInitializeConstraints (
VOID VOID
) )
{ {
NTSTATUS Status; NTSTATUS Status, ReturnStatus;
ULONGLONG LowestAddressValid, HighestAddressValid; ULONGLONG LowestAddressValid, HighestAddressValid;
ULONGLONG LowestPage, HighestPage;
/* Assume success */
ReturnStatus = STATUS_SUCCESS;
/* Check for LOWMEM */ /* Check for LOWMEM */
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData, Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
@ -61,8 +120,15 @@ BlpMmInitializeConstraints (
&LowestAddressValid); &LowestAddressValid);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
EfiPrintf(L"/LOWMEM not supported\r\n"); /* Align the address */
return STATUS_NOT_IMPLEMENTED; LowestAddressValid = (ULONG_PTR)PAGE_ALIGN(LowestAddressValid);
LowestPage = LowestAddressValid >> PAGE_SHIFT;
/* Make sure it's below 4GB */
if (LowestPage <= 0x100000)
{
PapMinimumPhysicalPage = LowestPage;
}
} }
/* Check for MAXMEM */ /* Check for MAXMEM */
@ -71,12 +137,15 @@ BlpMmInitializeConstraints (
&HighestAddressValid); &HighestAddressValid);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
EfiPrintf(L"/MAXMEM not supported\r\n"); /* Get the page */
return STATUS_NOT_IMPLEMENTED; HighestPage = HighestAddressValid >> PAGE_SHIFT;
/* Truncate memory above this page */
ReturnStatus = MmPaTruncateMemory(HighestPage);
} }
/* Return back to the caller */ /* Return back to the caller */
return STATUS_SUCCESS; return ReturnStatus;
} }
NTSTATUS NTSTATUS