Author: ion
Date: Sun May 14 00:11:48 2017
New Revision: 74541
URL: http://svn.reactos.org/svn/reactos?rev=74541&view=rev
Log:
[BOOTLIB]: Complete implementation of MmMdRemoveRegionFromMdlEx
Modified:
trunk/reactos/boot/environ/lib/mm/descriptor.c
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descri…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun May 14 00:11:48 2017
@@ -390,6 +390,7 @@
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount)
{
EfiPrintf(L"Out of descriptors!\r\n");
+ EfiStall(1000000);
return NULL;
}
@@ -409,9 +410,9 @@
BOOLEAN
MmMdpTruncateDescriptor (
- __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
- __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
- __in ULONG Flags
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
+ _In_ ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
@@ -435,12 +436,14 @@
if ((PreviousEntry != MdList->First) && (MemoryDescriptor->BasePage < PreviousEndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
+ EfiStall(1000000);
}
/* Check for forward overlap */
if ((NextEntry != MdList->First) && (NextDescriptor->BasePage < EndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
+ EfiStall(1000000);
}
/* Nothing to do */
@@ -449,9 +452,9 @@
BOOLEAN
MmMdpCoalesceDescriptor (
- __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
- __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
- __in ULONG Flags
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
+ _In_ ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
@@ -623,28 +626,25 @@
BOOLEAN HaveNewList, UseVirtualPage;
NTSTATUS Status;
PLIST_ENTRY ListHead, NextEntry;
- PBL_MEMORY_DESCRIPTOR Descriptor;
- //BL_MEMORY_DESCRIPTOR NewDescriptor;
+ PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor, ListDescriptor;
+ BL_MEMORY_DESCRIPTOR OldDescriptor;
ULONGLONG RegionSize;
- ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
+ ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage, VirtualPage;
/* Set initial status */
Status = STATUS_SUCCESS;
+ ListDescriptor = NULL;
+ NewDescriptor = NULL;
+ HaveNewList = FALSE;
/* Check if removed descriptors should go into a new list */
if (NewMdList != NULL)
{
/* Initialize it */
- MmMdInitializeListHead(NewMdList);
- NewMdList->Type = MdList->Type;
+ MmMdInitializeList(NewMdList, MdList->Type, NULL);
/* Remember for later */
HaveNewList = TRUE;
- }
- else
- {
- /* For later */
- HaveNewList = FALSE;
}
/* Is the region being removed physical? */
@@ -684,7 +684,7 @@
EndPage = PageCount + BasePage;
/* Make a copy of the original descriptor */
- //NewDescriptor = *Descriptor; // FIXME: Need to use this somewhere...
+ OldDescriptor = *Descriptor;
/* Check if the region to be removed starts after the found region starts */
if ((BasePage > FoundBasePage) || (FoundBasePage >= EndPage))
@@ -695,13 +695,14 @@
/* Check if the found region starts after the region or ends before the region */
if ((FoundBasePage >= BasePage) || (EndPage >= FoundEndPage))
{
- /* This descriptor doesn't cover any part of the range -- nothing to do */
- NOTHING;
+ /* This is a fully-mapped descriptor -- change nothing */
+ OldDescriptor.PageCount = 0;
}
else
{
/* This descriptor fully covers the entire allocation */
FoundBasePage = Descriptor->BasePage;
+ VirtualPage = Descriptor->VirtualPage;
FoundPageCount = BasePage - FoundBasePage;
/* This is how many pages we will eat away from the descriptor */
@@ -710,29 +711,40 @@
/* Update the descriptor to account for the consumed pages */
Descriptor->BasePage += RegionSize;
Descriptor->PageCount -= RegionSize;
- if (Descriptor->VirtualPage)
+ if (VirtualPage)
{
Descriptor->VirtualPage += RegionSize;
}
/* Initialize a descriptor for the start of the region */
- Descriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
- Descriptor->Type,
- FoundBasePage,
- Descriptor->VirtualPage,
- FoundPageCount);
- if (!Descriptor)
+ NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
+ Descriptor->Type,
+ FoundBasePage,
+ VirtualPage,
+ FoundPageCount);
+ if (!NewDescriptor)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Add it into the list */
- Status = MmMdAddDescriptorToList(MdList, Descriptor, Flags);
+ Status = MmMdAddDescriptorToList(MdList, NewDescriptor, Flags);
if (!NT_SUCCESS(Status))
{
Status = STATUS_NO_MEMORY;
goto Quickie;
+ }
+
+ /* Don't free it on exit path */
+ NewDescriptor = NULL;
+
+ /* Adjust the leftover descriptor */
+ OldDescriptor.BasePage += FoundPageCount;
+ OldDescriptor.PageCount = PageCount;
+ if (OldDescriptor.VirtualPage)
+ {
+ OldDescriptor.VirtualPage += FoundPageCount;
}
}
}
@@ -741,9 +753,17 @@
/* This descriptor contains the entire allocation */
RegionSize = FoundEndPage - BasePage;
Descriptor->PageCount -= RegionSize;
+
+ /* Adjust the leftover descriptor */
+ OldDescriptor.BasePage += Descriptor->PageCount;
+ OldDescriptor.PageCount = RegionSize;
+ if (OldDescriptor.VirtualPage)
+ {
+ OldDescriptor.VirtualPage += FoundPageCount;
+ }
}
- /* Keep going */
+ /* Go to the next entry */
NextEntry = NextEntry->Flink;
}
else
@@ -764,14 +784,14 @@
}
/* This is how many pages we will eat away from the descriptor */
- RegionSize = FoundEndPage - FoundBasePage;
+ FoundPageCount = FoundEndPage - FoundBasePage;
/* Update the descriptor to account for the consumed pages */
- Descriptor->BasePage += RegionSize;
- Descriptor->PageCount -= RegionSize;
+ Descriptor->BasePage += FoundPageCount;
+ Descriptor->PageCount -= FoundPageCount;
if (Descriptor->VirtualPage)
{
- Descriptor->VirtualPage += RegionSize;
+ Descriptor->VirtualPage += FoundPageCount;
}
/* Go to the next entry */
@@ -782,15 +802,53 @@
{
/* Remove it */
MmMdRemoveDescriptorFromList(MdList, Descriptor);
- MmMdFreeDescriptor(Descriptor);
/* Check if we're supposed to insert it into a new list */
if (HaveNewList)
{
- EfiPrintf(L"Not yet implemented\r\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ /* This is the one to add */
+ ListDescriptor = Descriptor;
+ }
+ else
+ {
+ /* Nope -- just get rid of it */
+ MmMdFreeDescriptor(Descriptor);
+ }
+ }
+ }
+
+ /* Is there a remainder descriptor, and do we have a list for it */
+ if ((OldDescriptor.PageCount) && (HaveNewList))
+ {
+ /* Did we already chop off the descriptor? */
+ if (ListDescriptor)
+ {
+ /* Use what we previously chopped */
+ *ListDescriptor = OldDescriptor;
+ }
+ else
+ {
+ /* First time, so build a descriptor to describe the leftover */
+ ListDescriptor = MmMdInitByteGranularDescriptor(OldDescriptor.Flags,
+ OldDescriptor.Type,
+ OldDescriptor.BasePage,
+ OldDescriptor.VirtualPage,
+ OldDescriptor.PageCount);
+ if (!ListDescriptor)
+ {
+ Status = STATUS_NO_MEMORY;
goto Quickie;
}
+
+ /* Add it into the list */
+ Status = MmMdAddDescriptorToList(NewMdList, ListDescriptor, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Don't free on exit path */
+ ListDescriptor = NULL;
}
}
}
@@ -804,11 +862,23 @@
{
/* Free and re-initialize it */
MmMdFreeList(NewMdList);
- MmMdInitializeListHead(NewMdList);
- NewMdList->Type = MdList->Type;
- }
- }
-
+ MmMdInitializeList(NewMdList, MdList->Type, NULL);
+ }
+
+ /* Check if we had a list descriptor, and free it */
+ if (ListDescriptor)
+ {
+ MmMdFreeDescriptor(ListDescriptor);
+ }
+
+ /* Check if we had a new descriptor, and free it */
+ if (NewDescriptor)
+ {
+ MmMdFreeDescriptor(NewDescriptor);
+ }
+ }
+
+ /* All done */
return Status;
}
Author: tkreuzer
Date: Sat May 13 20:07:39 2017
New Revision: 74539
URL: http://svn.reactos.org/svn/reactos?rev=74539&view=rev
Log:
[NTOSKRNL] Improve S-List-Fault detection in KiTrap0EHandler to handle usermode faults as well.
Modified:
trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Sat May 13 20:07:39 2017
@@ -15,6 +15,8 @@
VOID __cdecl KiFastCallEntry(VOID);
VOID __cdecl KiFastCallEntryWithSingleStep(VOID);
+extern PVOID KeUserPopEntrySListFault;
+extern PVOID KeUserPopEntrySListResume;
extern PVOID FrRestore;
VOID FASTCALL Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea);
@@ -1240,10 +1242,46 @@
TrapFrame);
}
- /* Check for S-LIST fault in kernel mode */
- if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
- {
- PSLIST_HEADER SListHeader;
+ /* Check for S-List fault
+
+ Explanation: An S-List fault can occur due to a race condition between 2
+ threads simultaneously trying to pop an element from the S-List. After
+ thread 1 has read the pointer to the top element on the S-List it is
+ preempted and thread 2 calls InterlockedPopEntrySlist on the same S-List,
+ removing the top element and freeing it's memory. After that thread 1
+ resumes and tries to read the address of the Next pointer from the top
+ element, which it assumes will be the next top element.
+ But since that memory has been freed, we get a page fault. To handle this
+ race condition, we let thread 1 repeat the operation.
+ We do NOT invoke the page fault handler in this case, since we do not
+ want to trigger any side effects, like paging or a guard page fault.
+
+ Sequence of operations:
+
+ Thread 1 : mov eax, [ebp] <= eax now points to the first element
+ Thread 1 : mov edx, [ebp + 4] <= edx is loaded with Depth and Sequence
+ *** preempted ***
+ Thread 2 : calls InterlockedPopEntrySlist, changing the top element
+ Thread 2 : frees the memory of the element that was popped
+ *** preempted ***
+ Thread 1 : checks if eax is NULL
+ Thread 1 : InterlockedPopEntrySListFault: mov ebx, [eax] <= faults
+
+ To be sure that we are dealing with exactly the case described above, we
+ check whether the ListHeader has changed. If Thread 2 only popped one
+ entry, the Next field in the S-List-header has changed.
+ If after thread 1 has faulted, thread 2 allocates a new element, by
+ chance getting the same address as the previously freed element and
+ pushes it on the list again, we will see the same top element, but the
+ Sequence member of the S-List header has changed. Therefore we check
+ both fields to make sure we catch any concurrent modification of the
+ S-List-header.
+ */
+ if ((TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault) ||
+ (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault))
+ {
+ ULARGE_INTEGER SListHeader;
+ PVOID ResumeAddress;
/* Sanity check that the assembly is correct:
This must be mov ebx, [eax]
@@ -1255,30 +1293,50 @@
(((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
(((UCHAR*)TrapFrame->Eip)[5] == 0x00));
- /* Get the pointer to the SLIST_HEADER */
- SListHeader = (PSLIST_HEADER)TrapFrame->Ebp;
-
- /* Check if the Next member of the SLIST_HEADER was changed */
- if (SListHeader->Next.Next != (PSLIST_ENTRY)TrapFrame->Eax)
- {
+ /* Check if this is a user fault */
+ if (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault)
+ {
+ /* EBP points to the S-List-header. Copy it inside SEH, to protect
+ against a bogus pointer from user mode */
+ _SEH2_TRY
+ {
+ ProbeForRead((PVOID)TrapFrame->Ebp,
+ sizeof(ULARGE_INTEGER),
+ TYPE_ALIGNMENT(SLIST_HEADER));
+ SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* The S-List pointer is not valid! */
+ goto NotSListFault;
+ }
+ _SEH2_END;
+ ResumeAddress = KeUserPopEntrySListResume;
+ }
+ else
+ {
+ SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
+ ResumeAddress = ExpInterlockedPopEntrySListResume;
+ }
+
+ /* Check if either the Next pointer or the Sequence member in the
+ S-List-header has changed. If any of these has changed, we restart
+ the operation. Otherwise we only have a bogus pointer and let the
+ page fault handler deal with it. */
+ if ((SListHeader.LowPart != TrapFrame->Eax) ||
+ (SListHeader.HighPart != TrapFrame->Edx))
+ {
+ DPRINT1("*** Got an S-List-Fault ***\n");
+ KeGetCurrentThread()->SListFaultCount++;
+
/* Restart the operation */
- TrapFrame->Eip = (ULONG_PTR)ExpInterlockedPopEntrySListResume;
+ TrapFrame->Eip = (ULONG_PTR)ResumeAddress;
/* Continue execution */
KiEoiHelper(TrapFrame);
}
- else
- {
-#if 0
- /* Do what windows does and issue an invalid access violation */
- KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
- TrapFrame->Eip,
- StoreInstruction,
- Cr2,
- TrapFrame);
-#endif
- }
- }
+ }
+NotSListFault:
/* Call the access fault handler */
Status = MmAccessFault(Present,
Author: ion
Date: Sat May 13 19:32:26 2017
New Revision: 74536
URL: http://svn.reactos.org/svn/reactos?rev=74536&view=rev
Log:
[BOOTLIB]: Separate free and zero memory, and code vs data runtime data, as newer bootlibs do.
[BOOTLIB]: Fix bugs in MmMdpHasPrecedence and cleanup.
[BOOTLIB]: Fix bug in MmMdFreeDescriptor.
[BOOTLIB]: Cleanup MmMdpSaveCurrentListPointer.
[BOOTLIB]: Fix bug in MmMdpCoalesceDescriptor.
[BOOTLIB]: Fix multiple bugs in MmMdAddDescriptorToList, and cleanup.
Modified:
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
trunk/reactos/boot/environ/lib/mm/descriptor.c
trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
Modified: trunk/reactos/boot/environ/include/bl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sat May 13 19:32:26 2017
@@ -329,12 +329,14 @@
BlUnusableMemory = 0xF0000002,
BlReservedMemory = 0xF0000003,
BlEfiBootMemory = 0xF0000004,
- BlEfiRuntimeMemory = 0xF0000006,
+ BlConventionalZeroedMemory = 0xF000005,
+ BlEfiRuntimeCodeMemory = 0xF0000006,
BlAcpiReclaimMemory = 0xF0000008,
BlAcpiNvsMemory = 0xF0000009,
BlDeviceIoMemory = 0xF000000A,
BlDevicePortMemory = 0xF000000B,
BlPalMemory = 0xF000000C,
+ BlEfiRuntimeDataMemory = 0xF000000E,
} BL_MEMORY_TYPE;
typedef enum _BL_MEMORY_ATTR
Modified: trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/…
==============================================================================
--- trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] Sat May 13 19:32:26 2017
@@ -1343,8 +1343,11 @@
break;
case EfiRuntimeServicesCode:
+ OsType = BlEfiRuntimeCodeMemory;
+ break;
+
case EfiRuntimeServicesData:
- OsType = BlEfiRuntimeMemory;
+ OsType = BlEfiRuntimeDataMemory;
break;
case EfiConventionalMemory:
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descri…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sat May 13 19:32:26 2017
@@ -26,13 +26,38 @@
BlDeviceIoMemory,
BlDevicePortMemory,
BlPalMemory,
- BlEfiRuntimeMemory,
+ BlEfiRuntimeCodeMemory,
+ BlEfiRuntimeDataMemory,
BlAcpiNvsMemory,
BlAcpiReclaimMemory,
- BlEfiBootMemory
+ BlEfiBootMemory,
+ BlConventionalMemory,
+ BlConventionalZeroedMemory
};
/* FUNCTIONS *****************************************************************/
+
+LONG
+MmMdpLookupTypePrecedenceIndex (
+ _In_ BL_MEMORY_TYPE Type
+ )
+{
+ ULONG i;
+
+ /* Check the precedence array */
+ for (i = 0; i < RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence); i++)
+ {
+ /* Check for a match */
+ if (MmPlatformMemoryTypePrecedence[i] == Type)
+ {
+ /* Return the index */
+ return i;
+ }
+ }
+
+ /* Invalid index type */
+ return -1;
+}
/* The order is Conventional > Other > System > Loader > Application */
BOOLEAN
@@ -44,14 +69,14 @@
BL_MEMORY_CLASS Class1, Class2;
ULONG i, j;
+ /* It isn't free RAM, but the comparator is -- it succeeds it */
+ if (Type2 == BlConventionalMemory)
+ {
+ return TRUE;
+ }
+
/* Descriptor is free RAM -- it precedes */
if (Type1 == BlConventionalMemory)
- {
- return TRUE;
- }
-
- /* It isn't free RAM, but the comparator is -- it succeeds it */
- if (Type2 == BlConventionalMemory)
{
return FALSE;
}
@@ -77,55 +102,30 @@
/* Descriptor is system class */
if (Class1 == BlSystemClass)
{
- /* And so is the other guy... */
- if (Class2 == BlSystemClass)
- {
- i = 0;
- j = 0;
-
- /* Scan for the descriptor's system precedence index */
- do
- {
- if (MmPlatformMemoryTypePrecedence[j] == Type1)
- {
- break;
- }
- } while (++j < RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence));
-
- /* Use an invalid index if one wasn't found */
- if (j == RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence))
- {
- j = 0xFFFFFFFF;
- }
-
- /* Now scan for the comparator's system precedence index */
- while (MmPlatformMemoryTypePrecedence[i] != Type2)
- {
- /* Use an invalid index if one wasn't found */
- if (++i >= RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence))
- {
- i = 0xFFFFFFFF;
- break;
- }
- }
-
- /* Does the current have a valid index? */
- if (j != 0xFFFFFFFF)
- {
- /* Yes, what about the comparator? */
- if (i != 0xFFFFFFFF)
- {
- /* Let the indexes fight! */
- return i >= j;
- }
-
- /* Succeed the comparator, its index is unknown */
- return FALSE;
- }
- }
-
- /* The comparator isn't system, so it precedes it */
- return TRUE;
+ /* If the other guy isn't, system wins */
+ if (Class2 != BlSystemClass)
+ {
+ return TRUE;
+ }
+
+ /* Scan for the descriptor's system precedence index */
+ i = MmMdpLookupTypePrecedenceIndex(Type1);
+ j = MmMdpLookupTypePrecedenceIndex(Type2);
+
+ /* Does the current have a valid index? */
+ if (i == 0xFFFFFFFF)
+ {
+ return TRUE;
+ }
+
+ /* Yes, what about the comparator? */
+ if (j == 0xFFFFFFFF)
+ {
+ return FALSE;
+ }
+
+ /* Let the indexes fight! */
+ return i <= j;
}
/* Descriptor is not system class, but comparator is -- it succeeds it */
@@ -134,7 +134,7 @@
return FALSE;
}
- /* Descriptor is loader class -- it precedes */
+ /* Descriptor is loader class -- it preceedes */
if (Class1 == BlLoaderClass)
{
return TRUE;
@@ -163,8 +163,9 @@
/* Check if this is a valid static descriptor */
if (((MmDynamicMemoryDescriptors) &&
(MemoryDescriptor >= MmDynamicMemoryDescriptors) &&
- (MemoryDescriptor < (MmDynamicMemoryDescriptors + MmDynamicMemoryDescriptorCount))) ||
- ((MemoryDescriptor >= MmStaticMemoryDescriptors) && (MemoryDescriptor < &MmStaticMemoryDescriptors[511])))
+ (MemoryDescriptor < &MmDynamicMemoryDescriptors[MmDynamicMemoryDescriptorCount])) ||
+ ((MemoryDescriptor >= MmStaticMemoryDescriptors) &&
+ (MemoryDescriptor < &MmStaticMemoryDescriptors[RTL_NUMBER_OF(MmStaticMemoryDescriptors)])))
{
/* It's a global/static descriptor, so just zero it */
RtlZeroMemory(MemoryDescriptor, sizeof(BL_MEMORY_DESCRIPTOR));
@@ -188,9 +189,13 @@
_In_ PLIST_ENTRY Current
)
{
+ PBL_MEMORY_DESCRIPTOR FirstEntry, LastEntry;
+
/* Make sure that this is not a global descriptor and not the first one */
- if (((Current < &MmGlobalMemoryDescriptors->ListEntry) ||
- (Current >= &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorCount].ListEntry)) &&
+ FirstEntry = &MmGlobalMemoryDescriptors[0];
+ LastEntry = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorCount];
+ if ((((ULONG_PTR)Current < (ULONG_PTR)FirstEntry) ||
+ ((ULONG_PTR)Current >= (ULONG_PTR)LastEntry)) &&
(Current != MdList->First))
{
/* Save this as the current pointer */
@@ -390,7 +395,7 @@
/* Take one of the available descriptors and fill it out */
MemoryDescriptor = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorsUsed];
- MemoryDescriptor->BaseAddress = BasePage;
+ MemoryDescriptor->BasePage = BasePage;
MemoryDescriptor->VirtualPage = VirtualPage;
MemoryDescriptor->PageCount = PageCount;
MemoryDescriptor->Flags = Flags;
@@ -485,9 +490,9 @@
(NextDescriptor->Type == MemoryDescriptor->Type) &&
((NextDescriptor->Flags ^ MemoryDescriptor->Flags) & 0x1B19FFFF) &&
(EndPage == NextDescriptor->BasePage) &&
- ((!(MemoryDescriptor->VirtualPage) && !(PreviousDescriptor->VirtualPage)) ||
- ((MemoryDescriptor->VirtualPage) && (PreviousDescriptor->VirtualPage) &&
- (MappedEndPage == NextDescriptor->VirtualPage))))
+ ((!(MemoryDescriptor->VirtualPage) && !(NextDescriptor->VirtualPage)) ||
+ ((MemoryDescriptor->VirtualPage) && (NextDescriptor->VirtualPage) &&
+ (MappedEndPage == NextDescriptor->VirtualPage))))
{
EfiPrintf(L"Next descriptor coalescable!\r\n");
}
@@ -516,15 +521,12 @@
if (Flags & BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG)
{
/* Then we won't be coalescing */
- Flags &= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
- }
- else
+ Flags &= ~BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
+ }
+ else if (MemoryDescriptor->Flags & BlMemoryCoalesced)
{
/* Coalesce if the descriptor requires it */
- if (MemoryDescriptor->Flags & BlMemoryCoalesced)
- {
- Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
- }
+ Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
}
/* Check if truncation is forcefully disabled */
@@ -548,82 +550,81 @@
/* Check if there's no current pointer, or if it's higher than the new one */
if (!(ThisEntry) ||
- (MemoryDescriptor->BaseAddress <= ThisDescriptor->BaseAddress))
+ (MemoryDescriptor->BasePage <= ThisDescriptor->BasePage))
{
/* Start at the first descriptor instead, since current is past us */
ThisEntry = FirstEntry->Flink;
+ }
+
+ /* Loop until we find the right location to insert */
+ while (ThisEntry != FirstEntry)
+ {
+ /* Get the descriptor part of this entry */
ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
- }
-
- /* Loop until we find the right location to insert */
- while (1)
- {
- /* Have we gotten back to the first entry? */
- if (ThisEntry == FirstEntry)
- {
- /* Then we didn't find a good match, so insert it right here */
- InsertTailList(FirstEntry, &MemoryDescriptor->ListEntry);
-
- /* Do we have to truncate? */
- if (Flags & BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG)
- {
- /* Do it and then exit */
- if (MmMdpTruncateDescriptor(MdList, MemoryDescriptor, Flags))
- {
- return STATUS_SUCCESS;
- }
- }
-
- /* Do we have to coalesce? */
- if (Flags & BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG)
- {
- /* Do it and then exit */
- if (MmMdpCoalesceDescriptor(MdList, MemoryDescriptor, Flags))
- {
- return STATUS_SUCCESS;
- }
- }
-
- /* Do we have to update the current pointer? */
- if (Flags & BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG)
- {
- /* Do it */
- MmMdpSaveCurrentListPointer(MdList, &MemoryDescriptor->ListEntry);
- }
-
- /* We're done */
- return STATUS_SUCCESS;
- }
-
- /* Is the new descriptor below this address, and has precedence over it? */
- if ((MemoryDescriptor->BaseAddress < ThisDescriptor->BaseAddress) &&
- (MmMdpHasPrecedence(MemoryDescriptor->Type, ThisDescriptor->Type)))
+
+ /* Is the address smaller, or equal but more important? */
+ if ((MemoryDescriptor->BasePage < ThisDescriptor->BasePage) ||
+ ((MemoryDescriptor->BasePage == ThisDescriptor->BasePage) &&
+ (MmMdpHasPrecedence(MemoryDescriptor->Type, ThisDescriptor->Type))))
{
/* Then insert right here */
InsertTailList(ThisEntry, &MemoryDescriptor->ListEntry);
+ goto Quickie;
+ }
+
+ /* Try the next entry */
+ ThisEntry = ThisEntry->Flink;
+ }
+
+ /* Then we didn't find a good match, so insert it right here */
+ InsertTailList(FirstEntry, &MemoryDescriptor->ListEntry);
+
+Quickie:
+ /* Do we have to truncate? */
+ if (Flags & BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG)
+ {
+ /* Do it and then exit */
+ if (MmMdpTruncateDescriptor(MdList, MemoryDescriptor, Flags))
+ {
return STATUS_SUCCESS;
}
-
- /* Try the next descriptor */
- ThisEntry = ThisEntry->Flink;
- ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
- }
+ }
+
+ /* Do we have to coalesce? */
+ if (Flags & BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG)
+ {
+ /* Do it and then exit */
+ if (MmMdpCoalesceDescriptor(MdList, MemoryDescriptor, Flags))
+ {
+ return STATUS_SUCCESS;
+ }
+ }
+
+ /* Do we have to update the current pointer? */
+ if (Flags & BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG)
+ {
+ /* Do it */
+ MmMdpSaveCurrentListPointer(MdList, &MemoryDescriptor->ListEntry);
+ }
+
+ /* We're done */
+ return STATUS_SUCCESS;
}
NTSTATUS
MmMdRemoveRegionFromMdlEx (
- __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
- __in ULONG Flags,
- __in ULONGLONG BasePage,
- __in ULONGLONG PageCount,
- __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ ULONG Flags,
+ _In_ ULONGLONG BasePage,
+ _In_ ULONGLONG PageCount,
+ _Out_opt_ PBL_MEMORY_DESCRIPTOR_LIST NewMdList
)
{
BOOLEAN HaveNewList, UseVirtualPage;
NTSTATUS Status;
PLIST_ENTRY ListHead, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor;
- BL_MEMORY_DESCRIPTOR NewDescriptor;
+ //BL_MEMORY_DESCRIPTOR NewDescriptor;
ULONGLONG RegionSize;
ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
@@ -683,7 +684,7 @@
EndPage = PageCount + BasePage;
/* Make a copy of the original descriptor */
- RtlCopyMemory(&NewDescriptor, NextEntry, sizeof(NewDescriptor));
+ //NewDescriptor = *Descriptor; // FIXME: Need to use this somewhere...
/* Check if the region to be removed starts after the found region starts */
if ((BasePage > FoundBasePage) || (FoundBasePage >= EndPage))
Modified: trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/i386/m…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] Sat May 13 19:32:26 2017
@@ -790,7 +790,8 @@
/* Check if this is a UEFI-related descriptor, unless it's the self-map page */
Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
if (((Descriptor->Type == BlEfiBootMemory) ||
- (Descriptor->Type == BlEfiRuntimeMemory) ||
+ (Descriptor->Type == BlEfiRuntimeCodeMemory) ||
+ (Descriptor->Type == BlEfiRuntimeDataMemory) || // WINBUG?
(Descriptor->Type == BlLoaderMemory)) &&
((Descriptor->BasePage << PAGE_SHIFT) != Mmx86SelfMapBase.QuadPart))
{