summaryrefslogtreecommitdiffstats
path: root/hw/phb3.c
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-06-29 10:44:21 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-03 07:23:49 +1000
commitb2636472eef708006a017fa3858ac754968e6cc9 (patch)
tree38654f30ab2e4237ec92833e5a8c64cf0d247f2f /hw/phb3.c
parentaa617925bb0e21550ec69b625cb9bd48f66655fb (diff)
downloadtalos-skiboot-b2636472eef708006a017fa3858ac754968e6cc9.tar.gz
talos-skiboot-b2636472eef708006a017fa3858ac754968e6cc9.zip
hw/phb3: Support config error injection to VF PE
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@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/phb3.c')
-rw-r--r--hw/phb3.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index 71546af5..009790e3 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);
}
OpenPOWER on IntegriCloud