summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorDean Sanner <dsanner@us.ibm.com>2018-02-15 07:04:43 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2018-02-16 10:02:29 -0500
commit1eac1bea6c0960e47d3929f519cbb78071e40b7f (patch)
tree72ad4a39fa44534a8e896fcf1c4583b65b1a3102 /src/kernel
parentfe7571698e857cdcafceac0f120e66293892d00e (diff)
downloadtalos-hostboot-1eac1bea6c0960e47d3929f519cbb78071e40b7f.tar.gz
talos-hostboot-1eac1bea6c0960e47d3929f519cbb78071e40b7f.zip
Close race condition in multi instance IPC
P9 Doorbells operate differently than P8 IPI mechanism, creating a race condition. Basically because the HB kernel turns a doorbell into a message, and then is ready for another one -- it can lose the next one since repeated messages with same key are dropped (IPC handling clears memory comm area, other HB instances notice, fill and drop a doorbell before getting back into kernel) Change-Id: I8eb6f010600afb9de365c8942fcd24227903436f Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/54118 Reviewed-by: Prachi Gupta <pragupta@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: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/intmsghandler.C17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/kernel/intmsghandler.C b/src/kernel/intmsghandler.C
index b4b5254a7..805b0d761 100644
--- a/src/kernel/intmsghandler.C
+++ b/src/kernel/intmsghandler.C
@@ -37,6 +37,7 @@ const char* VFS_ROOT_MSG_INTR = "/msg/interrupt";
InterruptMsgHdlr * InterruptMsgHdlr::cv_instance = NULL;
uint64_t InterruptMsgHdlr::cv_ipc_base_address = 0;
+uint64_t InterruptMsgHdlr::cv_ipc_salt = 0;
void InterruptMsgHdlr::create(MessageQueue * i_msgQ, uint64_t i_ipc_addr)
{
@@ -193,9 +194,19 @@ void InterruptMsgHdlr::sendIpcMsg(uint64_t i_pir)
{
if(cv_instance)
{
- // To avoid conflict with interrupts on thread i_pir, change the key
- // for the message to be an invalid PIR.
- uint64_t pir_key = i_pir | MSG_KEY_IPC_MSG;
+ //Note that due to how IPC works between independent HB
+ //Instances, their is a race between when the data area
+ //"lock" is released and when the doorbell handled response
+ //is sent back to the kernel. Basically the other instances
+ //pounce on the data area as soon as it is unlocked, and
+ //a duplicate doorbell happens before kernel clears first
+ //message.
+ //Since the kernel will drop any message with the same PIR
+ //key on the floor, need to make it unique with a incrementing
+ //counter
+
+ cv_ipc_salt += MSG_IPC_SALT;
+ uint64_t pir_key = i_pir | MSG_KEY_IPC_MSG | cv_ipc_salt;
cv_instance->iv_lock.lock();
cv_instance->sendMessage(MSG_INTR_IPC,
OpenPOWER on IntegriCloud