From 7d7c9d3dbd1bfd3fce9f534d9ba5bb179711202a Mon Sep 17 00:00:00 2001 From: spashabk-in Date: Wed, 25 Oct 2017 07:48:20 -0500 Subject: Handle OCC SRAM secure mem window Allow access to only the unsecure memory windows of OCC SRAM Change-Id: I66a9383b2470fa0124708a582db4a643738535cf Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48796 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Sachin Gupta --- src/sbefw/sbeSecureMemRegionManager.C | 17 ++- src/sbefw/sbeSecureMemRegionManager.H | 54 ++++++++-- src/sbefw/sbecmdiplcontrol.C | 4 +- src/sbefw/sbecmdmemaccess.C | 8 +- src/sbefw/sbecmdsram.C | 68 +++++++----- src/sbefw/sbeglobals.C | 3 + src/sbefw/sbeglobals.H | 9 ++ src/test/testcases/testSram.py | 194 ++++++++++++++++++++-------------- 8 files changed, 228 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/sbefw/sbeSecureMemRegionManager.C b/src/sbefw/sbeSecureMemRegionManager.C index 27bd0f66..822ee040 100644 --- a/src/sbefw/sbeSecureMemRegionManager.C +++ b/src/sbefw/sbeSecureMemRegionManager.C @@ -28,15 +28,12 @@ #include "sbeglobals.H" #ifndef __SBEFW_SEEPROM__ - -SBESecureMemRegionManager* SBESecMemRegionManager = - &SBESecureMemRegionManager::getInstance(); - -SBESecureMemRegionManager& SBESecureMemRegionManager::getInstance() -{ - static SBESecureMemRegionManager iv_instance; - return iv_instance; -} +SBESecureMemRegionManager mainStoreSecMemRegionManager( + &SBE_GLOBAL->mainMemRegions[0], + MAX_MAIN_STORE_REGIONS); +SBEOccSramSecMemRegionManager occSramSecRegionManager( + &SBE_GLOBAL->occSramRegions[0], + MAX_OCC_SRAM_REGIONS); secureMemRegion_t SBESecureMemRegionManager::getPartialRegionSize( const secureMemRegion_t i_region) @@ -91,7 +88,7 @@ sbeSecondaryResponse SBESecureMemRegionManager::add(const uint64_t i_startAddr, rc = SBE_SEC_MEM_REGION_AMEND_ATTEMPTED; break; } - if(iv_regionsOpenCnt >= MAX_NONSECURE_MEM_REGIONS) + if(iv_regionsOpenCnt >= iv_maxRegions) { SBE_ERROR(SBE_FUNC" SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED"); rc = SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED; diff --git a/src/sbefw/sbeSecureMemRegionManager.H b/src/sbefw/sbeSecureMemRegionManager.H index c1127643..934fba0d 100644 --- a/src/sbefw/sbeSecureMemRegionManager.H +++ b/src/sbefw/sbeSecureMemRegionManager.H @@ -6,6 +6,7 @@ /* OpenPOWER sbe Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -41,17 +42,20 @@ typedef struct uint32_t mode; } secureMemRegion_t; -constexpr size_t MAX_NONSECURE_MEM_REGIONS = 8; +// OCC SRAM Command buffer +constexpr uint64_t OCC_CMD_ADDR = 0xFFFBE000ull; +constexpr uint32_t OCC_CMD_SIZE = 0xFFFBEFFF - 0xFFFBE000; +// OCC SRAM Response buffer +constexpr uint64_t OCC_RESP_ADDR = 0xFFFBF000ull; +constexpr uint32_t OCC_RESP_SIZE = 0xFFFBFFFF- 0xFFFBF000; class SBESecureMemRegionManager { - secureMemRegion_t iv_memRegions[MAX_NONSECURE_MEM_REGIONS]; + protected: + secureMemRegion_t *iv_memRegions; + const size_t iv_maxRegions; size_t iv_regionsOpenCnt; - SBESecureMemRegionManager():iv_memRegions{0} - { - } - /* * @brief getPartialRegionSize - get the overlapping region * if it exists. @@ -66,12 +70,17 @@ class SBESecureMemRegionManager secureMemRegion_t getPartialRegionSize(const secureMemRegion_t i_region); public: + SBESecureMemRegionManager(secureMemRegion_t *i_regions, + size_t i_maxRegions): + iv_memRegions(i_regions), + iv_maxRegions(i_maxRegions) + { + } + // Disable copy constructors SBESecureMemRegionManager(const SBESecureMemRegionManager&) = delete; SBESecureMemRegionManager& operator=(const SBESecureMemRegionManager&) = delete; - static SBESecureMemRegionManager& getInstance(); - /* * @brief add - Open a new memory region * @@ -110,4 +119,31 @@ class SBESecureMemRegionManager } }; -extern SBESecureMemRegionManager* SBESecMemRegionManager; +class SBEOccSramSecMemRegionManager : public SBESecureMemRegionManager +{ + public: + SBEOccSramSecMemRegionManager(secureMemRegion_t *i_regions, + size_t i_maxRegions): + SBESecureMemRegionManager(i_regions, + i_maxRegions) + { + add(OCC_CMD_ADDR, + OCC_CMD_SIZE, + static_cast( memRegionMode::WRITE) | + static_cast(memRegionMode::READ)); + add(OCC_RESP_ADDR, + OCC_RESP_SIZE, + static_cast(memRegionMode::READ)); + } + + // Disable copy constructors + SBEOccSramSecMemRegionManager(const SBEOccSramSecMemRegionManager&) = delete; + SBEOccSramSecMemRegionManager& operator=(const SBEOccSramSecMemRegionManager&) = delete; + // Disable delete functions + sbeSecondaryResponse remove(const uint64_t i_startAddr) = delete; + void closeAllRegions() = delete; + +}; + +extern SBESecureMemRegionManager mainStoreSecMemRegionManager; +extern SBEOccSramSecMemRegionManager occSramSecRegionManager; diff --git a/src/sbefw/sbecmdiplcontrol.C b/src/sbefw/sbecmdiplcontrol.C index fcad94c6..b49a2886 100644 --- a/src/sbefw/sbecmdiplcontrol.C +++ b/src/sbefw/sbecmdiplcontrol.C @@ -922,7 +922,7 @@ ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp) SBE_INFO("istep 5.1 HB Dump mem Region [0x%08X%08X]", SBE::higher32BWord(drawer_base_address_nm0), SBE::lower32BWord(drawer_base_address_nm0)); - SBESecMemRegionManager->add(drawer_base_address_nm0, + mainStoreSecMemRegionManager.add(drawer_base_address_nm0, HB_MEM_WINDOW_SIZE, static_cast(memRegionMode::READ)); @@ -1261,7 +1261,7 @@ ReturnCode istepStartMpipl( sbeIstepHwp_t i_hwp) // Set MPIPL mode bit in Scratch Reg 3 (void)SbeRegAccess::theSbeRegAccess().setMpIplMode(true); // Close all non-secure memory regions - SBESecMemRegionManager->closeAllRegions(); + mainStoreSecMemRegionManager.closeAllRegions(); do { diff --git a/src/sbefw/sbecmdmemaccess.C b/src/sbefw/sbecmdmemaccess.C index a62b4de6..9ea19d34 100644 --- a/src/sbefw/sbecmdmemaccess.C +++ b/src/sbefw/sbecmdmemaccess.C @@ -192,7 +192,7 @@ uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, { l_addr = i_hdr.getAddr(); // Check if the access to the address is allowed - l_respHdr.secondaryStatus = SBESecMemRegionManager->isAccessAllowed( + l_respHdr.secondaryStatus = mainStoreSecMemRegionManager.isAccessAllowed( {l_addr, i_hdr.len, (i_isFlagRead ? static_cast(memRegionMode::READ): @@ -469,7 +469,7 @@ uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr, SBE_MEM_ACCESS_WRITE), sbeMemAccessInterface::ADU_GRAN_SIZE_BYTES); // Check if the access to the address is allowed - l_respHdr.secondaryStatus = SBESecMemRegionManager->isAccessAllowed( + l_respHdr.secondaryStatus = mainStoreSecMemRegionManager.isAccessAllowed( {l_addr, i_hdr.len, (i_isFlagRead ? static_cast(memRegionMode::READ): @@ -764,7 +764,7 @@ uint32_t sbeUpdateMemAccessRegion (uint8_t *i_pArg) if(mode == SBE_MEM_REGION_CLOSE) { SBE_GLOBAL->sbeSbe2PsuRespHdr.secStatus = - SBESecMemRegionManager->remove(req.startAddress); + mainStoreSecMemRegionManager.remove(req.startAddress); } else { @@ -779,7 +779,7 @@ uint32_t sbeUpdateMemAccessRegion (uint8_t *i_pArg) static_cast(memRegionMode::WRITE); } SBE_GLOBAL->sbeSbe2PsuRespHdr.secStatus = - SBESecMemRegionManager->add(req.startAddress, + mainStoreSecMemRegionManager.add(req.startAddress, req.size, memMode); } diff --git a/src/sbefw/sbecmdsram.C b/src/sbefw/sbecmdsram.C index 416dd1fc..f4732d5c 100644 --- a/src/sbefw/sbecmdsram.C +++ b/src/sbefw/sbecmdsram.C @@ -35,6 +35,7 @@ #include "sbetrace.H" #include "sbeFifoMsgUtils.H" #include "sberegaccess.H" +#include "sbeSecureMemRegionManager.H" #include "fapi2.H" #include "p9_pm_ocb_init.H" @@ -81,11 +82,11 @@ uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag) // Check if True - Get / False - Put p9ocb::PM_OCB_ACCESS_OP l_ocb_access = (i_isGetFlag)? p9ocb::OCB_GET : p9ocb::OCB_PUT; + // Get the Req Struct Size Data from upstream Fifo + uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t); do { - // Get the Req Struct Size Data from upstream Fifo - uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t); l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_req, i_isGetFlag); @@ -134,6 +135,20 @@ uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag) break; } CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + // Check if the access to the address is allowed + if(l_validAddrForFirstAccess) + { + l_respHdr.secondaryStatus = occSramSecRegionManager.isAccessAllowed( + {static_cast(l_req.addr)&(0x00000000FFFFFFFFull), + l_req.len, + (i_isGetFlag? static_cast(memRegionMode::READ): + static_cast(memRegionMode::WRITE))}); + if(l_respHdr.secondaryStatus != SBE_SEC_OPERATION_SUCCESSFUL) + { + l_respHdr.primaryStatus = SBE_PRI_UNSECURE_ACCESS_DENIED; + break; + } + } // Setup Needs to be called in Normal and Debug Mode only if( (l_req.mode == NORMAL_MODE) || (l_req.mode == DEBUG_MODE) ) @@ -224,40 +239,39 @@ uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag) } } // End of while Put/Get from Hwp + }while(0); + do + { // If there was a FIFO error, will skip sending the response, // instead give the control back to the command processor thread CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); - - do + l_len2dequeue = 0; + if (!i_isGetFlag) { - l_len2dequeue = 0; - if (!i_isGetFlag) + // If there was a HWP failure for put sram occ request, + // need to Flush out upstream FIFO, until EOT arrives + if ( l_respHdr.primaryStatus != SBE_PRI_OPERATION_SUCCESSFUL) { - // If there was a HWP failure for put sram occ request, - // need to Flush out upstream FIFO, until EOT arrives - if ( l_fapiRc != FAPI2_RC_SUCCESS ) - { - l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, - true, true); - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); - } - // For other success paths, just attempt to offload - // the next entry, which is supposed to be the EOT entry - else - { - l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true); - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); - } + l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, + true, true); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + } + // For other success paths, just attempt to offload + // the next entry, which is supposed to be the EOT entry + else + { + l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); } + } - uint32_t l_len = 1; - // first enqueue the length of data actually written - l_rc = sbeDownFifoEnq_mult(l_len, (uint32_t *)(&l_totalReturnLen)); + uint32_t l_len = 1; + // first enqueue the length of data actually written + l_rc = sbeDownFifoEnq_mult(l_len, (uint32_t *)(&l_totalReturnLen)); - CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); - l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc); - }while(0); + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc); + l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc); }while(0); SBE_EXIT(SBE_FUNC); diff --git a/src/sbefw/sbeglobals.C b/src/sbefw/sbeglobals.C index 5dd146a0..f3084e30 100644 --- a/src/sbefw/sbeglobals.C +++ b/src/sbefw/sbeglobals.C @@ -42,3 +42,6 @@ SBEGlobalsSingleton& SBEGlobalsSingleton::getInstance() } // SBE commit id uint32_t SBEGlobalsSingleton::fwCommitId = SBE_COMMIT_ID; + +secureMemRegion_t SBEGlobalsSingleton::mainMemRegions[MAX_MAIN_STORE_REGIONS] = {}; +secureMemRegion_t SBEGlobalsSingleton::occSramRegions[MAX_OCC_SRAM_REGIONS] = {}; diff --git a/src/sbefw/sbeglobals.H b/src/sbefw/sbeglobals.H index 2b49a20e..176d2720 100644 --- a/src/sbefw/sbeglobals.H +++ b/src/sbefw/sbeglobals.H @@ -31,9 +31,13 @@ #include "sbestates.H" #include "sbeexeintf.H" #include "sbecmdgeneric.H" +#include "sbeSecureMemRegionManager.H" #define SBE_GLOBAL sbeGlobal +constexpr size_t MAX_MAIN_STORE_REGIONS = 8; +constexpr size_t MAX_OCC_SRAM_REGIONS = 2; + // Extern declartion, Defined in sbeglobal.C extern uint8_t sbe_Kernel_NCInt_stack[SBE_NONCRITICAL_STACK_SIZE]; extern uint8_t sbeCommandReceiver_stack[SBE_THREAD_CMD_RECV_STACK_SIZE]; @@ -87,6 +91,11 @@ class SBEGlobalsSingleton // SBE commit id static uint32_t fwCommitId; + + // Secure memory window arrays + static secureMemRegion_t mainMemRegions[MAX_MAIN_STORE_REGIONS]; + static secureMemRegion_t occSramRegions[MAX_OCC_SRAM_REGIONS]; + //////////////////////////////////////////////////////////////// //// @brief PkThread structure for SBE Command Receiver thread ////////////////////////////////////////////////////////////////// diff --git a/src/test/testcases/testSram.py b/src/test/testcases/testSram.py index cf992478..1465705e 100644 --- a/src/test/testcases/testSram.py +++ b/src/test/testcases/testSram.py @@ -5,7 +5,7 @@ # # OpenPOWER sbe Project # -# Contributors Listed Below - COPYRIGHT 2016 +# Contributors Listed Below - COPYRIGHT 2016,2017 # [+] International Business Machines Corp. # # @@ -23,98 +23,138 @@ # # IBM_PROLOG_END_TAG import sys +import os sys.path.append("targets/p9_nimbus/sbeTest" ) import testUtil err = False #from testWrite import * -LOOP_COUNT = 1 - -PUTSRAM_OCC_CNTLDATA = [0,0,0,0x20, - 0,0,0xa4,0x04, #magic - 0,0,0,0x01, - 0xe7,0xf0,0x00,0x00, #addr - 0,0,0x01,0x00] # length - -PUTSRAM_OCC_TESTDATA = [0xab,0xcd,0xef,0x12, - 0xba,0xdc,0xfe,0x21, - 0x34,0x56,0x78,0x9a, - 0x43,0x65,0x87,0xa9, - 0xab,0xcd,0xef,0x12, - 0xba,0xdc,0xfe,0x21, - 0x34,0x56,0x78,0x9a, - 0x43,0x65,0x87,0xa9] - -PUTSRAM_OCC_EXP_CNTLDATA = [0,0,0x01,0x00, - 0xc0,0xde,0xa4,0x04, - 0x0,0x0,0x0,0x0, - 0x00,0x0,0x0,0x03] - -GETSRAM_OCC_CNTLDATA = [0,0,0,0x5, - 0,0,0xa4,0x03, - 0,0,0,0x01, - 0xe7,0xf0,0x00,0x00, #address - 0x00,0x00,0x01,0x00] # length of data - -GETSRAM_OCC_EXP_TESTDATA = [0xab,0xcd,0xef,0x12, #data - 0xba,0xdc,0xfe,0x21, - 0x34,0x56,0x78,0x9a, - 0x43,0x65,0x87,0xa9, - 0xab,0xcd,0xef,0x12, - 0xba,0xdc,0xfe,0x21, - 0x34,0x56,0x78,0x9a, - 0x43,0x65,0x87,0xa9] - -GETSRAM_OCC_EXP_CNTLDATA = [0x00,0x00,0x01,0x00, # length - 0xc0,0xde,0xa4,0x03, - 0x0,0x0,0x0,0x0, - 0x00,0x0,0x0,0x03]; +def gethalfword(dataInInt): + hex_string = '0'*(4-len(str(hex(dataInInt))[2:])) + str(hex(dataInInt))[2:] + return list(struct.unpack(' 32*8 = 256 = 0x100 - i_cnt = 0 - while i_cnt < 8: - testUtil.writeUsFifo( PUTSRAM_OCC_TESTDATA ) - i_cnt = i_cnt+1 - + testUtil.writeUsFifo( req ) testUtil.writeEot( ) - # Read the expected data for put sram - testUtil.readDsFifo( PUTSRAM_OCC_EXP_CNTLDATA ) + if((primStatus != 0) or (secStatus != 0)): + data = [] + expData = (getsingleword(len(data)) + + [0xc0, 0xde, 0xa4, 0x04] + + gethalfword(primStatus) + + gethalfword(secStatus) + + getsingleword(0x03)) + testUtil.readDsFifo(expData) testUtil.readEot( ) - # Get Sram Linear - testUtil.writeUsFifo( GETSRAM_OCC_CNTLDATA ) - testUtil.writeEot( ) +def getsram(addr, mode, length, primStatus, secStatus): + req = (getsingleword(0x05) + + getsingleword(0xa403) + + getsingleword(mode) + + getsingleword(addr) + + getsingleword(length)) - # Read the Expected Data for get Sram - i_cnt = 0 - while i_cnt < 8: - testUtil.readDsFifo( GETSRAM_OCC_EXP_TESTDATA ) - i_cnt = i_cnt+1 + testUtil.runCycles( 10000000 ) + testUtil.writeUsFifo( req ) + testUtil.writeEot( ) - testUtil.readDsFifo( GETSRAM_OCC_EXP_CNTLDATA ) + data = [] + if((primStatus != 0) or (secStatus != 0)): + length = 0 + for i in range(0, int(-(-float(length)//4))): + data += list(testUtil.readDsEntryReturnVal()) + readLen = testUtil.readDsEntryReturnVal() + if(getsingleword(length) != list(readLen)): + print getsingleword(length) + print list(readLen) + raise Exception("Invalid Length") + + expResp = (getsingleword(0xc0dea403) + + gethalfword(primStatus) + + gethalfword(secStatus) + + getsingleword(0x03)) + testUtil.readDsFifo(expResp) testUtil.readEot( ) - # Put Occ Sram test - Circular - Can be enabled once we get - # valid address range to read the circular data - #testUtil.writeUsFifo( PUTSRAM_OCC_TESTDATA_1 ) - #testUtil.writeEot( ) - #testUtil.readDsFifo( PUTSRAM_OCC_EXPDATA_1 ) - #testUtil.readEot( ) - #testUtil.writeUsFifo( GETSRAM_OCC_TESTDATA_1 ) - #testUtil.writeEot( ) - #testUtil.readDsFifo( GETSRAM_OCC_EXPDATA_1 ) - #testUtil.readEot( ) + return data[:length] +# MAIN Test Run Starts Here... +#------------------------------------------------- +def main( ): + testcase = "" + try: + testUtil.runCycles( 10000000 ) + + # Put Occ Sram test - Linear - Can be tested over Normal + # Debug mode + data = os.urandom(128*2) + data = [ord(c) for c in data] + putsram(0xFFFBE000, 0x01, data, 0, 0) + + readData = getsram(0xFFFBE000, 0x01, 128*2, 0, 0) + + if(data == readData): + print("Success: put - get sram") + else: + print data + print readData + raise Exception('data mistmach') + + # secure mem - write to disallowed mem + # start and end completely outside + testcase = "sec put test 1" + putsram(0xFFFBE000-256, 0x01, data, 0x0005, 0x0014) + print("Success: "+testcase) + # start outside and end inside the window + testcase = "sec put test 2" + putsram(0xFFFBE000-128, 0x01, data, 0x0005, 0x0014) + print("Success: "+testcase) + # start inside and end outside the window + testcase = "sec put test 3" + putsram(0xFFFBE000-128, 0x01, data, 0x0005, 0x0014) + print("Success: "+testcase) + + # secure mem - read on disallowed mem + # start and end completely outside + testcase = "sec get test 1" + getsram(0xFFFBE000-256, 0x01, 256, 0x0005, 0x0014) + print("Success: "+testcase) + # start outside and end inside the window + testcase = "sec get test 2" + getsram(0xFFFBE000-128, 0x01, 256, 0x0005, 0x0014) + print("Success: "+testcase) + # start inside and end outside the window + testcase = "sec get test 3" + getsram(0xFFFBE000-128, 0x01, 256, 0x0005, 0x0014) + print("Success: "+testcase) + + # Put Occ Sram test - Circular - Can be enabled once we get + # valid address range to read the circular data + #testUtil.writeUsFifo( PUTSRAM_OCC_TESTDATA_1 ) + #testUtil.writeEot( ) + #testUtil.readDsFifo( PUTSRAM_OCC_EXPDATA_1 ) + #testUtil.readEot( ) + #testUtil.writeUsFifo( GETSRAM_OCC_TESTDATA_1 ) + #testUtil.writeEot( ) + #testUtil.readDsFifo( GETSRAM_OCC_EXPDATA_1 ) + #testUtil.readEot( ) + except: + print "FAILED Test Case:"+str(testcase) + raise Exception('Failure') #------------------------------------------------- # Calling all test code -- cgit v1.2.1