[Skiboot] [PATCH 1/2] hw/phb3: Support config error injection to VF PE

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


Before the SRIOV is enabled, the only supported PE type is PCI bus
dependent PE when doing error injection via PCI config space. That
means the device/function number are ignored when writing to PAPR
error injection address/mask registers (0x2b8 and 0x2c0) to inject
PCI config access caused errors. If user intends to inject error
to one VF, which is binding with individual PE, all VFs hooked to
same PCI bus might receive errors wrongly.

The patch fixes above issue by writing correct PCI config address
to the registers according to the PE type: bus dependent or PCI
device dependent PE.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 hw/phb3.c           | 45 ++++++++++++++++++++++++++++++---------------
 include/phb3-regs.h |  1 +
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/hw/phb3.c b/hw/phb3.c
index 9b4444c..9d52c84 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2891,25 +2891,42 @@ static int64_t phb3_err_inject_cfg(struct phb3 *p, uint32_t pe_no,
 {
 	uint64_t a, m, prefer;
 	uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_CFG;
-	int bus_no, bdfn;
+	int bdfn;
+	bool is_bus_pe;
 
 	a = 0xffffull;
 	prefer = 0xffffull;
+	m = PHB_PAPR_ERR_INJ_MASK_CFG_ALL;
 	for (bdfn = 0; bdfn < RTT_TABLE_ENTRIES; bdfn++) {
 		if (p->rte_cache[bdfn] != pe_no)
 			continue;
 
-		/* Select minimal bus number as PE
-		 * primary bus number
-		 */
-		bus_no = (bdfn >> 8);
-		if (prefer == 0xffffull)
-			prefer = SETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG, 0x0ull, bus_no);
+		/* The PE can be associated with PCI bus or device */
+		is_bus_pe = false;
+		if ((bdfn + 8) < RTT_TABLE_ENTRIES &&
+		    p->rte_cache[bdfn + 8] == pe_no)
+			is_bus_pe = true;
+
+		/* Figure out the PCI config address */
+		if (prefer == 0xffffull) {
+			if (is_bus_pe) {
+				m = PHB_PAPR_ERR_INJ_MASK_CFG;
+				prefer = SETFIELD(m, 0x0ull, (bdfn >> 8));
+			} else {
+				m = PHB_PAPR_ERR_INJ_MASK_CFG_ALL;
+				prefer = SETFIELD(m, 0x0ull, bdfn);
+			}
+		}
 
-		/* Address should no greater than max bus
-		 * number within PE
-		 */
-		if ((GETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG, addr) == bus_no)) {
+		/* Check the input address is valid or not */
+		if (!is_bus_pe &&
+		    GETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG_ALL, addr) == bdfn) {
+			a = addr;
+			break;
+		}
+
+		if (is_bus_pe &&
+		    GETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG, addr) == (bdfn >> 8)) {
 			a = addr;
 			break;
 		}
@@ -2920,12 +2937,10 @@ static int64_t phb3_err_inject_cfg(struct phb3 *p, uint32_t pe_no,
 		return OPAL_PARAMETER;
 
 	/* Specified address is out of range */
-	if (a == 0xffffull) {
+	if (a == 0xffffull)
 		a = prefer;
-		m = PHB_PAPR_ERR_INJ_MASK_CFG;
-	} else {
+	else
 		m = mask;
-	}
 
 	return phb3_err_inject_finalize(p, a, m, ctrl, is_write);
 }
diff --git a/include/phb3-regs.h b/include/phb3-regs.h
index 632ed93..91f25f9 100644
--- a/include/phb3-regs.h
+++ b/include/phb3-regs.h
@@ -123,6 +123,7 @@
 #define   PHB_PAPR_ERR_INJ_ADDR_MMIO		PPC_BITMASK(16,63)
 #define PHB_PAPR_ERR_INJ_MASK		0x2c0
 #define   PHB_PAPR_ERR_INJ_MASK_CFG		PPC_BITMASK(4,11)
+#define   PHB_PAPR_ERR_INJ_MASK_CFG_ALL		PPC_BITMASK(4,19)
 #define   PHB_PAPR_ERR_INJ_MASK_MMIO		PPC_BITMASK(16,63)
 #define PHB_ETU_ERR_SUMMARY		0x2c8
 
-- 
2.1.0



More information about the Skiboot mailing list