Skip to content

Commit

Permalink
Make the MemRegionMgr class target aware
Browse files Browse the repository at this point in the history
Creates a map of target,region map lists to allow the opening of
the same regions against different targets

Change-Id: Ieb2235765da99b25c018a5e9546ac2f8ca252a39
CQ:SW412793
Backport:release-fips910
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/51923
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Stephen Cprek authored and dcrowell77 committed Jan 17, 2018
1 parent d1c5692 commit 329b814
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 48 deletions.
161 changes: 119 additions & 42 deletions src/usr/sbeio/sbe_memRegionMgr.C
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2017 */
/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -37,6 +37,7 @@
#include <vmmconst.h>
#include <sys/misc.h>
#include <secureboot/service.H>
#include <initservice/initserviceif.H>

#include "sbe_memRegionMgr.H"

Expand Down Expand Up @@ -90,21 +91,59 @@ errlHndl_t closeAllUnsecureMemRegions()
/*
* MemRegionMgr : Constructor : Setup Instance Variables
*/
MemRegionMgr::MemRegionMgr()
MemRegionMgr::MemRegionMgr(): iv_memRegionMap{}, iv_masterProc(nullptr)
{
SBE_TRACD(ENTER_MRK"MemRegionMgr Constructor");

errlHndl_t l_errl = nullptr;

do {
// SBE opens Memory Region for HB DUMP before starting hostboot
// so just add it directly to iv_memRegions
// so just add it directly to master proc's memory regions
regionData hb_dump_region;
hb_dump_region.start_addr = cpu_spr_value(CPU_SPR_HRMOR);
hb_dump_region.size = VMM_MEMORY_SIZE;
hb_dump_region.flags = SbePsu::SBE_MEM_REGION_OPEN_READ_ONLY;
iv_memRegions.push_back(hb_dump_region);

// Find master proc for target of PSU commdoand, if necessary
TARGETING::TargetHandle_t l_masterProc = nullptr;
TARGETING::TargetService& tS = TARGETING::targetService();

l_errl = tS.queryMasterProcChipTargetHandle(l_masterProc);
if (l_errl)
{
SBE_TRACF(ERR_MRK "doUnsecureMemRegionOp: Failed to get Master "
"Proc: err rc=0x%.4X plid=0x%.8X",
ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl));

break;
}

// Store Master Proc for easy lookup
iv_masterProc = l_masterProc;

// Set target for future operations
hb_dump_region.tgt = iv_masterProc;

// Add Memory region for HB Dump to master proc's list
addToTargetRegionList(iv_masterProc, hb_dump_region);

SBE_TRACD("MemRegionMgr Constructor: Initial region(s):");
printIvMemRegions();

} while(0);

// doShutdown if error in constructor
if (l_errl)
{
uint64_t l_reasonCode = l_errl->reasonCode();
SBE_TRACF(ERR_MRK"MemRegionMgr Constructor: failed with rc=0x%08X",
l_reasonCode);
l_errl->collectTrace(SBEIO_COMP_NAME);
errlCommit(l_errl, SBEIO_COMP_ID);
INITSERVICE::doShutdown(l_reasonCode);
}

SBE_TRACD(EXIT_MRK"MemRegionMgr Constructor");
};

Expand All @@ -113,8 +152,8 @@ MemRegionMgr::MemRegionMgr()
*/
MemRegionMgr::~MemRegionMgr()
{
// Clear Vector of Unsecure Memory Regions
iv_memRegions.clear();
// Clear map of Unsecure Memory Regions
iv_memRegionMap.clear();
};

