[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