Stewart Smith | 99be97f | 2018-04-18 04:40:44 -0500 | [diff] [blame^] | 1 | From 3dba59d5b60a9ad307b91d4063279cb1535cda8f Mon Sep 17 00:00:00 2001 |
| 2 | From: Stewart Smith <stewart@linux.ibm.com> |
| 3 | Date: Wed, 18 Apr 2018 17:06:09 +1000 |
| 4 | Subject: [PATCH] Revert "Mark Read-Only Partitions as Such" |
| 5 | |
| 6 | This reverts commit f5cd23d6c3be17356e0851ec5d5bb65cee48f15f. |
| 7 | |
| 8 | Only changing the presence of this commit, we go from failing to boot |
| 9 | (error below) to being able to boot. |
| 10 | |
| 11 | 24.41069|ISTEP 10. 2 - host_slave_sbe_update |
| 12 | 24.44213|System shutting down with error status 0x90000012 |
| 13 | 24.45270|================================================ |
| 14 | 24.45420|Error reported by initservice (0x0500) PLID 0x90000012 |
| 15 | 24.45422| Initialization Service launched a function and |
| 16 | the task returned an error. |
| 17 | 24.45423| ModuleId 0x01 BASE_INITSVC_MOD_ID |
| 18 | 24.45573| ReasonCode 0x0506 WAIT_FN_FAILED |
| 19 | 24.45574| UserData1 task id or task return code : 0x00000000000000ec |
| 20 | 24.45574| UserData2 returned status from task : 0x0000000000000001 |
| 21 | 24.45575|------------------------------------------------ |
| 22 | 24.45875| Callout type : Procedure Callout |
| 23 | 24.45876| Procedure : EPUB_PRC_HB_CODE |
| 24 | 24.45876| Priority : SRCI_PRIORITY_HIGH |
| 25 | 24.45877|------------------------------------------------ |
| 26 | 24.45878| host_slave_sbe_update |
| 27 | 24.45878|------------------------------------------------ |
| 28 | 24.45879| Hostboot Build ID: |
| 29 | 24.45879|================================================ |
| 30 | |
| 31 | Change-Id: I7ac38afc8bed608d6272f1ef6f099e3fc03bb270 |
| 32 | Signed-off-by: Stewart Smith <stewart@linux.ibm.com> |
| 33 | --- |
| 34 | src/include/usr/pnor/pnor_reasoncodes.H | 1 - |
| 35 | src/usr/pnor/pnorrp.C | 15 +- |
| 36 | src/usr/pnor/test/pnorrptest.H | 188 ++++++++---------------- |
| 37 | src/usr/secureboot/base/test/securerommgrtest.H | 20 --- |
| 38 | 4 files changed, 71 insertions(+), 153 deletions(-) |
| 39 | |
| 40 | diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H |
| 41 | index 2835f8a153d0..4dd2ef1c43de 100644 |
| 42 | --- a/src/include/usr/pnor/pnor_reasoncodes.H |
| 43 | +++ b/src/include/usr/pnor/pnor_reasoncodes.H |
| 44 | @@ -187,7 +187,6 @@ namespace PNOR |
| 45 | RC_SECURE_SIZE_MISMATCH = PNOR_COMP_ID | 0x3A, |
| 46 | RC_NOT_PAGE_ALIGNED = PNOR_COMP_ID | 0x3B, |
| 47 | RC_SECURE_PRO_SIZE_MISMATCH = PNOR_COMP_ID | 0x3C, |
| 48 | - RC_READ_ONLY_PERM_FAIL = PNOR_COMP_ID | 0x3D, |
| 49 | |
| 50 | //@fixme-RTC:131607-Temporary value to allow HWSV compile |
| 51 | //termination_rc |
| 52 | diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C |
| 53 | index df88ba821b70..e33a1b0c377c 100644 |
| 54 | --- a/src/usr/pnor/pnorrp.C |
| 55 | +++ b/src/usr/pnor/pnorrp.C |
| 56 | @@ -1776,31 +1776,32 @@ errlHndl_t PnorRP::setVirtAddrs(void) |
| 57 | // Handle section permissions |
| 58 | if (iv_TOC[i].misc & FFS_MISC_READ_ONLY) |
| 59 | { |
| 60 | - // Partitions marked with readOnly flag should be |
| 61 | - // READ_ONLY and not WRITABLE. |
| 62 | + // Need to set permissions to allow writing to virtual |
| 63 | + // addresses, but prevents the kernel from ejecting |
| 64 | + // dirty pages (no WRITE_TRACKED). |
| 65 | int rc = mm_set_permission( |
| 66 | (void*)iv_TOC[i].virtAddr, |
| 67 | iv_TOC[i].size, |
| 68 | - READ_ONLY); |
| 69 | + WRITABLE); |
| 70 | if (rc) |
| 71 | { |
| 72 | - TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to READ_ONLY for section %s.", |
| 73 | + TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to WRITABLE for section %s.", |
| 74 | SectionIdToString(i)); |
| 75 | /*@ |
| 76 | * @errortype |
| 77 | * @moduleid PNOR::MOD_PNORRP_READTOC |
| 78 | - * @reasoncode PNOR::RC_READ_ONLY_PERM_FAIL |
| 79 | + * @reasoncode PNOR::RC_WRITABLE_PERM_FAIL |
| 80 | * @userdata1 PNOR section id |
| 81 | * @userdata2 PNOR section vaddr |
| 82 | * @devdesc Could not set permissions of the |
| 83 | - * given PNOR section to READ_ONLY |
| 84 | + * given PNOR section to WRITABLE |
| 85 | * @custdesc A problem occurred while reading |
| 86 | * Processor NOR flash partition table |
| 87 | */ |
| 88 | l_errhdl = new ERRORLOG::ErrlEntry( |
| 89 | ERRORLOG::ERRL_SEV_UNRECOVERABLE, |
| 90 | PNOR::MOD_PNORRP_READTOC, |
| 91 | - PNOR::RC_READ_ONLY_PERM_FAIL, |
| 92 | + PNOR::RC_WRITABLE_PERM_FAIL, |
| 93 | i, |
| 94 | iv_TOC[i].virtAddr, |
| 95 | true /*Add HB SW Callout*/); |
| 96 | diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H |
| 97 | index 5108840f5040..942eff9abdff 100644 |
| 98 | --- a/src/usr/pnor/test/pnorrptest.H |
| 99 | +++ b/src/usr/pnor/test/pnorrptest.H |
| 100 | @@ -5,7 +5,7 @@ |
| 101 | /* */ |
| 102 | /* OpenPOWER HostBoot Project */ |
| 103 | /* */ |
| 104 | -/* Contributors Listed Below - COPYRIGHT 2011,2018 */ |
| 105 | +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ |
| 106 | /* [+] Google Inc. */ |
| 107 | /* [+] International Business Machines Corp. */ |
| 108 | /* */ |
| 109 | @@ -39,7 +39,6 @@ |
| 110 | #include <sys/msg.h> |
| 111 | #include <limits.h> |
| 112 | #include <sys/mm.h> |
| 113 | -#include <sys/task.h> |
| 114 | #include <targeting/common/targetservice.H> |
| 115 | #include <devicefw/userif.H> |
| 116 | #include <config.h> |
| 117 | @@ -626,53 +625,82 @@ class PnorRpTest : public CxxTest::TestSuite |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | - * @brief PNOR RP test - read_ReadOnly_partition |
| 122 | - * Tests if we can read a readOnly partition |
| 123 | + * @brief PNOR RP test - ReadOnlyTag |
| 124 | + * Tests if readOnly tag on a section is being processed correctly |
| 125 | * |
| 126 | */ |
| 127 | - void test_read_ReadOnly_partition(void) |
| 128 | + void test_ReadOnlyTag(void) |
| 129 | { |
| 130 | - TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition Start"); |
| 131 | - |
| 132 | - int l_status = TASK_STATUS_EXITED_CLEAN; |
| 133 | - PNOR::SectionId l_testroSecId = PNOR::TESTRO; |
| 134 | - tid_t l_childTask = |
| 135 | - task_create(readFromReadOnlyPartition, &l_testroSecId); |
| 136 | + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag Start" ); |
| 137 | + PNOR::SectionInfo_t l_info; |
| 138 | + errlHndl_t l_errhdl = NULL; |
| 139 | + uint64_t chip_select = 0xF; |
| 140 | + bool needs_ecc = false; |
| 141 | |
| 142 | - if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) || |
| 143 | - (l_status != TASK_STATUS_EXITED_CLEAN)) |
| 144 | + l_errhdl = PNOR::getSectionInfo(PNOR::TESTRO, l_info); |
| 145 | + if( l_errhdl ) |
| 146 | { |
| 147 | - TS_FAIL("Could not read from readOnly partition."); |
| 148 | + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : getSectionInfo returned error for %d : RC=%X", |
| 149 | + PNOR::TESTRO, l_errhdl->reasonCode()); |
| 150 | + ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| 151 | + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : could not read pnor section %d", PNOR::TESTRO); |
| 152 | } |
| 153 | - TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition End"); |
| 154 | - } |
| 155 | |
| 156 | - /** |
| 157 | - * @brief PNOR RP test - write_ReadOnly_partition |
| 158 | - * Tests if we can write to a readOnly partition (fail expected) |
| 159 | - * |
| 160 | - */ |
| 161 | - void test_write_ReadOnly_partition(void) |
| 162 | - { |
| 163 | - TRACFCOMP(g_trac_pnor, |
| 164 | - "PnorRpTest::test_write_ReadOnly_partition Start"); |
| 165 | + // Write some data |
| 166 | + const uint64_t l_writeData = 0x1122334455667788; |
| 167 | + uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr); |
| 168 | + l_dataptr[0] = l_writeData; |
| 169 | |
| 170 | - int l_status = TASK_STATUS_EXITED_CLEAN; |
| 171 | - PNOR::SectionId l_testroSecId = PNOR::TESTRO; |
| 172 | + // Flush the page to make sure it gets out to the device |
| 173 | + // Due to ReadOnly permissions set on TESTRO should be a no-op |
| 174 | + int rc = mm_remove_pages( RELEASE, l_dataptr, PAGESIZE ); |
| 175 | + if( rc ) |
| 176 | + { |
| 177 | + TRACFCOMP( g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE : rc=%X", rc ); |
| 178 | + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE" ); |
| 179 | + } |
| 180 | |
| 181 | - printk("Test case: Expect to see uncaught exception! "); |
| 182 | - tid_t l_childTask = |
| 183 | - task_create(writeToReadOnlyPartition, &l_testroSecId); |
| 184 | + // Get physical address of pnor section |
| 185 | + uint64_t l_address = 0; |
| 186 | + l_errhdl = PnorRP::getInstance().computeDeviceAddr((void*)l_info.vaddr, |
| 187 | + l_address, |
| 188 | + chip_select, |
| 189 | + needs_ecc); |
| 190 | + if(l_errhdl) |
| 191 | + { |
| 192 | + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr); |
| 193 | + errlCommit(l_errhdl,PNOR_COMP_ID); |
| 194 | + TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr); |
| 195 | + } |
| 196 | |
| 197 | - if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) || |
| 198 | - (l_status != TASK_STATUS_CRASHED)) |
| 199 | + // Read pnor section and check if write did not occur |
| 200 | + uint64_t l_readData = 0; |
| 201 | + size_t l_size = sizeof(uint64_t); |
| 202 | + l_errhdl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, |
| 203 | + &l_readData, |
| 204 | + l_size, |
| 205 | + DEVICE_PNOR_ADDRESS(0, l_address)); |
| 206 | + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> Read Data = 0x%X",l_readData); |
| 207 | + if(l_errhdl) |
| 208 | { |
| 209 | - TS_FAIL("Write to readOnly partition exception not caught."); |
| 210 | + TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() failed! Error committed."); |
| 211 | + ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| 212 | + } |
| 213 | + if(l_readData == l_writeData) |
| 214 | + { |
| 215 | + TS_FAIL("PnorRpTest::test_ReadOnlyTag: Data was written to readOnly section = %s", |
| 216 | + l_info.name); |
| 217 | + } |
| 218 | + if(l_size != sizeof(uint64_t)) |
| 219 | + { |
| 220 | + TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d", |
| 221 | + l_address, sizeof(uint64_t), l_size); |
| 222 | } |
| 223 | |
| 224 | - TRACFCOMP(g_trac_pnor, "PnorRpTest::test_write_ReadOnly_partition End"); |
| 225 | + TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag End"); |
| 226 | } |
| 227 | |
| 228 | + |
| 229 | //@todo - import config data from build and compare to section info |
| 230 | |
| 231 | /** |
| 232 | @@ -885,97 +913,7 @@ class PnorRpTest : public CxxTest::TestSuite |
| 233 | |
| 234 | } while (0); |
| 235 | #endif |
| 236 | - } |
| 237 | - |
| 238 | - private: |
| 239 | - static void* readFromReadOnlyPartition(void* i_section) |
| 240 | - { |
| 241 | - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition Start"); |
| 242 | - PNOR::SectionId* l_section = |
| 243 | - reinterpret_cast<PNOR::SectionId*>(i_section); |
| 244 | - PNOR::SectionInfo_t l_info; |
| 245 | - errlHndl_t l_errhdl = nullptr; |
| 246 | - |
| 247 | - do { |
| 248 | - |
| 249 | - if(isEnforcedSecureSection(*l_section)) |
| 250 | - { |
| 251 | - TS_FAIL("readFromReadOnlyPartition: section %d is secure." |
| 252 | - " readFromReadOnlyPartition does not support testing" |
| 253 | - " secure sections.", *l_section); |
| 254 | - break; |
| 255 | - } |
| 256 | - |
| 257 | - l_errhdl = PNOR::getSectionInfo(*l_section, l_info); |
| 258 | - if(l_errhdl) |
| 259 | - { |
| 260 | - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition: getSectionInfo " |
| 261 | - " returned an error for section %d : RC = 0x%.04x", |
| 262 | - *l_section, l_errhdl->reasonCode()); |
| 263 | - ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| 264 | - TS_FAIL("readFromReadOnlyPartition: failed to getSectionInfo" |
| 265 | - " for section %d", *l_section); |
| 266 | - break; |
| 267 | - } |
| 268 | - |
| 269 | - uint64_t l_data = 0; |
| 270 | - memcpy(&l_data, (void*)l_info.vaddr, sizeof(l_data)); |
| 271 | - // For this testing purpose, it doesn't actually matter what the data is |
| 272 | - } while(0); |
| 273 | - TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition End"); |
| 274 | - return nullptr; |
| 275 | - } |
| 276 | - |
| 277 | - static void* writeToReadOnlyPartition(void* i_section) |
| 278 | - { |
| 279 | - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition Start"); |
| 280 | - PNOR::SectionId* l_section = |
| 281 | - reinterpret_cast<PNOR::SectionId*>(i_section); |
| 282 | - PNOR::SectionInfo_t l_info; |
| 283 | - errlHndl_t l_errhdl = nullptr; |
| 284 | - |
| 285 | - do { |
| 286 | - |
| 287 | - if(isEnforcedSecureSection(*l_section)) |
| 288 | - { |
| 289 | - TS_FAIL("writeToReadOnlyPartition: section %d is secure." |
| 290 | - " writeToReadOnlyPartition does not support testing secure" |
| 291 | - " sections.", *l_section); |
| 292 | - break; |
| 293 | - } |
| 294 | - |
| 295 | - l_errhdl = PNOR::getSectionInfo(*l_section, l_info); |
| 296 | - if(l_errhdl) |
| 297 | - { |
| 298 | - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition:" |
| 299 | - " getSectionInfo returned" |
| 300 | - " an error for section %d : RC=0x%.04x", |
| 301 | - *l_section, l_errhdl->reasonCode()); |
| 302 | - ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID); |
| 303 | - TS_FAIL("writeToReadOnlyPartition: could not read pnor section %d", |
| 304 | - *l_section); |
| 305 | - break; |
| 306 | - } |
| 307 | - |
| 308 | - // Write some data; should cause a task crash |
| 309 | - const uint64_t l_writeData = 0x1122334455667788; |
| 310 | - uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr); |
| 311 | - l_dataptr[0] = l_writeData; |
| 312 | - |
| 313 | - int rc = mm_remove_pages(RELEASE, l_dataptr, PAGESIZE); |
| 314 | - if(!rc) |
| 315 | - { |
| 316 | - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition : uncaught " |
| 317 | - "exception - write to a readOnly partition succeeded"); |
| 318 | - TS_FAIL("writeToReadOnlyPartition : no error returned on writing to" |
| 319 | - " a readOnly partition"); |
| 320 | - break; |
| 321 | - } |
| 322 | - |
| 323 | - } while(0); |
| 324 | - TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition End"); |
| 325 | - return nullptr; |
| 326 | - } |
| 327 | + } |
| 328 | }; |
| 329 | |
| 330 | |
| 331 | diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H |
| 332 | index 35e70f707598..8ffa8375daff 100644 |
| 333 | --- a/src/usr/secureboot/base/test/securerommgrtest.H |
| 334 | +++ b/src/usr/secureboot/base/test/securerommgrtest.H |
| 335 | @@ -380,16 +380,6 @@ class SecureRomManagerTest : public CxxTest::TestSuite |
| 336 | - VFS::VfsRp::getInstance().iv_unprotectedOffset |
| 337 | + l_vaddr; |
| 338 | memcpy(l_originPage, reinterpret_cast<uint8_t*>(l_pnorVaddr), PAGESIZE); |
| 339 | - // Open the write permissions to allow the test to temporarily corrupt |
| 340 | - // the partition. |
| 341 | - int l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr), |
| 342 | - 2*PAGESIZE, |
| 343 | - WRITABLE); |
| 344 | - if(l_rc) |
| 345 | - { |
| 346 | - TS_FAIL("mm_set_permission: Cannot set permissions to write"); |
| 347 | - break; |
| 348 | - } |
| 349 | |
| 350 | // Corrupt page |
| 351 | uint8_t l_corruptByte = 0xFF; |
| 352 | @@ -410,16 +400,6 @@ class SecureRomManagerTest : public CxxTest::TestSuite |
| 353 | delete l_errl; |
| 354 | l_errl = nullptr; |
| 355 | |
| 356 | - // Reset to read-only permissions. |
| 357 | - l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr), |
| 358 | - 2*PAGESIZE, |
| 359 | - READ_ONLY); |
| 360 | - if(l_rc) |
| 361 | - { |
| 362 | - TS_FAIL("mm_set_permission: Cannot reset permissions to read only"); |
| 363 | - break; |
| 364 | - } |
| 365 | - |
| 366 | } while(0); |
| 367 | |
| 368 | if ( signedFile_pageAddr != nullptr ) |
| 369 | -- |
| 370 | 2.14.3 |
| 371 | |