/**
Expand All @@ -130,7 +169,9 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(

errlHndl_t errl = nullptr;
regionData l_region;
uint8_t region_count = iv_memRegions.size();
// Get Region list based on target
auto l_memRegions = getTargetRegionList(i_target);
uint8_t region_count = l_memRegions->size();
bool itr_region_closed = false;
const uint8_t input_flags = i_isWritable ?
SbePsu::SBE_MEM_REGION_OPEN_READ_WRITE :
Expand All @@ -152,8 +193,8 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(
// ---- If no overlap, open requested region
// Throughout check that no more than 8 memory regions are opened

auto itr = iv_memRegions.begin();
while (itr != iv_memRegions.end())
auto itr = l_memRegions->begin();
while (itr != l_memRegions->end())
{
// reset for each loop
itr_region_closed = false;
Expand Down Expand Up @@ -223,7 +264,7 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(
++region_count;

// Add the region to the cache list
iv_memRegions.push_front(l_region);
l_memRegions->push_front(l_region);
}
}
}
Expand Down Expand Up @@ -299,7 +340,7 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(
++region_count;

// Add the region to the cache list
iv_memRegions.push_front(l_region);
l_memRegions->push_front(l_region);
}
}

Expand Down Expand Up @@ -348,7 +389,7 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(
// Increment Iterator
if (itr_region_closed == true)
{
itr = iv_memRegions.erase(itr);
itr = l_memRegions->erase(itr);
}
else
{
Expand Down Expand Up @@ -388,7 +429,7 @@ errlHndl_t MemRegionMgr::openUnsecureMemRegion(
else
{
// Add region to cache on success
iv_memRegions.push_front(l_region);
l_memRegions->push_front(l_region);
}

}
Expand Down Expand Up @@ -432,11 +473,13 @@ errlHndl_t MemRegionMgr::closeUnsecureMemRegion(
SBE_TRACF(ENTER_MRK"closeUnsecureMemRegion: i_tgt=0x%X: "
"i_start_addr=0x%.16llX",
TARGETING::get_huid(i_target), i_start_addr);

do
{
auto itr = iv_memRegions.begin();
while (itr != iv_memRegions.end())
// Get Region list based on target
auto l_memRegions = getTargetRegionList(i_target);

auto itr = l_memRegions->begin();
while (itr != l_memRegions->end())
{
if (itr->start_addr == i_start_addr)
{
Expand All @@ -457,7 +500,7 @@ errlHndl_t MemRegionMgr::closeUnsecureMemRegion(
}
else
{
itr = iv_memRegions.erase(itr);
itr = l_memRegions->erase(itr);
}

// Quit walking through regions
Expand Down Expand Up @@ -494,7 +537,7 @@ errlHndl_t MemRegionMgr::closeUnsecureMemRegion(
SBEIO_MEM_REGION,
SBEIO_MEM_REGION_DOES_NOT_EXIST,
i_start_addr,
iv_memRegions.size(),
l_memRegions->size(),
true /*Add HB SW Callout*/ );

errl->collectTrace(SBEIO_COMP_NAME);
Expand Down Expand Up @@ -536,16 +579,22 @@ errlHndl_t MemRegionMgr::closeAllUnsecureMemRegions()

regionData l_region;

SBE_TRACF(ENTER_MRK"closeAllUnsecureMemRegions: closing %d region(s)",
iv_memRegions.size());
SBE_TRACF(ENTER_MRK"closeAllUnsecureMemRegions: closing %d region(s) among all targets",
getTotalNumOfRegions());

printIvMemRegions();

do
{
// Close every memory region saved in vector
auto itr = iv_memRegions.begin();
while (itr != iv_memRegions.end())
// Loop all targets
for (auto & l_memRegionPair : iv_memRegionMap)
{
// Get Region list based on target
auto l_memRegions = &l_memRegionPair.second;

// Close every memory region saved in list
auto itr = l_memRegions->begin();
while (itr != l_memRegions->end())
{
// Close Requested Region
l_region.start_addr = itr->start_addr;
Expand Down Expand Up @@ -589,17 +638,17 @@ errlHndl_t MemRegionMgr::closeAllUnsecureMemRegions()
}
else
{
itr = iv_memRegions.erase(itr);
itr = l_memRegions->erase(itr);
}
}
}
while (0);
} while (0);

printIvMemRegions();

