mirror of
				https://gitlab.com/qemu-project/edk2.git
				synced 2025-11-03 07:59:00 +08:00 
			
		
		
		
	StandaloneMmPkg/MemLib: Check if the non-MMRAM buffer is valid
Check if the non-MMRAM buffer is inside valid non-mmram range in API MmIsBufferOutsideMmValid of StandaloneMmMemLib. Previously, the API only checks if the input buffer is overlapped with MMRAM range. Currently, in the new standalone MM infrastructure, we limit the non-MMRAM access to the ranges reported by the resource HOB. To meet the new design, in this API, we cache all the memory ranges reported by the resource HOB and check if the input buffer is inside valid non-MMRAM ranges reported by the resource HOB. Signed-off-by: Dun Tan <dun.tan@intel.com>
This commit is contained in:
		@ -59,3 +59,45 @@ MmMemLibInternalFreeMmramRanges (
 | 
			
		||||
{
 | 
			
		||||
  // Not implemented for AARCH64.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Initialize valid non-Mmram Ranges from Resource HOB.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibInitializeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  // Not implemented for AARCH64.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Deinitialize cached non-Mmram Ranges.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibFreeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  // Not implemented for AARCH64.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function check if the buffer is valid non-MMRAM memory range.
 | 
			
		||||
 | 
			
		||||
  @param[in] Buffer  The buffer start address to be checked.
 | 
			
		||||
  @param[in] Length  The buffer length to be checked.
 | 
			
		||||
 | 
			
		||||
  @retval TRUE  This buffer is valid non-MMRAM memory range.
 | 
			
		||||
  @retval FALSE This buffer is not valid non-MMRAM memory range.
 | 
			
		||||
**/
 | 
			
		||||
BOOLEAN
 | 
			
		||||
MmMemLibIsValidNonMmramRange (
 | 
			
		||||
  IN EFI_PHYSICAL_ADDRESS  Buffer,
 | 
			
		||||
  IN UINT64                Length
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,7 @@ MmIsBufferOutsideMmValid (
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
  return MmMemLibIsValidNonMmramRange (Buffer, Length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -261,6 +261,11 @@ MemLibConstructor (
 | 
			
		||||
  //
 | 
			
		||||
  MmMemLibCalculateMaximumSupportAddress ();
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Initialize valid non-Mmram Ranges from Resource HOB.
 | 
			
		||||
  //
 | 
			
		||||
  MmMemLibInitializeValidNonMmramRanges ();
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Initialize cached Mmram Ranges from HOB.
 | 
			
		||||
  //
 | 
			
		||||
@ -290,5 +295,9 @@ MemLibDestructor (
 | 
			
		||||
  //
 | 
			
		||||
  MmMemLibInternalFreeMmramRanges ();
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Deinitialize cached non-Mmram Ranges.
 | 
			
		||||
  //
 | 
			
		||||
  MmMemLibFreeValidNonMmramRanges ();
 | 
			
		||||
  return EFI_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,4 +45,37 @@ MmMemLibInternalFreeMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Initialize valid non-Mmram Ranges from Resource HOB.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibInitializeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Deinitialize cached non-Mmram Ranges.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibFreeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function check if the buffer is valid non-MMRAM memory range.
 | 
			
		||||
 | 
			
		||||
  @param[in] Buffer  The buffer start address to be checked.
 | 
			
		||||
  @param[in] Length  The buffer length to be checked.
 | 
			
		||||
 | 
			
		||||
  @retval TRUE  This buffer is valid non-MMRAM memory range.
 | 
			
		||||
  @retval FALSE This buffer is not valid non-MMRAM memory range.
 | 
			
		||||
**/
 | 
			
		||||
BOOLEAN
 | 
			
		||||
MmMemLibIsValidNonMmramRange (
 | 
			
		||||
  IN EFI_PHYSICAL_ADDRESS  Buffer,
 | 
			
		||||
  IN UINT64                Length
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,14 @@
 | 
			
		||||
 | 
			
		||||
#include <Guid/MmramMemoryReserve.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  EFI_PHYSICAL_ADDRESS    Base;
 | 
			
		||||
  UINT64                  Length;
 | 
			
		||||
} NON_MM_MEMORY_RANGE;
 | 
			
		||||
 | 
			
		||||
NON_MM_MEMORY_RANGE  *mValidNonMmramRanges;
 | 
			
		||||
UINTN                mValidNonMmramCount;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Maximum support address used to check input buffer
 | 
			
		||||
//
 | 
			
		||||
@ -135,3 +143,194 @@ MmMemLibInternalFreeMmramRanges (
 | 
			
		||||
    FreePool (mMmMemLibInternalMmramRanges);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Merge the overlapped or continuous ranges in input MemoryRange. This function is to optimize
 | 
			
		||||
  the process of checking whether a buffer range belongs to the range reported by resource HOB,
 | 
			
		||||
  since the buffer to be checked may be covered by multi resource HOB.
 | 
			
		||||
 | 
			
		||||
  @param[in, out]  MemoryRange            A pointer to the NonMmramRanges reported by resource HOB.
 | 
			
		||||
  @param[in, out]  MemoryRangeSize        A pointer to the size, in bytes, of the MemoryRange buffer.
 | 
			
		||||
                                          On input, it is the size of the current memory map.
 | 
			
		||||
                                          On output, it is the size of new memory map after merge.
 | 
			
		||||
**/
 | 
			
		||||
STATIC
 | 
			
		||||
VOID
 | 
			
		||||
MergeOverlappedOrContinuousRanges (
 | 
			
		||||
  IN OUT NON_MM_MEMORY_RANGE  *MemoryRange,
 | 
			
		||||
  IN OUT UINTN                *MemoryRangeSize
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  NON_MM_MEMORY_RANGE   *MemoryRangeEntry;
 | 
			
		||||
  NON_MM_MEMORY_RANGE   *MemoryRangeEnd;
 | 
			
		||||
  NON_MM_MEMORY_RANGE   *NewMemoryRangeEntry;
 | 
			
		||||
  NON_MM_MEMORY_RANGE   *NextMemoryRangeEntry;
 | 
			
		||||
  EFI_PHYSICAL_ADDRESS  End;
 | 
			
		||||
 | 
			
		||||
  MemoryRangeEntry    = MemoryRange;
 | 
			
		||||
  NewMemoryRangeEntry = MemoryRange;
 | 
			
		||||
  MemoryRangeEnd      = (NON_MM_MEMORY_RANGE *)((UINT8 *)MemoryRange + *MemoryRangeSize);
 | 
			
		||||
  while ((UINTN)MemoryRangeEntry < (UINTN)MemoryRangeEnd) {
 | 
			
		||||
    NextMemoryRangeEntry = MemoryRangeEntry + 1;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
      if (((UINTN)NextMemoryRangeEntry < (UINTN)MemoryRangeEnd) &&
 | 
			
		||||
          ((MemoryRangeEntry->Base + MemoryRangeEntry->Length) >= NextMemoryRangeEntry->Base))
 | 
			
		||||
      {
 | 
			
		||||
        //
 | 
			
		||||
        // Merge the overlapped or continuous ranges.
 | 
			
		||||
        //
 | 
			
		||||
        End = MAX (
 | 
			
		||||
                MemoryRangeEntry->Base + MemoryRangeEntry->Length,
 | 
			
		||||
                NextMemoryRangeEntry->Base + NextMemoryRangeEntry->Length
 | 
			
		||||
                );
 | 
			
		||||
        MemoryRangeEntry->Length = End - MemoryRangeEntry->Base;
 | 
			
		||||
 | 
			
		||||
        NextMemoryRangeEntry++;
 | 
			
		||||
        continue;
 | 
			
		||||
      } else {
 | 
			
		||||
        //
 | 
			
		||||
        // Copy the processed independent range to the new index location.
 | 
			
		||||
        //
 | 
			
		||||
        CopyMem (NewMemoryRangeEntry, MemoryRangeEntry, sizeof (NON_MM_MEMORY_RANGE));
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    } while (TRUE);
 | 
			
		||||
 | 
			
		||||
    MemoryRangeEntry = NextMemoryRangeEntry;
 | 
			
		||||
    NewMemoryRangeEntry++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *MemoryRangeSize = (UINTN)NewMemoryRangeEntry - (UINTN)MemoryRange;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Function to compare 2 NON_MM_MEMORY_RANGE pointer based on Base.
 | 
			
		||||
 | 
			
		||||
  @param[in] Buffer1            pointer to NON_MM_MEMORY_RANGE pointer to compare
 | 
			
		||||
  @param[in] Buffer2            pointer to second NON_MM_MEMORY_RANGE pointer to compare
 | 
			
		||||
 | 
			
		||||
  @retval 0                     Buffer1 equal to Buffer2
 | 
			
		||||
  @retval <0                    Buffer1 is less than Buffer2
 | 
			
		||||
  @retval >0                    Buffer1 is greater than Buffer2
 | 
			
		||||
**/
 | 
			
		||||
INTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
NonMmMapCompare (
 | 
			
		||||
  IN  CONST VOID  *Buffer1,
 | 
			
		||||
  IN  CONST VOID  *Buffer2
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base > ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
 | 
			
		||||
    return 1;
 | 
			
		||||
  } else if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base < ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Initialize valid non-Mmram Ranges from Resource HOB.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibInitializeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  EFI_PEI_HOB_POINTERS  Hob;
 | 
			
		||||
  UINTN                 Count;
 | 
			
		||||
  UINTN                 Index;
 | 
			
		||||
  UINTN                 RangeSize;
 | 
			
		||||
  NON_MM_MEMORY_RANGE   SortBuffer;
 | 
			
		||||
 | 
			
		||||
  mValidNonMmramRanges = NULL;
 | 
			
		||||
  mValidNonMmramCount  = 0;
 | 
			
		||||
 | 
			
		||||
  Count     = 0;
 | 
			
		||||
  Index     = 0;
 | 
			
		||||
  RangeSize = 0;
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // 1. Get the count.
 | 
			
		||||
  //
 | 
			
		||||
  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
 | 
			
		||||
  while (Hob.Raw != NULL) {
 | 
			
		||||
    Count++;
 | 
			
		||||
    Hob.Raw = GET_NEXT_HOB (Hob);
 | 
			
		||||
    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // 2. Store the initial data.
 | 
			
		||||
  //
 | 
			
		||||
  RangeSize            = sizeof (NON_MM_MEMORY_RANGE) * Count;
 | 
			
		||||
  mValidNonMmramRanges = (NON_MM_MEMORY_RANGE *)AllocateZeroPool (RangeSize);
 | 
			
		||||
  ASSERT (mValidNonMmramRanges != NULL);
 | 
			
		||||
 | 
			
		||||
  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
 | 
			
		||||
  while (Hob.Raw != NULL) {
 | 
			
		||||
    mValidNonMmramRanges[Index].Base   = Hob.ResourceDescriptor->PhysicalStart;
 | 
			
		||||
    mValidNonMmramRanges[Index].Length = Hob.ResourceDescriptor->ResourceLength;
 | 
			
		||||
    Index++;
 | 
			
		||||
 | 
			
		||||
    Hob.Raw = GET_NEXT_HOB (Hob);
 | 
			
		||||
    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ASSERT (Index == Count);
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // 3. Sort the data.
 | 
			
		||||
  //
 | 
			
		||||
  QuickSort (mValidNonMmramRanges, Count, sizeof (NON_MM_MEMORY_RANGE), (BASE_SORT_COMPARE)NonMmMapCompare, &SortBuffer);
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // 4. Merge the overlapped or continuous ranges.
 | 
			
		||||
  //
 | 
			
		||||
  MergeOverlappedOrContinuousRanges (mValidNonMmramRanges, &RangeSize);
 | 
			
		||||
  mValidNonMmramCount = RangeSize/sizeof (NON_MM_MEMORY_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Deinitialize cached non-Mmram Ranges.
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
VOID
 | 
			
		||||
MmMemLibFreeValidNonMmramRanges (
 | 
			
		||||
  VOID
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  if (mValidNonMmramRanges != NULL) {
 | 
			
		||||
    FreePool (mValidNonMmramRanges);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  This function check if the buffer is valid non-MMRAM memory range.
 | 
			
		||||
 | 
			
		||||
  @param[in] Buffer  The buffer start address to be checked.
 | 
			
		||||
  @param[in] Length  The buffer length to be checked.
 | 
			
		||||
 | 
			
		||||
  @retval TRUE  This buffer is valid non-MMRAM memory range.
 | 
			
		||||
  @retval FALSE This buffer is not valid non-MMRAM memory range.
 | 
			
		||||
**/
 | 
			
		||||
BOOLEAN
 | 
			
		||||
MmMemLibIsValidNonMmramRange (
 | 
			
		||||
  IN EFI_PHYSICAL_ADDRESS  Buffer,
 | 
			
		||||
  IN UINT64                Length
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  UINTN  Index;
 | 
			
		||||
 | 
			
		||||
  for (Index = 0; Index < mValidNonMmramCount; Index++) {
 | 
			
		||||
    if ((Buffer >= mValidNonMmramRanges[Index].Base) &&
 | 
			
		||||
        (Buffer + Length <= mValidNonMmramRanges[Index].Base + mValidNonMmramRanges[Index].Length))
 | 
			
		||||
    {
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user