mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			172 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  System Management System Table Services SmmInstallConfigurationTable service
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "PiSmmCore.h"
 | 
						|
 | 
						|
#define CONFIG_TABLE_SIZE_INCREASED 0x10
 | 
						|
 | 
						|
UINTN  mSmmSystemTableAllocateSize = 0;
 | 
						|
 | 
						|
/**
 | 
						|
  The SmmInstallConfigurationTable() function is used to maintain the list
 | 
						|
  of configuration tables that are stored in the System Management System
 | 
						|
  Table.  The list is stored as an array of (GUID, Pointer) pairs.  The list
 | 
						|
  must be allocated from pool memory with PoolType set to EfiRuntimeServicesData.
 | 
						|
 | 
						|
  @param  SystemTable      A pointer to the SMM System Table (SMST).
 | 
						|
  @param  Guid             A pointer to the GUID for the entry to add, update, or remove.
 | 
						|
  @param  Table            A pointer to the buffer of the table to add.
 | 
						|
  @param  TableSize        The size of the table to install.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.
 | 
						|
  @retval EFI_INVALID_PARAMETER Guid is not valid.
 | 
						|
  @retval EFI_NOT_FOUND         An attempt was made to delete a non-existent entry.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available to complete the operation.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SmmInstallConfigurationTable (
 | 
						|
  IN  CONST EFI_SMM_SYSTEM_TABLE2  *SystemTable,
 | 
						|
  IN  CONST EFI_GUID               *Guid,
 | 
						|
  IN  VOID                         *Table,
 | 
						|
  IN  UINTN                        TableSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                    Index;
 | 
						|
  EFI_CONFIGURATION_TABLE  *ConfigurationTable;
 | 
						|
  EFI_CONFIGURATION_TABLE  *OldTable;
 | 
						|
 | 
						|
  //
 | 
						|
  // If Guid is NULL, then this operation cannot be performed
 | 
						|
  //
 | 
						|
  if (Guid == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ConfigurationTable = gSmmCoreSmst.SmmConfigurationTable;
 | 
						|
 | 
						|
  //
 | 
						|
  // Search all the table for an entry that matches Guid
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < gSmmCoreSmst.NumberOfTableEntries; Index++) {
 | 
						|
    if (CompareGuid (Guid, &(ConfigurationTable[Index].VendorGuid))) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Index < gSmmCoreSmst.NumberOfTableEntries) {
 | 
						|
    //
 | 
						|
    // A match was found, so this is either a modify or a delete operation
 | 
						|
    //
 | 
						|
    if (Table != NULL) {
 | 
						|
      //
 | 
						|
      // If Table is not NULL, then this is a modify operation.
 | 
						|
      // Modify the table entry and return.
 | 
						|
      //
 | 
						|
      ConfigurationTable[Index].VendorTable = Table;
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // A match was found and Table is NULL, so this is a delete operation.
 | 
						|
    //
 | 
						|
    gSmmCoreSmst.NumberOfTableEntries--;
 | 
						|
 | 
						|
    //
 | 
						|
    // Copy over deleted entry
 | 
						|
    //
 | 
						|
    CopyMem (
 | 
						|
      &(ConfigurationTable[Index]),
 | 
						|
      &(ConfigurationTable[Index + 1]),
 | 
						|
      (gSmmCoreSmst.NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
 | 
						|
      );
 | 
						|
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // No matching GUIDs were found, so this is an add operation.
 | 
						|
    //
 | 
						|
    if (Table == NULL) {
 | 
						|
      //
 | 
						|
      // If Table is NULL on an add operation, then return an error.
 | 
						|
      //
 | 
						|
      return EFI_NOT_FOUND;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Assume that Index == gSmmCoreSmst.NumberOfTableEntries
 | 
						|
    //
 | 
						|
    if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSmmSystemTableAllocateSize) {
 | 
						|
      //
 | 
						|
      // Allocate a table with one additional entry.
 | 
						|
      //
 | 
						|
      mSmmSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
 | 
						|
      ConfigurationTable = AllocatePool (mSmmSystemTableAllocateSize);
 | 
						|
      if (ConfigurationTable == NULL) {
 | 
						|
        //
 | 
						|
        // If a new table could not be allocated, then return an error.
 | 
						|
        //
 | 
						|
        return EFI_OUT_OF_RESOURCES;
 | 
						|
      }
 | 
						|
 | 
						|
      if (gSmmCoreSmst.SmmConfigurationTable != NULL) {
 | 
						|
        //
 | 
						|
        // Copy the old table to the new table.
 | 
						|
        //
 | 
						|
        CopyMem (
 | 
						|
          ConfigurationTable,
 | 
						|
          gSmmCoreSmst.SmmConfigurationTable,
 | 
						|
          Index * sizeof (EFI_CONFIGURATION_TABLE)
 | 
						|
          );
 | 
						|
 | 
						|
        //
 | 
						|
        // Record the old table pointer.
 | 
						|
        //
 | 
						|
        OldTable = gSmmCoreSmst.SmmConfigurationTable;
 | 
						|
 | 
						|
        //
 | 
						|
        // As the SmmInstallConfigurationTable() may be re-entered by FreePool() in
 | 
						|
        // its calling stack, updating System table to the new table pointer must
 | 
						|
        // be done before calling FreePool() to free the old table.
 | 
						|
        // It can make sure the gSmmCoreSmst.SmmConfigurationTable point to the new
 | 
						|
        // table and avoid the errors of use-after-free to the old table by the
 | 
						|
        // reenter of SmmInstallConfigurationTable() in FreePool()'s calling stack.
 | 
						|
        //
 | 
						|
        gSmmCoreSmst.SmmConfigurationTable = ConfigurationTable;
 | 
						|
 | 
						|
        //
 | 
						|
        // Free the old table after updating System Table to the new table pointer.
 | 
						|
        //
 | 
						|
        FreePool (OldTable);
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // Update System Table
 | 
						|
        //
 | 
						|
        gSmmCoreSmst.SmmConfigurationTable = ConfigurationTable;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Fill in the new entry
 | 
						|
    //
 | 
						|
    CopyGuid ((VOID *)&ConfigurationTable[Index].VendorGuid, Guid);
 | 
						|
    ConfigurationTable[Index].VendorTable = Table;
 | 
						|
 | 
						|
    //
 | 
						|
    // This is an add operation, so increment the number of table entries
 | 
						|
    //
 | 
						|
    gSmmCoreSmst.NumberOfTableEntries++;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // CRC-32 field is ignorable for SMM System Table and should be set to zero
 | 
						|
  //
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |