[Skiboot] [PATCH 2/8] phb3+iov: Fixup support for config space filters
Benjamin Herrenschmidt
benh at kernel.crashing.org
Tue Jun 6 08:59:18 AEST 2017
The filter should be called before the HW access and its
return value control whether to perform the access or not
Also fix the pci-iov.c return values to match accordingly
otherwise this breaks SR-IOV
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
core/pci-iov.c | 11 +++++------
hw/phb3.c | 34 +++++++++++++++++++---------------
2 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/core/pci-iov.c b/core/pci-iov.c
index 6abb85a..9d75b37 100644
--- a/core/pci-iov.c
+++ b/core/pci-iov.c
@@ -33,9 +33,8 @@ static int64_t pci_iov_vf_devctl(void *dev, struct pci_cfg_reg_filter *pcrf,
uint32_t pos = pci_cap(vf, PCI_CFG_CAP_ID_EXP, false);
uint8_t *pcache;
- if (offset != pcrf->start ||
- offset != (pos + PCICAP_EXP_DEVCTL))
- return OPAL_SUCCESS;
+ if (offset != (pos + PCICAP_EXP_DEVCTL))
+ return OPAL_PARTIAL;
pcache = &pcrf->data[0];
if (write) {
@@ -130,13 +129,13 @@ static int64_t pci_iov_change(void *dev __unused,
/* Update SRIOV variable parameters */
changed = pci_iov_update_parameters(iov);
if (!changed)
- return OPAL_SUCCESS;
+ return OPAL_PARTIAL;
/* Remove all VFs that have been attached to the parent */
if (!iov->enabled) {
list_for_each_safe(&pd->children, vf, tmp, link)
list_del(&vf->link);
- return OPAL_SUCCESS;
+ return OPAL_PARTIAL;
}
/* Initialize the VFs and attach them to parent */
@@ -165,7 +164,7 @@ static int64_t pci_iov_change(void *dev __unused,
phb->ops->device_init(phb, pd, NULL);
}
- return OPAL_SUCCESS;
+ return OPAL_PARTIAL;
}
/*
diff --git a/hw/phb3.c b/hw/phb3.c
index c99f1de..f32142e 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -216,9 +216,9 @@ static void phb3_link_update(struct phb *phb, uint16_t data)
}
}
-static void phb3_pcicfg_filter(struct phb *phb, uint32_t bdfn,
- uint32_t offset, uint32_t len,
- uint32_t *data, bool write)
+static int64_t phb3_pcicfg_filter(struct phb *phb, uint32_t bdfn,
+ uint32_t offset, uint32_t len,
+ uint32_t *data, bool write)
{
struct pci_device *pd;
struct pci_cfg_reg_filter *pcrf;
@@ -229,25 +229,25 @@ static void phb3_pcicfg_filter(struct phb *phb, uint32_t bdfn,
*/
if (bdfn == 0 && write && len == 4 && offset == 0x58) {
phb3_link_update(phb, (*data) >> 16);
- return;
+ return OPAL_SUCCESS;
}
if (bdfn == 0 && write && len == 2 && offset == 0x5a) {
phb3_link_update(phb, *(uint16_t *)data);
- return;
+ return OPAL_SUCCESS;
}
if (!pci_device_has_cfg_reg_filters(phb, bdfn))
- return;
+ return OPAL_PARTIAL;
pd = pci_find_dev(phb, bdfn);
pcrf = pd ? pci_find_cfg_reg_filter(pd, offset, len) : NULL;
if (!pcrf || !pcrf->func)
- return;
+ return OPAL_PARTIAL;
flags = write ? PCI_REG_FLAG_WRITE : PCI_REG_FLAG_READ;
if ((pcrf->flags & flags) != flags)
- return;
+ return OPAL_PARTIAL;
- pcrf->func(pd, pcrf, offset, len, data, write);
+ return pcrf->func(pd, pcrf, offset, len, data, write);
}
#define PHB3_PCI_CFG_READ(size, type) \
@@ -275,6 +275,11 @@ static int64_t phb3_pcicfg_read##size(struct phb *phb, uint32_t bdfn, \
return OPAL_HARDWARE; \
} \
\
+ rc = phb3_pcicfg_filter(phb, bdfn, offset, sizeof(type), \
+ (uint32_t *)data, false); \
+ if (rc != OPAL_PARTIAL) \
+ return rc; \
+ \
addr = PHB_CA_ENABLE; \
addr = SETFIELD(PHB_CA_BDFN, addr, bdfn); \
addr = SETFIELD(PHB_CA_REG, addr, offset); \
@@ -290,9 +295,6 @@ static int64_t phb3_pcicfg_read##size(struct phb *phb, uint32_t bdfn, \
(offset & (4 - sizeof(type)))); \
} \
\
- phb3_pcicfg_filter(phb, bdfn, offset, sizeof(type), \
- (uint32_t *)data, false); \
- \
return OPAL_SUCCESS; \
}
@@ -318,6 +320,11 @@ static int64_t phb3_pcicfg_write##size(struct phb *phb, uint32_t bdfn, \
return OPAL_HARDWARE; \
} \
\
+ rc = phb3_pcicfg_filter(phb, bdfn, offset, sizeof(type), \
+ (uint32_t *)&data, true); \
+ if (rc != OPAL_PARTIAL) \
+ return rc; \
+ \
addr = PHB_CA_ENABLE; \
addr = SETFIELD(PHB_CA_BDFN, addr, bdfn); \
addr = SETFIELD(PHB_CA_REG, addr, offset); \
@@ -334,9 +341,6 @@ static int64_t phb3_pcicfg_write##size(struct phb *phb, uint32_t bdfn, \
(offset & (4 - sizeof(type))), data); \
} \
\
- phb3_pcicfg_filter(phb, bdfn, offset, sizeof(type), \
- (uint32_t *)&data, true); \
- \
return OPAL_SUCCESS; \
}
--
2.9.4
More information about the Skiboot
mailing list