[Skiboot] [PATCH 2/2] hw/phb3: Fix M64 error injection for VFs

Gavin Shan gwshan at linux.vnet.ibm.com
Mon Jun 29 10:44:22 AEST 2015


The last M64 (64-bits MMIO) BAR is always enabled and it is equal
to the PHB's M64 window. Also, the BAR is split to 256 segments
and each PE will have one segment in it. However, the VF PE takes
another BAR other than the last one to accomodate its M64 resources.
So current code will always give wrong M64 base address and size
when injecting M64 error for specified VF PE.

In order to fix the issue, we have to recognize the type of the
target PE: (A) bus dependent or (B) PCI device (VF) dependent.
For (A), we figure out the M64 base address and length from the
last M64 BAR. For (B), we scan from BAR#0 to BAR#14 and first
hit wins.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 hw/phb3.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/hw/phb3.c b/hw/phb3.c
index 9d52c84..47261c3 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2818,10 +2818,27 @@ static int64_t phb3_err_inject_mem64(struct phb3 *p, uint32_t pe_no,
 	uint64_t base, len, segstart, segsize;
 	uint64_t cache, a, m;
 	uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
-	uint32_t index;
+	uint32_t index, s_index, e_index;
+
+	/* By default, the PE is PCI device dependent one */
+	s_index = 0;
+	e_index = ARRAY_SIZE(p->m64b_cache) - 2;
+	for (index = 0; index < RTT_TABLE_ENTRIES; index++) {
+		if (p->rte_cache[index] != pe_no)
+			continue;
+
+		if (index + 8 >= RTT_TABLE_ENTRIES)
+			break;
+
+		/* PCI bus dependent PE */
+		if (p->rte_cache[index + 8] == pe_no) {
+			s_index = e_index = ARRAY_SIZE(p->m64b_cache) - 1;
+			break;
+		}
+	}
 
 	a = base = len = 0x0ull;
-	for (index = 0; index < ARRAY_SIZE(p->m64b_cache); index++) {
+	for (index = s_index; !len && index <= e_index; index++) {
 		cache = p->m64b_cache[index];
 		if (!(cache & IODA2_M64BT_ENABLE))
 			continue;
@@ -2845,24 +2862,18 @@ static int64_t phb3_err_inject_mem64(struct phb3 *p, uint32_t pe_no,
 			segstart = segstart + segsize * pe_no;
 		}
 
-		/* We expect contiguous segments. Otherwise, to
-		 * pick the bigger one, which has more possibility
-		 * to be accessed
+		/* First window always wins based on the ascending
+		 * searching priority the 16 BARs have. We're using
+		 * the feature to assign resource for SRIOV VFs.
 		 */
 		if (!len) {
 			base = segstart;
 			len = segsize;
-		} else if ((base + len) == segstart) {
-			len += segsize;
-		} else if (segsize > len) {
-			base = segstart;
-			len = segsize;
 		}
 
 		/* Specified address is valid one */
 		if (addr >= segstart && addr < (segstart + segsize)) {
 			a = addr;
-			break;
 		}
 	}
 
-- 
2.1.0



More information about the Skiboot mailing list