[Skiboot] [PATCH] phb3: Handle fence in phb3_pci_msi_check_q to fix hang

Ian Munsie imunsie at au1.ibm.com
Tue Sep 1 11:07:02 AEST 2015


From: Ian Munsie <imunsie at au1.ibm.com>

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 at au1.ibm.com>
---
 hw/phb3.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/phb3.c b/hw/phb3.c
index 134fc62..4c1b84a 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -1037,7 +1037,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 */
@@ -1061,9 +1061,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;
-- 
2.1.4



More information about the Skiboot mailing list