[Skiboot] [PATCH RFC 4/6] pci-iov: Fix device allocation for VFs
Sergey Miroshnichenko
s.miroshnichenko at yadro.com
Sat Mar 2 01:30:36 AEDT 2019
Cfg filters are invoked before performing the I/O, so pci_iov_change() was
reading an old value of the SRIOV_CTRL_VFE register - before it is updated.
This patch makes use of the data which is being written to SRIOV_CTRL_VFE.
Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko at yadro.com>
---
core/pci-iov.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/core/pci-iov.c b/core/pci-iov.c
index 8fecebc1..3bbb7b86 100644
--- a/core/pci-iov.c
+++ b/core/pci-iov.c
@@ -79,15 +79,13 @@ static void pci_iov_vf_quirk(struct phb *phb, struct pci_device *vf)
* Update the SRIOV parameters that change when the number of
* VFs is configured.
*/
-static bool pci_iov_update_parameters(struct pci_iov *iov)
+static bool pci_iov_update_parameters(struct pci_iov *iov, uint16_t val)
{
struct phb *phb = iov->phb;
uint16_t bdfn = iov->pd->bdfn;
uint32_t pos = iov->pos;
- uint16_t val;
bool enabled;
- pci_cfg_read16(phb, bdfn, pos + PCIECAP_SRIOV_CTRL, &val);
enabled = !!(val & PCIECAP_SRIOV_CTRL_VFE);
if (iov->enabled == enabled)
return false;
@@ -115,8 +113,8 @@ static bool pci_iov_update_parameters(struct pci_iov *iov)
static int64_t pci_iov_change(void *dev __unused,
struct pci_cfg_reg_filter *pcrf,
uint32_t offset __unused,
- uint32_t len __unused,
- uint32_t *data __unused,
+ uint32_t len,
+ uint32_t *data,
bool write __unused)
{
struct pci_iov *iov = (struct pci_iov *)pcrf->data;
@@ -127,7 +125,9 @@ static int64_t pci_iov_change(void *dev __unused,
bool changed;
/* Update SRIOV variable parameters */
- changed = pci_iov_update_parameters(iov);
+ changed = pci_iov_update_parameters(iov,
+ (len == 2) ? (*data >> 16) : *data);
+
if (!changed)
return OPAL_PARTIAL;
@@ -202,6 +202,7 @@ void pci_init_iov_cap(struct phb *phb, struct pci_device *pd)
struct pci_iov *iov;
struct pci_cfg_reg_filter *pcrf;
uint32_t i;
+ uint16_t val;
/* Search for SRIOV capability */
if (!pci_has_cap(pd, PCI_CFG_CAP_ID_EXP, false))
@@ -260,6 +261,7 @@ void pci_init_iov_cap(struct phb *phb, struct pci_device *pd)
iov->pd = pd;
iov->pos = pos;
iov->enabled = false;
- pci_iov_update_parameters(iov);
+ pci_cfg_read16(phb, pd->bdfn, pos + PCIECAP_SRIOV_CTRL, &val);
+ pci_iov_update_parameters(iov, val);
pci_set_cap(pd, PCIECAP_ID_SRIOV, pos, iov, pci_free_iov_cap, true);
}
--
2.20.1
More information about the Skiboot
mailing list