| From 3dba59d5b60a9ad307b91d4063279cb1535cda8f Mon Sep 17 00:00:00 2001 |
| From: Stewart Smith <stewart@linux.ibm.com> |
| Date: Wed, 18 Apr 2018 17:06:09 +1000 |
| Subject: [PATCH] Revert "Mark Read-Only Partitions as Such" |
| |
| This reverts commit f5cd23d6c3be17356e0851ec5d5bb65cee48f15f. |
| |
| Only changing the presence of this commit, we go from failing to boot |
| (error below) to being able to boot. |
| |
| 24.41069|ISTEP 10. 2 - host_slave_sbe_update |
| 24.44213|System shutting down with error status 0x90000012 |
| 24.45270|================================================ |
| 24.45420|Error reported by initservice (0x0500) PLID 0x90000012 |
| 24.45422| Initialization Service launched a function and |
| the task returned an error. |
| 24.45423| ModuleId 0x01 BASE_INITSVC_MOD_ID |
| 24.45573| ReasonCode 0x0506 WAIT_FN_FAILED |
| 24.45574| UserData1 task id or task return code : 0x00000000000000ec |
| 24.45574| UserData2 returned status from task : 0x0000000000000001 |
| 24.45575|------------------------------------------------ |
| 24.45875| Callout type : Procedure Callout |
| 24.45876| Procedure : EPUB_PRC_HB_CODE |
| 24.45876| Priority : SRCI_PRIORITY_HIGH |
| 24.45877|------------------------------------------------ |
| 24.45878| host_slave_sbe_update |
| 24.45878|------------------------------------------------ |
| 24.45879| Hostboot Build ID: |
| 24.45879|================================================ |
| |
| Change-Id: I7ac38afc8bed608d6272f1ef6f099e3fc03bb270 |
| Signed-off-by: Stewart Smith <stewart@linux.ibm.com> |
| --- |
| src/include/usr/pnor/pnor_reasoncodes.H | 1 - |
| src/usr/pnor/pnorrp.C | 15 +- |
| src/usr/pnor/test/pnorrptest.H | 188 ++++++++---------------- |
| src/usr/secureboot/base/test/securerommgrtest.H | 20 --- |
| 4 files changed, 71 insertions(+), 153 deletions(-) |
| |
| diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H |
| index 2835f8a153d0..4dd2ef1c43de 100644 |
| --- a/src/include/usr/pnor/pnor_reasoncodes.H |
| +++ b/src/include/usr/pnor/pnor_reasoncodes.H |
| @@ -187,7 +187,6 @@ namespace PNOR |
| RC_SECURE_SIZE_MISMATCH = PNOR_COMP_ID | 0x3A, |
| RC_NOT_PAGE_ALIGNED = PNOR_COMP_ID | 0x3B, |
| RC_SECURE_PRO_SIZE_MISMATCH = PNOR_COMP_ID | 0x3C, |
| - RC_READ_ONLY_PERM_FAIL = PNOR_COMP_ID | 0x3D, |
| |
| //@fixme-RTC:131607-Temporary value to allow HWSV compile |
| //termination_rc |
| diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C |
| index df88ba821b70..e33a1b0c377c 100644 |
| --- a/src/usr/pnor/pnorrp.C |
| +++ b/src/usr/pnor/pnorrp.C |
| @@ -1776,31 +1776,32 @@ errlHndl_t PnorRP::setVirtAddrs(void) |
| // Handle section permissions |
| if (iv_TOC[i].misc & FFS_MISC_READ_ONLY) |
| { |
| - // Partitions marked with readOnly flag should be |
| - // READ_ONLY and not WRITABLE. |
| + // Need to set permissions to allow writing to virtual |
| + // addresses, but prevents the kernel from ejecting |
| + // dirty pages (no WRITE_TRACKED). |
| int rc = mm_set_permission( |
| (void*)iv_TOC[i].virtAddr, |
| iv_TOC[i].size, |
| - READ_ONLY); |
| + WRITABLE); |
| if (rc) |
| { |
| - TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to READ_ONLY for section %s.", |
| + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to WRITABLE for section %s.", |
| SectionIdToString(i)); |
| /*@ |
| * @errortype |
| * @moduleid PNOR::MOD_PNORRP_READTOC |
| - * @reasoncode PNOR::RC_READ_ONLY_PERM_FAIL |
| + * @reasoncode PNOR::RC_WRITABLE_PERM_FAIL |
| * @userdata1 PNOR section id |
| * @userdata2 PNOR section vaddr |
| * @devdesc Could not set permissions of the |
| - * given PNOR section to READ_ONLY |
| + * given PNOR section to WRITABLE |
| * @custdesc A problem occurred while reading |
| * Processor NOR flash partition table |
| */ |
| l_errhdl = new ERRORLOG::ErrlEntry( |
| ERRORLOG::ERRL_SEV_UNRECOVERABLE, |
| PNOR::MOD_PNORRP_READTOC, |
| - PNOR::RC_READ_ONLY_PERM_FAIL, |
| + PNOR::RC_WRITABLE_PERM_FAIL, |
| i, |
| iv_TOC[i].virtAddr, |
| true /*Add HB SW Callout*/); |
| diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H |
| index 5108840f5040..942eff9abdff 100644 |
| --- a/src/usr/pnor/test/pnorrptest.H |
| +++ b/src/usr/pnor/test/pnorrptest.H |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2011,2018 */ |
| +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ |
| /* [+] Google Inc. */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| @@ -39,7 +39,6 @@ |
| #include <sys/msg.h> |
| #include <limits.h> |
| #include <sys/mm.h> |
| -#include <sys/task.h> |
| #include <targeting/common/targetservice.H> |
| #include <devicefw/userif.H> |
| #include <config.h> |
| @@ -626,53 +625,82 @@ class PnorRpTest : public CxxTest::TestSuite |
| } |
| |
| /** |
| - * @brief PNOR RP test - read_ReadOnly_partition |
| - * Tests if we can read a readOnly partition |
| + * @brief PNOR RP test - ReadOnlyTag |
| + * Tests if readOnly tag on a section is being processed correctly |
| * |
| */ |
| - void test_read_ReadOnly_partition(void) |
| + void test_ReadOnlyTag(void) |
| { |
| - TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition Start"); |
| - |
| - int l_status = TASK_STATUS_EXITED_CLEAN; |
| - PNOR::SectionId l_testroSecId = PNOR::TESTRO; |
| - tid_t l_childTask = |
| - task_create(readFromReadOnlyPartition, &l_testroSecId); |
| + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag Start" ); |
| + PNOR::SectionInfo_t l_info; |
| + errlHndl_t l_errhdl = NULL; |
| + uint64_t chip_select = 0xF; |
| + bool needs_ecc = false; |
| |
| - if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) || |
| - (l_status != TASK_STATUS_EXITED_CLEAN)) |
| + l_errhdl = PNOR::getSectionInfo(PNOR::TESTRO, l_info); |
| + if( l_errhdl ) |
| { |
| - TS_FAIL("Could not read from readOnly partition."); |
| + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : getSectionInfo returned error for %d : RC=%X", |
| + PNOR::TESTRO, l_errhdl->reasonCode()); |
| + ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : could not read pnor section %d", PNOR::TESTRO); |
| } |
| - TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition End"); |
| - } |
| |
| - /** |
| - * @brief PNOR RP test - write_ReadOnly_partition |
| - * Tests if we can write to a readOnly partition (fail expected) |
| - * |
| - */ |
| - void test_write_ReadOnly_partition(void) |
| - { |
| - TRACFCOMP(g_trac_pnor, |
| - "PnorRpTest::test_write_ReadOnly_partition Start"); |
| + // Write some data |
| + const uint64_t l_writeData = 0x1122334455667788; |
| + uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr); |
| + l_dataptr[0] = l_writeData; |
| |
| - int l_status = TASK_STATUS_EXITED_CLEAN; |
| - PNOR::SectionId l_testroSecId = PNOR::TESTRO; |
| + // Flush the page to make sure it gets out to the device |
| + // Due to ReadOnly permissions set on TESTRO should be a no-op |
| + int rc = mm_remove_pages( RELEASE, l_dataptr, PAGESIZE ); |
| + if( rc ) |
| + { |
| + TRACFCOMP( g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE : rc=%X", rc ); |
| + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE" ); |
| + } |
| |
| - printk("Test case: Expect to see uncaught exception! "); |
| - tid_t l_childTask = |
| - task_create(writeToReadOnlyPartition, &l_testroSecId); |
| + // Get physical address of pnor section |
| + uint64_t l_address = 0; |
| + l_errhdl = PnorRP::getInstance().computeDeviceAddr((void*)l_info.vaddr, |
| + l_address, |
| + chip_select, |
| + needs_ecc); |
| + if(l_errhdl) |
| + { |
| + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr); |
| + errlCommit(l_errhdl,PNOR_COMP_ID); |
| + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr); |
| + } |
| |
| - if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) || |
| - (l_status != TASK_STATUS_CRASHED)) |
| + // Read pnor section and check if write did not occur |
| + uint64_t l_readData = 0; |
| + size_t l_size = sizeof(uint64_t); |
| + l_errhdl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, |
| + &l_readData, |
| + l_size, |
| + DEVICE_PNOR_ADDRESS(0, l_address)); |
| + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> Read Data = 0x%X",l_readData); |
| + if(l_errhdl) |
| { |
| - TS_FAIL("Write to readOnly partition exception not caught."); |
| + TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() failed! Error committed."); |
| + ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| + } |
| + if(l_readData == l_writeData) |
| + { |
| + TS_FAIL("PnorRpTest::test_ReadOnlyTag: Data was written to readOnly section = %s", |
| + l_info.name); |
| + } |
| + if(l_size != sizeof(uint64_t)) |
| + { |
| + TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", |
| + l_address, sizeof(uint64_t), l_size); |
| } |
| |
| - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_write_ReadOnly_partition End"); |
| + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag End"); |
| } |
| |
| + |
| //@todo - import config data from build and compare to section info |
| |
| /** |
| @@ -885,97 +913,7 @@ class PnorRpTest : public CxxTest::TestSuite |
| |
| } while (0); |
| #endif |
| - } |
| - |
| - private: |
| - static void* readFromReadOnlyPartition(void* i_section) |
| - { |
| - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition Start"); |
| - PNOR::SectionId* l_section = |
| - reinterpret_cast<PNOR::SectionId*>(i_section); |
| - PNOR::SectionInfo_t l_info; |
| - errlHndl_t l_errhdl = nullptr; |
| - |
| - do { |
| - |
| - if(isEnforcedSecureSection(*l_section)) |
| - { |
| - TS_FAIL("readFromReadOnlyPartition: section %d is secure." |
| - " readFromReadOnlyPartition does not support testing" |
| - " secure sections.", *l_section); |
| - break; |
| - } |
| - |
| - l_errhdl = PNOR::getSectionInfo(*l_section, l_info); |
| - if(l_errhdl) |
| - { |
| - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition: getSectionInfo " |
| - " returned an error for section %d : RC = 0x%.04x", |
| - *l_section, l_errhdl->reasonCode()); |
| - ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| - TS_FAIL("readFromReadOnlyPartition: failed to getSectionInfo" |
| - " for section %d", *l_section); |
| - break; |
| - } |
| - |
| - uint64_t l_data = 0; |
| - memcpy(&l_data, (void*)l_info.vaddr, sizeof(l_data)); |
| - // For this testing purpose, it doesn't actually matter what the data is |
| - } while(0); |
| - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition End"); |
| - return nullptr; |
| - } |
| - |
| - static void* writeToReadOnlyPartition(void* i_section) |
| - { |
| - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition Start"); |
| - PNOR::SectionId* l_section = |
| - reinterpret_cast<PNOR::SectionId*>(i_section); |
| - PNOR::SectionInfo_t l_info; |
| - errlHndl_t l_errhdl = nullptr; |
| - |
| - do { |
| - |
| - if(isEnforcedSecureSection(*l_section)) |
| - { |
| - TS_FAIL("writeToReadOnlyPartition: section %d is secure." |
| - " writeToReadOnlyPartition does not support testing secure" |
| - " sections.", *l_section); |
| - break; |
| - } |
| - |
| - l_errhdl = PNOR::getSectionInfo(*l_section, l_info); |
| - if(l_errhdl) |
| - { |
| - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition:" |
| - " getSectionInfo returned" |
| - " an error for section %d : RC=0x%.04x", |
| - *l_section, l_errhdl->reasonCode()); |
| - ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| - TS_FAIL("writeToReadOnlyPartition: could not read pnor section %d", |
| - *l_section); |
| - break; |
| - } |
| - |
| - // Write some data; should cause a task crash |
| - const uint64_t l_writeData = 0x1122334455667788; |
| - uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr); |
| - l_dataptr[0] = l_writeData; |
| - |
| - int rc = mm_remove_pages(RELEASE, l_dataptr, PAGESIZE); |
| - if(!rc) |
| - { |
| - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition : uncaught " |
| - "exception - write to a readOnly partition succeeded"); |
| - TS_FAIL("writeToReadOnlyPartition : no error returned on writing to" |
| - " a readOnly partition"); |
| - break; |
| - } |
| - |
| - } while(0); |
| - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition End"); |
| - return nullptr; |
| - } |
| + } |
| }; |
| |
| |
| diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H |
| index 35e70f707598..8ffa8375daff 100644 |
| --- a/src/usr/secureboot/base/test/securerommgrtest.H |
| +++ b/src/usr/secureboot/base/test/securerommgrtest.H |
| @@ -380,16 +380,6 @@ class SecureRomManagerTest : public CxxTest::TestSuite |
| - VFS::VfsRp::getInstance().iv_unprotectedOffset |
| + l_vaddr; |
| memcpy(l_originPage, reinterpret_cast<uint8_t*>(l_pnorVaddr), PAGESIZE); |
| - // Open the write permissions to allow the test to temporarily corrupt |
| - // the partition. |
| - int l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr), |
| - 2*PAGESIZE, |
| - WRITABLE); |
| - if(l_rc) |
| - { |
| - TS_FAIL("mm_set_permission: Cannot set permissions to write"); |
| - break; |
| - } |
| |
| // Corrupt page |
| uint8_t l_corruptByte = 0xFF; |
| @@ -410,16 +400,6 @@ class SecureRomManagerTest : public CxxTest::TestSuite |
| delete l_errl; |
| l_errl = nullptr; |
| |
| - // Reset to read-only permissions. |
| - l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr), |
| - 2*PAGESIZE, |
| - READ_ONLY); |
| - if(l_rc) |
| - { |
| - TS_FAIL("mm_set_permission: Cannot reset permissions to read only"); |
| - break; |
| - } |
| - |
| } while(0); |
| |
| if ( signedFile_pageAddr != nullptr ) |
| -- |
| 2.14.3 |
| |