From 61c1742ba15386f488cb452d8e0594467c7e3108 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Tue, 6 Mar 2018 11:31:57 +0800 Subject: [PATCH] MdeModulePkg/NullMemoryTest: Fix bug in CompatibleRangeTest CompatibleRangeTest() contains two bugs: 1. It doesn't reject the memory above 16MB 2. it cannot handle the case when the partial or whole range of requested memory is already tested. The patch fixes the two bugs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni Reviewed-by: Michael D Kinney Reviewed-by: Liming Gao --- .../NullMemoryTestDxe/NullMemoryTest.c | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c b/MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c index c66f3fd208..a9bd101501 100644 --- a/MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c +++ b/MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c @@ -240,14 +240,51 @@ GenCompatibleRangeTest ( { EFI_STATUS Status; EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + EFI_PHYSICAL_ADDRESS CurrentBase; + UINT64 CurrentLength; - Status = gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor); - if (!EFI_ERROR (Status)) { - Status = ConvertToTestedMemory ( - Descriptor.BaseAddress, - Descriptor.Length, - Descriptor.Capabilities - ); + // + // Check if the parameter is below 16MB + // + if (StartAddress + Length > SIZE_16MB) { + return EFI_INVALID_PARAMETER; } - return Status; + CurrentBase = StartAddress; + do { + // + // Check the required memory range status; if the required memory range span + // the different GCD memory descriptor, it may be cause different action. + // + Status = gDS->GetMemorySpaceDescriptor ( + CurrentBase, + &Descriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeReserved && + (Descriptor.Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == + (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED) + ) { + CurrentLength = Descriptor.BaseAddress + Descriptor.Length - CurrentBase; + if (CurrentBase + CurrentLength > StartAddress + Length) { + CurrentLength = StartAddress + Length - CurrentBase; + } + Status = ConvertToTestedMemory ( + CurrentBase, + CurrentLength, + Descriptor.Capabilities + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + CurrentBase = Descriptor.BaseAddress + Descriptor.Length; + } while (CurrentBase < StartAddress + Length); + // + // Here means the required range already be tested, so just return success. + // + return EFI_SUCCESS; } +