aboutsummaryrefslogtreecommitdiff
path: root/hw/phb3.c
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2015-09-01 11:07:02 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-09-01 11:56:56 +1000
commit147f3e45efb26152a53acecef15ea7096e3ff9db (patch)
treead128a070c5af8be3fd0bd82fad69e714b34420e /hw/phb3.c
parentf8680a86f4aa19ced179f2a8da352c5650ba48cf (diff)
downloadskiboot-147f3e45efb26152a53acecef15ea7096e3ff9db.zip
skiboot-147f3e45efb26152a53acecef15ea7096e3ff9db.tar.gz
skiboot-147f3e45efb26152a53acecef15ea7096e3ff9db.tar.bz2
phb3: Handle fence in phb3_pci_msi_check_q to fix hang
If the PHB is fenced during phb3_pci_msi_check_q, it can get stuck in an infinite loop waiting to lock the FFI. Further, as the phb lock is held during this function it will prevent any other CPUs from dealing with the fence, leading to the entire system hanging. If the PHB_FFI_LOCK returns all Fs, return immediately to allow the fence to be dealt with. Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/phb3.c')
-rw-r--r--hw/phb3.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index 9fa8afb..86ca7be 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -1047,7 +1047,7 @@ static int64_t phb3_map_pe_dma_window_real(struct phb *phb,
static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num)
{
- uint64_t ive, ivc, ffi;
+ uint64_t ive, ivc, ffi, state;
uint8_t *q_byte;
/* Each IVE has 16-bytes or 128-bytes */
@@ -1071,9 +1071,13 @@ static void phb3_pci_msi_check_q(struct phb3 *p, uint32_t ive_num)
}
/* Lock FFI and send interrupt */
- while (in_be64(p->regs + PHB_FFI_LOCK))
- /* XXX Handle fences ! */
- ;
+ while (1) {
+ state = in_be64(p->regs + PHB_FFI_LOCK);
+ if (!state)
+ break;
+ if (state == ~0ULL) /* PHB Fenced */
+ return;
+ }
/* Clear Q bit and update IVC */
*q_byte = 0;