SBE_TRACF(EXIT_MRK "closeAllUnsecureMemRegions: regions left = %d, "
SBE_TRACF(EXIT_MRK "closeAllUnsecureMemRegions: regions left = %d among all targets, "
"err_rc=0x%.4X",
iv_memRegions.size(),
getTotalNumOfRegions(),
ERRL_GETRC_SAFE(errl_orig));
if(errl_orig)
{
Expand Down Expand Up @@ -751,27 +800,55 @@ errlHndl_t MemRegionMgr::checkNumberOfMemRegions(uint8_t i_count) const
*/
void MemRegionMgr::printIvMemRegions(void) const
{
const uint8_t size = iv_memRegions.size();

if ( size == 0 )
{
SBE_TRACD("MemRegionMgr::printIvMemRegions: number of entries=%d",
iv_memRegions.size());
}
else
SBE_TRACF("printIvMemRegions");
for (const auto & l_memRegionPair : iv_memRegionMap)
{
SBE_TRACF("Target HUID 0x%.8X",
TARGETING::get_huid(l_memRegionPair.first));
// Get size of target specific memory region list
const uint8_t size = l_memRegionPair.second.size();
uint8_t count = 1;
for ( const auto& itr : iv_memRegions )
for (const auto & l_memRegion : l_memRegionPair.second)
{
SBE_TRACD("printIvMemRegions: %d/%d: tgt=0x%.8X: "
"start_addr=0x%.16llX, size=0x%.8X, flags=0x%.2X (%s)",
count, size, TARGETING::get_huid(itr.tgt),
itr.start_addr, itr.size, itr.flags,
itr.flags == SbePsu::SBE_MEM_REGION_OPEN_READ_ONLY ?
"Read-Only" : "Read-Write");
SBE_TRACF("- %d/%d: tgt=0x%.8X: start_addr=0x%.16llX, size=0x%.8X, flags=0x%.2X (%s)",
count, size, TARGETING::get_huid(l_memRegion.tgt),
l_memRegion.start_addr, l_memRegion.size,
l_memRegion.flags,
(l_memRegion.flags == SbePsu::SBE_MEM_REGION_OPEN_READ_ONLY) ?
"Read-Only" : "Read-Write");
++count;
}
}
}

void MemRegionMgr::addToTargetRegionList(TARGETING::TargetHandle_t i_target,
const regionData& i_region)
{
if (i_target == nullptr)
{
i_target = iv_masterProc;
}
iv_memRegionMap[i_target].push_back(i_region);
}

RegionDataList* MemRegionMgr::getTargetRegionList(TARGETING::TargetHandle_t i_target)
{
if (i_target == nullptr)
{
i_target = iv_masterProc;
}
return &iv_memRegionMap[i_target];
}

uint8_t MemRegionMgr::getTotalNumOfRegions() const
{
uint8_t l_count = 0;
for (const auto & l_memRegionPair : iv_memRegionMap)
{
l_count += l_memRegionPair.second.size();
}

return l_count;
}

} // end namespace SBEIO
52 changes: 46 additions & 6 deletions src/usr/sbeio/sbe_memRegionMgr.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2017 */
/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand All @@ -27,8 +27,10 @@

#include <stdint.h>
#include <errl/errlentry.H>
#include <vector>
#include <list>
#include <sbeio/sbeioif.H>
#include <targeting/common/target.H>
#include <map>

namespace SBEIO
{
Expand All @@ -52,11 +54,15 @@ struct regionData

// Target associated with the SBE
// - If tgt == nullptr it will eventually be updated to the Master Proc
TARGETING::Target* tgt;
TARGETING::TargetHandle_t tgt;

regionData() : start_addr(0), size(0), flags(0), tgt(nullptr) {}
};

typedef std::list<regionData> RegionDataList;
typedef std::pair<TARGETING::TargetHandle_t, RegionDataList> MemRegionMapPair;
typedef std::map<TARGETING::TargetHandle_t, RegionDataList> MemRegionMap;

/** @class MemRegionMgr
* @brief Responsible for managing the SBE Unsecure Memory Regions
*
Expand All @@ -66,12 +72,17 @@ class MemRegionMgr

private:

/** Cache of Unsecure Memory Regions that are currently open */
std::list< regionData > iv_memRegions;
/** Cache of Unsecure Memory Regions that are currently open
* Key = Target Pointer, Value = List of Memory Regions
*/
MemRegionMap iv_memRegionMap;

/* For Debug purposes: Pring Out Vector of iv_memRegions */
/* For Debug purposes: Print out memory region map */
void printIvMemRegions() const;

/* Cache master proc */
TARGETING::TargetHandle_t iv_masterProc;

/**
* @brief Local Function To Open/Close Unsecure Memory Regions
*
Expand All @@ -94,6 +105,35 @@ class MemRegionMgr
*/
errlHndl_t checkNumberOfMemRegions(uint8_t i_count) const;

/**
* @brief Append region data to region list of specified target
*
* @param[in] i_target Proc target to apply region data to
* Note: nullptr assumed to be acting master proc
* @param[in] i_region Region data
*
* @return N/A
*/
void addToTargetRegionList(TARGETING::TargetHandle_t i_target,
const regionData& i_region);

/**
* @brief Get region data list of specified target
*
* @param[in] i_target Proc target to obtain region data list from
* Note: nullptr assumed to be acting master proc
*
* @return N/A
*/
RegionDataList* getTargetRegionList(TARGETING::TargetHandle_t i_target);

/**
* @brief Get number of all memory regions amongst all targets
*
* @return N/A
*/
uint8_t getTotalNumOfRegions() const;

public:
/**
* @brief Constructor. Initializes instance variables.
Expand Down

0 comments on commit 329b814

Please sign in to comment.