diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2017-06-20 14:23:55 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-06-21 17:07:20 +1000 |
commit | c74e88e8614de0a82cba5c30812d5aa39db747a9 (patch) | |
tree | bd767d6b2ae68b5b4b523b1a8402becfce561202 /hw | |
parent | 23d759f80925d65fd59c16552467c85cc2c5090f (diff) | |
download | skiboot-c74e88e8614de0a82cba5c30812d5aa39db747a9.zip skiboot-c74e88e8614de0a82cba5c30812d5aa39db747a9.tar.gz skiboot-c74e88e8614de0a82cba5c30812d5aa39db747a9.tar.bz2 |
FSP: Add check to detect FSP R/R inside fsp_sync_msg()
OPAL sends MBOX message to FSP and updates message state from fsp_msg_queued
-> fsp_msg_sent. fsp_sync_msg() queues message and waits until we get response
from FSP. During FSP R/R we move outstanding MBOX messages from msgq to rr_queue
including inflight message (fsp_reset_cmdclass()). But we are not resetting
inflight message state.
In extreme croner case where we sent message to FSP via fsp_sync_msg() path
and FSP R/R happens before getting respose from FSP, then we will endup waiting
in fsp_sync_msg() until everything becomes normal.
This patch adds fsp_in_rr() check to fsp_sync_msg() and return error to caller
if FSP is in R/R.
CC: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/fsp/fsp.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c index 4c888c8..4d17397 100644 --- a/hw/fsp/fsp.c +++ b/hw/fsp/fsp.c @@ -282,9 +282,8 @@ void fsp_cancelmsg(struct fsp_msg *msg) { bool need_unlock = false; struct fsp_cmdclass* cmdclass = fsp_get_cmdclass(msg); - struct fsp *fsp = fsp_get_active(); - if (fsp->state != fsp_mbx_rr) { + if (!fsp_in_rr()) { prerror("FSP: Message cancel allowed only when" "FSP is in reset\n"); return; @@ -1745,6 +1744,11 @@ int fsp_sync_msg(struct fsp_msg *msg, bool autofree) goto bail; while(fsp_msg_busy(msg)) { + if (fsp_in_rr()) { + fsp_cancelmsg(msg); + rc = -1; + goto bail; + } cpu_relax(); opal_run_pollers(); } @@ -2033,6 +2037,11 @@ int fsp_fatal_msg(struct fsp_msg *msg) return rc; while(fsp_msg_busy(msg)) { + if (fsp_in_rr()) { + fsp_cancelmsg(msg); + return -1; + } + cpu_relax(); fsp_opal_poll(NULL); } |