summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/targeting/attrrp.H44
-rw-r--r--src/include/usr/targeting/common/target.H2
-rw-r--r--src/include/usr/targeting/common/targetservice.H64
-rw-r--r--src/include/usr/targeting/common/targreasoncodes.H1
-rwxr-xr-xsrc/usr/targeting/attrrp.C175
-rw-r--r--src/usr/targeting/common/targetservice.C173
-rw-r--r--src/usr/targeting/runtime/start_rt.C125
-rwxr-xr-xsrc/usr/targeting/targetservicestart.C28
8 files changed, 376 insertions, 236 deletions
diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H
index 0c6f1aa8d..bc9425007 100644
--- a/src/include/usr/targeting/attrrp.H
+++ b/src/include/usr/targeting/attrrp.H
@@ -49,6 +49,10 @@ namespace TARGETING
// Forward declaration of attribute section parsed information structure.
struct AttrRP_Section;
+// These constexprs are used by editPagePermissions function
+constexpr uint32_t DEFAULT_PERMISSIONS = 0xFFFFFFFF;
+constexpr uint8_t ALL_SECTION_TYPES = 0xFF;
+
#ifdef __HOSTBOOT_RUNTIME
/**
* @brief Structure used to store Node specific information
@@ -264,6 +268,46 @@ class AttrRP
static void init(errlHndl_t& io_taskRetErrl, bool i_isMpipl = false);
#ifndef __HOSTBOOT_RUNTIME
+
+ /**
+ * @brief Modifies the memory R/W permissions on VMM pages for a
+ * given type of AttrRP_Section. Valid types can be found
+ * in the generated file pnorheader.H. Valid permissions
+ * can be found in src/include/sys/mm.h . It was chosen to
+ * not use the enums to avoid needing to include the headers
+ * all over.
+ *
+ * @param[in] i_type The type of AttrRP_Section we want to apply the permission
+ * edits to. Valid options for the attrrp types are:
+ * SECTION_TYPE_PNOR_RO = 0x00
+ * SECTION_TYPE_PNOR_RW = 0x01
+ * SECTION_TYPE_HEAP_PNOR_INIT = 0x02
+ * SECTION_TYPE_HEAP_ZERO_INIT = 0x03
+ * SECTION_TYPE_HB_HEAP_ZERO_INIT = 0x0A
+ * ALL_SECTION_TYPES = 0xFF
+ *
+ * @param[in] i_permission The R/W permissions the user desires to apply to a
+ * given section. Note that values can be OR'ed
+ * together. Valid options are :
+ * READ_ONLY = 0x00000001
+ * WRITABLE = 0x00000002
+ * EXECUTABLE = 0x00000004
+ * WRITE_TRACKED = 0x00000008
+ * ALLOCATE_FROM_ZERO = 0x00000010
+ * NO_ALLOCATE_FROM_ZERO = 0x00000020
+ * NO_ACCESS = 0x00000040
+ * BYPASS_HRMOR = 0x00000080
+ * GUARDED = 0x00000100
+ * DEFAULT_PERMISSIONS = 0xFFFFFFFF
+ *
+ * @note If the value 0xFF is passed in for i_type then all types will
+ * get permissions updated to i_permission.
+ * If the value 0xFFFF is passed in for i_permission then the sections
+ * will have their R/W permissions set up to the default values given
+ * in PNOR
+ */
+ errlHndl_t editPagePermissions(uint8_t i_type, uint32_t i_permission);
+
/**
* @brief Copies all present attribute sections to memory.
*
diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H
index ab22a62bb..f462581de 100644
--- a/src/include/usr/targeting/common/target.H
+++ b/src/include/usr/targeting/common/target.H
@@ -61,7 +61,6 @@ namespace ERRORLOG
}
namespace RT_TARG
{
- void adjustTargeting4Runtime();
ERRORLOG::ErrlEntry* saveRestoreAttrs(void *i_rsvdMemPtr,
void *io_lidStructPtr,
uint8_t i_instance);
@@ -811,7 +810,6 @@ class Target
friend class AttributeTank;
#ifdef __HOSTBOOT_RUNTIME
- friend void RT_TARG::adjustTargeting4Runtime();
friend ERRORLOG::ErrlEntry* RT_TARG::saveRestoreAttrs(void *,
void *,
uint8_t);
diff --git a/src/include/usr/targeting/common/targetservice.H b/src/include/usr/targeting/common/targetservice.H
index 860a5564b..37bf6216e 100644
--- a/src/include/usr/targeting/common/targetservice.H
+++ b/src/include/usr/targeting/common/targetservice.H
@@ -563,6 +563,33 @@ class TargetService
void dump() const;
#ifndef __HOSTBOOT_RUNTIME
+
+ /**
+ * @brief This func changes the readOnly section of the targeting data
+ * to be writeable, allowing hostboot to update attributes that
+ * are read-only. After attributes are updated the user should
+ * toggle back to making the section readOnly
+ *
+ * This top level interface calls the lower level attribute resource
+ * provider interface to modify R/W permissions on the VMM pages it has
+ * mapped for each of the different sections of the targeting data. This
+ * function specifically provides a way to toggle the ability to write to
+ * the readOnly pages of the targeting data.
+ *
+ * @param[in] i_allowWrites If TRUE will change R/W permissions of readOnly
+ * targeting data to be writable
+ * If FALSE will change R/W permissions of readOnly
+ * targeting data to be readOnly
+ *
+ * @pre AttrRp must be initialized
+ *
+ * @post R/W permissions of the readOnly section of the targeting data will
+ * be modified depending on boolean parameter.
+ *
+ * @return Error handle holding any errors accrued during execution
+ */
+ errlHndl_t modifyReadOnlyPagePermissions(bool i_allowWrites);
+
/**
* @brief Updates the targeting/attribute section data with the
* specified vector parameters.
@@ -790,23 +817,46 @@ class TargetService
AttrRP *i_attrRP,
ATTRIBUTE_ID* &o_pAttrId,
AbstractPointer<void>* &o_ppAttrAddr);
+ /**
+ * @brief Update the address that PEER_TARGET points to for a given target
+ *
+ * @par Detailed Description:
+ * The PEER_TARGET attribute is a pointer to a target's peer. The location
+ * of the target changes when we transition from Hostboot<->HBRT. After
+ * transitioning to runtime, or if we perform an MPIPL this function needs
+ * to be run on all targets in order to insure any target with a PEER_TARGET
+ * attribute gets the PEER_TARGET's pointer looked up again and set to the
+ * new value.
+ *
+ * @param[in] i_pTarget pointer to target to update PEER_TARGET attr for
+ *
+ * @pre TargetService must be initialized.
+ *
+ * @post If the target passed in has a PEER_TARGET , its value will be updated
+ *
+ * @return TRUE if target was updated , FALSE if PEER_TARGET was not updated
+ */
+ bool updatePeerTarget( const Target* i_pTarget);
+
#ifdef __HOSTBOOT_MODULE
/**
- * @brief Reset all hostboot mutex attributes
+ * @brief Reset all hostboot mutex attributes on a given target
*
* @par Detailed Description:
- * Iterates through all targets and check each of their attributes to
- * see if they are of type hbmutex. If we find a mutex attribute we will
- * run mutex_init on it to reset it.
+ * Take in target and check each of its attributes to see if they are
+ * of type hbmutex. If we find a mutex attribute we will run mutex_init
+ * on it to reset it.
+ *
+ * @param[in] i_pTarget pointer to target to reset mutex attrs on
*
* @pre TargetService must be initialized.
* AttrRp must be initialized
*
- * @post All hb mutex attributes on all targets have been reset
+ * @post All hb mutex attributes on given target have been reset
*
- * @return void
+ * @return number of mutex attributes reset
*/
- void resetMutexAttributes();
+ uint32_t resetMutexAttributes( const Target* i_pTarget);
#endif
private:
diff --git a/src/include/usr/targeting/common/targreasoncodes.H b/src/include/usr/targeting/common/targreasoncodes.H
index 411d686cb..ddff835be 100644
--- a/src/include/usr/targeting/common/targreasoncodes.H
+++ b/src/include/usr/targeting/common/targreasoncodes.H
@@ -50,6 +50,7 @@ enum TargetingModuleId
TARG_APPLY_ATTR_OVER = 0x0A,
TARG_HANDLE_ENUM_CHECK_FAILURE = 0x0B,
TARG_HANDLE_RANGE_CHECK_FAILURE = 0x0C,
+ TARG_EDIT_PAGE_PERMISSIONS = 0x0D,
};
enum TargetingReasonCode
diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C
index defe5ceed..9ba04090a 100755
--- a/src/usr/targeting/attrrp.C
+++ b/src/usr/targeting/attrrp.C
@@ -101,6 +101,14 @@ namespace TARGETING
break;
}
+ // Now that the VMM blocks have been created we must set
+ // the appropriate R/W permissions
+ l_errl = this->editPagePermissions(ALL_SECTION_TYPES, DEFAULT_PERMISSIONS);
+ if (l_errl)
+ {
+ break;
+ }
+
// Spawn daemon thread.
task_create(&AttrRP::startMsgServiceTask, this);
@@ -649,69 +657,113 @@ namespace TARGETING
}
- errlHndl_t AttrRP::createVmmSections()
+ errlHndl_t AttrRP::editPagePermissions(uint8_t i_type, uint32_t i_permission)
{
errlHndl_t l_errl = NULL;
-
+ int rc;
+ uint32_t l_perm = i_permission;
do
{
- // Allocate message queue for VMM requests.
- iv_msgQ = msg_q_create();
-
- // register it so it can be discovered by istep 21 and thus allow
- // secure runtime preparation of persistent r/w attributes
- int rc = msg_q_register(iv_msgQ, ATTRRP_MSG_Q);
-
- assert(rc == 0, "Bug! Unable to register message queue");
-
// Create VMM block for each section, assign permissions.
for (size_t i = 0; i < iv_sectionCount; ++i)
{
- uint64_t l_perm = 0;
- switch(iv_sections[i].type)
+ if(i_permission == DEFAULT_PERMISSIONS)
{
- case SECTION_TYPE_PNOR_RO:
- l_perm = READ_ONLY;
- break;
-
- case SECTION_TYPE_PNOR_RW:
- l_perm = WRITABLE | WRITE_TRACKED;
- break;
+ switch(iv_sections[i].type)
+ {
+ case SECTION_TYPE_PNOR_RO:
+ l_perm = READ_ONLY;
+ break;
- case SECTION_TYPE_HEAP_PNOR_INIT:
- l_perm = WRITABLE;
- break;
+ case SECTION_TYPE_PNOR_RW:
+ l_perm = WRITABLE | WRITE_TRACKED;
+ break;
- case SECTION_TYPE_HEAP_ZERO_INIT:
- case SECTION_TYPE_HB_HEAP_ZERO_INIT:
- l_perm = WRITABLE | ALLOCATE_FROM_ZERO;
- break;
+ case SECTION_TYPE_HEAP_PNOR_INIT:
+ l_perm = WRITABLE;
+ break;
- default:
+ case SECTION_TYPE_HEAP_ZERO_INIT:
+ case SECTION_TYPE_HB_HEAP_ZERO_INIT:
+ l_perm = WRITABLE | ALLOCATE_FROM_ZERO;
+ break;
- /*@
- * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TARG_CREATE_VMM_SECTIONS
- * @reasoncode TARG_RC_UNHANDLED_ATTR_SEC_TYPE
- * @userdata1 Section type
- *
- * @devdesc Found unhandled attribute section type
- * @custdesc FW error, unexpected Attribute section type
- */
- const bool hbSwError = true;
- l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- TARG_CREATE_VMM_SECTIONS,
- TARG_RC_UNHANDLED_ATTR_SEC_TYPE,
- iv_sections[i].type,
- 0, hbSwError);
- break;
+ default:
+
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid TARG_EDIT_PAGE_PERMISSIONS
+ * @reasoncode TARG_RC_UNHANDLED_ATTR_SEC_TYPE
+ * @userdata1 Section type
+ *
+ * @devdesc Found unhandled attribute section type
+ * @custdesc FW error, unexpected Attribute section type
+ */
+ const bool hbSwError = true;
+ l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_EDIT_PAGE_PERMISSIONS,
+ TARG_RC_UNHANDLED_ATTR_SEC_TYPE,
+ iv_sections[i].type,
+ 0, hbSwError);
+ break;
+ }
+ }
+ if( i_type == ALL_SECTION_TYPES || i_type == iv_sections[i].type)
+ {
+ rc = mm_set_permission(reinterpret_cast<void*>(
+ iv_sections[i].vmmAddress),
+ iv_sections[i].size,
+ l_perm);
}
- if(l_errl)
+ if (rc)
{
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid TARG_EDIT_PAGE_PERMISSIONS
+ * @reasoncode TARG_RC_MM_PERM_FAIL
+ * @userdata1 vAddress attempting to allocate.
+ * @userdata2 (kernel-rc << 32) | (Permissions)
+ *
+ * @devdesc While attempting to set permissions on
+ * a virtual memory block for an attribute
+ * section, the kernel returned an error.
+ *
+ * @custdesc Kernel failed to set permissions on
+ * virtual memory block
+ */
+ const bool hbSwError = true;
+ l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_EDIT_PAGE_PERMISSIONS,
+ TARG_RC_MM_PERM_FAIL,
+ iv_sections[i].vmmAddress,
+ TWO_UINT32_TO_UINT64(rc, l_perm),
+ hbSwError);
break;
}
+ }
+ } while(0);
+ return l_errl;
+ }
+ errlHndl_t AttrRP::createVmmSections()
+ {
+ errlHndl_t l_errl = NULL;
+
+ do
+ {
+ // Allocate message queue for VMM requests.
+ iv_msgQ = msg_q_create();
+
+ // register it so it can be discovered by istep 21 and thus allow
+ // secure runtime preparation of persistent r/w attributes
+ int rc = msg_q_register(iv_msgQ, ATTRRP_MSG_Q);
+
+ assert(rc == 0, "Bug! Unable to register message queue");
+
+ // Create VMM block for each section, assign permissions.
+ for (size_t i = 0; i < iv_sectionCount; ++i)
+ {
int rc = 0;
msg_q_t l_msgQ = iv_msgQ;
@@ -750,8 +802,6 @@ namespace TARGETING
if(iv_sections[i].type == SECTION_TYPE_PNOR_RW)
{
- // TODO RTC:164480 For MPIPL we need to map the RW section
- // in real memory to virtual address of the section in PNOR
/*
* Register this memory range to be FLUSHed during
* a shutdown.
@@ -760,37 +810,6 @@ namespace TARGETING
reinterpret_cast<void*>(iv_sections[i].vmmAddress),
iv_sections[i].size,ATTR_PRIORITY);
}
-
- rc = mm_set_permission(reinterpret_cast<void*>(
- iv_sections[i].vmmAddress),
- iv_sections[i].size,
- l_perm);
-
- if (rc)
- {
- /*@
- * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TARG_CREATE_VMM_SECTIONS
- * @reasoncode TARG_RC_MM_PERM_FAIL
- * @userdata1 vAddress attempting to allocate.
- * @userdata2 (kernel-rc << 32) | (Permissions)
- *
- * @devdesc While attempting to set permissions on
- * a virtual memory block for an attribute
- * section, the kernel returned an error.
- *
- * @custdesc Kernel failed to set permissions on
- * virtual memory block
- */
- const bool hbSwError = true;
- l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
- TARG_CREATE_VMM_SECTIONS,
- TARG_RC_MM_PERM_FAIL,
- iv_sections[i].vmmAddress,
- TWO_UINT32_TO_UINT64(rc, l_perm),
- hbSwError);
- break;
- }
} // End iteration through each section
if(l_errl)
diff --git a/src/usr/targeting/common/targetservice.C b/src/usr/targeting/common/targetservice.C
index a92423a92..709e57560 100644
--- a/src/usr/targeting/common/targetservice.C
+++ b/src/usr/targeting/common/targetservice.C
@@ -54,6 +54,8 @@
#include <targeting/common/utilFilter.H>
#ifdef __HOSTBOOT_MODULE
+// System
+#include <sys/mm.h>
// Generated
#include <arch/pirformat.H>
@@ -1703,72 +1705,143 @@ uint32_t TargetService::getTargetAttributes(Target*i_target,
// Return the number of attributes for this target
return i_target->iv_attrs;
}
+
#ifdef __HOSTBOOT_MODULE
-void TargetService::resetMutexAttributes()
+
+#ifndef __HOSTBOOT_RUNTIME
+errlHndl_t TargetService::modifyReadOnlyPagePermissions(bool i_allowWrites)
{
- #define TARG_FN "resetMutexAttributes(...)"
+ #define TARG_FN "modifyReadOnlyPagePermissions(...)"
+ TARG_ENTER();
+ errlHndl_t l_errl = NULL;
TARGETING::AttrRP *l_pAttrRP = &TARG_GET_SINGLETON(TARGETING::theAttrRP);
- ATTRIBUTE_ID* l_pAttrIds = nullptr;
- AbstractPointer<void>* l_ppAttrAddrs = nullptr;
- for( auto targ_iter = targetService().begin();
- targ_iter != targetService().end();
- targ_iter++)
+ if(i_allowWrites)
{
- uint32_t l_attrCount = 0;
- Target* l_pTarget = *targ_iter;
- l_attrCount = targetService().getTargetAttributes(l_pTarget, l_pAttrRP,
- l_pAttrIds, l_ppAttrAddrs );
+ l_errl = l_pAttrRP->editPagePermissions(SECTION_TYPE_PNOR_RO, WRITABLE);
+ }
+ else
+ {
+ l_errl = l_pAttrRP->editPagePermissions(SECTION_TYPE_PNOR_RO, READ_ONLY);
+ }
+ TARG_EXIT();
+ #undef TARG_FN
+ return l_errl;
+}
+#endif
+
+bool TargetService::updatePeerTarget(const Target* i_pTarget)
+{
+ #define TARG_FN "updatePeerTarget(...)"
+ // Variable which holds return value
+ bool l_peerTargetUpdated = false;
+ do
+ {
+ TARGETING::Target * l_peer = static_cast<Target*>(NULL);
+ if(! i_pTarget->tryGetAttr<ATTR_PEER_TARGET>(l_peer))
+ {
+ // This is a normal path, many targets do not have PEERS
+ TRACDCOMP(g_trac_targeting, "No PEER_TARGET found for target 0x%x",
+ get_huid(i_pTarget));
+ // Skip the rest of the function in this case
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_targeting, "Initial PEER_TARGET address for HUID 0x%x found to be %p",
+ get_huid(i_pTarget), l_peer);
+ }
+
+ TARGETING::ATTR_PEER_PATH_type l_peerPath;
+ if(i_pTarget->tryGetAttr<ATTR_PEER_PATH>(l_peerPath))
+ {
+ // If we find a PEER_PATH we need to next look up the PEER_TARGET with toTarget
+ l_peer = targetService().toTarget(l_peerPath);
- // Make sure that attributes were found
- if(l_attrCount == 0)
+ // Make sure the path resolved to a non-null target
+ if (l_peer != NULL)
+ {
+ l_peerTargetUpdated = i_pTarget->_trySetAttr(ATTR_PEER_TARGET,
+ sizeof(l_peer),
+ &l_peer);
+ TRACFCOMP(g_trac_targeting, "Updated PEER_TARGET address for HUID 0x%x found to be %p",
+ get_huid(i_pTarget), l_peer);
+ }
+ else
+ {
+ // This is unexpected so make the trace visible, but no need to assert
+ TRACFCOMP(g_trac_targeting,
+ "PEER_PATH did not resolve to a valid target for the entity path %s",
+ l_peerPath.toString());
+ }
+ }
+ else
{
- TRACFCOMP( g_trac_targeting,
- "Target 0x%X has no attributes", get_huid(l_pTarget) );
- // Continue to next target if there were no attributes
- continue;
+ // This is unexpected so make the trace visible, but no need to assert
+ TRACFCOMP(g_trac_targeting,
+ "No PEER_PATH found for target 0x%x which does have a PEER_TARGET attribute",
+ get_huid(i_pTarget));
}
+ } while(0);
+
+ return l_peerTargetUpdated;
+ #undef TARG_FN
+}
- for ( uint32_t l_attrIndex = 0; l_attrIndex < l_attrCount; l_attrIndex++)
+uint32_t TargetService::resetMutexAttributes(const Target* i_pTarget)
+{
+ #define TARG_FN "resetMutexAttributes(...)"
+ TARGETING::AttrRP *l_pAttrRP = &TARG_GET_SINGLETON(TARGETING::theAttrRP);
+ ATTRIBUTE_ID* l_pAttrIds = nullptr;
+ AbstractPointer<void>* l_ppAttrAddrs = nullptr;
+ uint32_t l_numberMutexAttrsReset = 0;
+ uint32_t l_attrCount = 0;
+ l_attrCount = targetService().getTargetAttributes(const_cast<TARGETING::Target*>(i_pTarget),
+ l_pAttrRP,
+ l_pAttrIds,
+ l_ppAttrAddrs );
+
+ for ( uint32_t l_attrIndex = 0; l_attrIndex < l_attrCount; l_attrIndex++)
+ {
+ const ATTRIBUTE_ID l_attrId = l_pAttrIds[l_attrIndex];
+ for( const auto mutexId : hbMutexAttrIds)
{
- const ATTRIBUTE_ID l_attrId = l_pAttrIds[l_attrIndex];
- for( const auto mutexId : hbMutexAttrIds)
+ if(l_attrId == mutexId)
{
- if(l_attrId == mutexId)
+ mutex_t* l_mutex;
+ if(i_pTarget->_tryGetHbMutexAttr(l_attrId, l_mutex))
{
- mutex_t* l_mutex;
- if(l_pTarget->_tryGetHbMutexAttr(l_attrId, l_mutex))
- {
- mutex_init(l_mutex);
- }
- else
- {
- /*@
- * @errortype ERRORLOG::ERRL_SEV_PREDICTIVE
- * @moduleid TARG_SVC_RESET_MUTEX
- * @reasoncode TARG_SVC_MISSING_ATTR
- * @userdata1 Attribute Id we attempted to read
- * @userdata2 Huid of target we attempted to read
- *
- * @devdesc For some reason attr IDs in hbMutexAttrIds list
- * are not matching the attribute IDs that target
- * service is seeing. This is causing incorrect matching
- * Make sure mutexattribute.H in genfiles has good values
- *
- * @custdesc Attempted to perform an invalid attribute look up
- */
- errlHndl_t l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
- TARG_SVC_RESET_MUTEX,
- TARG_SVC_MISSING_ATTR,
- l_attrId,
- get_huid(l_pTarget),
- true); // software error
- errlCommit(l_errl, TARG_COMP_ID);
- }
+ mutex_init(l_mutex);
+ l_numberMutexAttrsReset++;
+ }
+ else
+ {
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid TARG_SVC_RESET_MUTEX
+ * @reasoncode TARG_SVC_MISSING_ATTR
+ * @userdata1 Attribute Id we attempted to read
+ * @userdata2 Huid of target we attempted to read
+ *
+ * @devdesc For some reason attr IDs in hbMutexAttrIds list
+ * are not matching the attribute IDs that target
+ * service is seeing. This is causing incorrect matching
+ * Make sure mutexattribute.H in genfiles has good values
+ *
+ * @custdesc Attempted to perform an invalid attribute look up
+ */
+ errlHndl_t l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ TARG_SVC_RESET_MUTEX,
+ TARG_SVC_MISSING_ATTR,
+ l_attrId,
+ get_huid(i_pTarget),
+ true); // software error
+ errlCommit(l_errl, TARG_COMP_ID);
}
}
}
}
#undef TARG_FN
+ return l_numberMutexAttrsReset;
}
#endif
diff --git a/src/usr/targeting/runtime/start_rt.C b/src/usr/targeting/runtime/start_rt.C
index ea99db972..d3edf9cb3 100644
--- a/src/usr/targeting/runtime/start_rt.C
+++ b/src/usr/targeting/runtime/start_rt.C
@@ -33,7 +33,7 @@ using namespace TARGETING;
namespace RT_TARG
{
- void adjustTargeting4Runtime();
+ void adjustTargetingForRuntime();
static void initTargeting() __attribute__((constructor));
static void initTargeting()
@@ -50,17 +50,14 @@ namespace RT_TARG
TargetService& l_targetService = targetService();
l_targetService.init(Singleton<AttrRP>::instance().getNodeCount());
- // Reset hb mutex attributes in case they got stuck in a locked state
- l_targetService.resetMutexAttributes();
-
- adjustTargeting4Runtime();
+ adjustTargetingForRuntime();
// set global that TARG is ready
Util::setIsTargetingLoaded();
}
// Make any adjustments needed to targeting for runtime
- void adjustTargeting4Runtime()
+ void adjustTargetingForRuntime()
{
TRACDCOMP(g_trac_targeting,"adjustTargeting4Runtime");
@@ -77,109 +74,41 @@ namespace RT_TARG
// was at IPL. Using this "old" address would seg fault at run time.
// The value of the ATTR_PEER_TARGET attributes must be translated
// for run time.
- // The _trySetAttr is used directly to avoid the trySetAttr template
- // error check that ATTR_PEER_TARGET is only readable, not writable.
- // adjustTargeting4Runtime has been included as a friend to allow
- // access to the private target class methods.
- size_t l_xlateCnt = 0;
- uint8_t l_maxNodeId =
- TARGETING::targetService().getNumInitializedNodes();
+
+ // Also in this function we will reset any mutex attributes we find
+ // on any target incase they got left in the locked state when hostboot
+ // passed the payload to the hypervisor.
+
+ TargetService& l_targetService = targetService();
+ size_t l_updatedCount = 0;
+ uint32_t l_numberMutexAttrsReset = 0;
+ uint8_t l_maxNodeId = l_targetService.getNumInitializedNodes();
for(uint8_t l_nodeId = NODE0; l_nodeId < l_maxNodeId; ++l_nodeId)
{
- for (TargetIterator target = targetService().begin(l_nodeId);
- target != targetService().end();
- ++target)
+ for (TargetIterator target = l_targetService.begin(l_nodeId);
+ target != l_targetService.end();
+ ++target)
{
const TARGETING::Target * l_target = *target;
- TARGETING::Target * l_peer = static_cast<Target*>(NULL);
- bool l_hasPeer = l_target->tryGetAttr<ATTR_PEER_TARGET>(l_peer);
- if (l_hasPeer && (l_peer != nullptr))
- {
- TRACDCOMP(g_trac_targeting,
- "translate the peer target %p for HUID %x",
- l_peer, get_huid(l_target));
+ // Check if there any mutex attributes we need to reset on this target
+ l_numberMutexAttrsReset += l_targetService.resetMutexAttributes(l_target);
- ATTR_PEER_TARGET_type l_xlated = (TARGETING::Target *)
- Singleton<AttrRP>::instance().
- AttrRP::translateAddr(l_peer,l_target);
- bool l_fixed = false;
- l_fixed = l_target->_trySetAttr(ATTR_PEER_TARGET,
- sizeof(l_xlated),
- &l_xlated);
- if (l_fixed)
- {
- TRACDCOMP(g_trac_targeting, " to=%p", l_xlated);
- l_xlateCnt++;
- }
- // Not good if could not be fixed. But might not be
- // referenced. A segment fault will occur if used.
- else
- {
- TRACFCOMP(g_trac_targeting,
- "failed to translate peer target for HUID=0x%x",
- get_huid(l_target));
- }
- }
- else if(l_hasPeer && l_peer == nullptr)
+ // Check if there is any PEER_TARAGET attribute to update on this target
+ if(l_targetService.updatePeerTarget(l_target))
{
- TRACDCOMP(g_trac_targeting,
- "looking up peer path and target for HUID %x",
- get_huid(l_target));
- // Create variables entity path variable to write PEER_PATH into
- // as well as a Target pointer to set once we get the PEER_PATH
- TARGETING::EntityPath l_peerPath;
- TARGETING::Target * l_newTargPtr;
-
- // Look up the PEER_PATH attribute if it exists on the target
- bool l_hasPeerPath = l_target->tryGetAttr<ATTR_PEER_PATH>(l_peerPath);
-
- //If we find a PEER_PATH we need to next look up the PEER_TARGET
- if(l_hasPeerPath)
- {
- TRACDCOMP(g_trac_targeting,
- "Found peer path for HUID %x",get_huid(l_target));
- // Look up the PEER_TARGET based on what the PEER_PATH is
- l_newTargPtr = targetService().toTarget(l_peerPath);
-
- bool l_fixed = false;
-
- // If the pointer returned from toTarget isn't null then
- // we will try to set PEER_TARGET with that value
- if(l_newTargPtr != nullptr)
- {
- l_fixed = l_target->_trySetAttr(ATTR_PEER_TARGET,
- sizeof(l_newTargPtr),
- &l_newTargPtr);
- }
-
- if (l_fixed)
- {
- TRACDCOMP(g_trac_targeting, "Peer target for HUID %x found to be %p",
- get_huid(l_target), l_newTargPtr);
- l_xlateCnt++;
- }
- // Not good if could not be fixed. But might not be
- // referenced. A segment fault will occur if used.
- else
- {
- TRACFCOMP(g_trac_targeting,
- "failed to find peer target for HUID=0x%x",
- get_huid(l_target));
- }
- }
- else
- {
- TRACFCOMP(g_trac_targeting,
- "Failed to find peer path for HUID=0x%x",
- get_huid(l_target));
- }
+ l_updatedCount++;
}
}
}
TRACFCOMP(g_trac_targeting,
- "adjustTargeting4Runtime: %d peer target addresses "
+ "adjustTargetingForRuntime: %d peer target addresses "
"translated on %d nodes",
- l_xlateCnt,
+ l_updatedCount,
+ l_maxNodeId);
+ TRACFCOMP(g_trac_targeting,
+ "adjustTargetingForRuntime: %d mutex attributes reset "
+ "on %d nodes",
+ l_numberMutexAttrsReset,
l_maxNodeId);
}
}
diff --git a/src/usr/targeting/targetservicestart.C b/src/usr/targeting/targetservicestart.C
index 00393b017..5b7e639dd 100755
--- a/src/usr/targeting/targetservicestart.C
+++ b/src/usr/targeting/targetservicestart.C
@@ -194,7 +194,33 @@ static void initTargeting(errlHndl_t& io_pError)
//Ensure all mutex attributes are reset on MPIPL
if(l_isMpipl)
{
- l_targetService.resetMutexAttributes();
+ // updatePeerTargets will write to read-only attribute pages
+ // to get around vmm fails we need to allow writes to readonly
+ // memory for the duration of this loop
+ l_targetService.modifyReadOnlyPagePermissions(true);
+ uint32_t l_peerTargetsAdjusted = 0;
+ uint32_t l_numberMutexAttrsReset = 0;
+ for( auto targ_iter = l_targetService.begin();
+ targ_iter != l_targetService.end();
+ targ_iter++)
+ {
+ const Target* l_pTarget = *targ_iter;
+ // Check if there any mutex attributes we need to reset on this target
+ l_numberMutexAttrsReset += l_targetService.resetMutexAttributes(l_pTarget);
+
+ // Update any peer target addresses if necessary
+ if(l_targetService.updatePeerTarget(l_pTarget))
+ {
+ l_peerTargetsAdjusted++;
+ }
+ }
+ // Now that the loop is complete we can re-apply
+ // the read only permissions to the read only attr pages
+ l_targetService.modifyReadOnlyPagePermissions(false);
+ TARG_INF("Number of peer target addresses adjusted: %d",
+ l_peerTargetsAdjusted);
+ TARG_INF("Number of mutex attributes reset: %d",
+ l_numberMutexAttrsReset);
}
checkProcessorTargeting(l_targetService);
OpenPOWER on IntegriCloud