git: 1f960e646b72 - main - pci: Implement pci_bar_enabled() for SR-IOV VFs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 09 Nov 2021 18:20:26 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=1f960e646b7280795766fdaa183e3b9bd4cea345 commit 1f960e646b7280795766fdaa183e3b9bd4cea345 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-11-09 18:07:57 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-11-09 18:13:36 +0000 pci: Implement pci_bar_enabled() for SR-IOV VFs In a VF's configuration space, "memory space enable" is hard-wired to 0, so the existing implementation always returns false. We need to read the SR-IOV control register from the PF device to get the value of the MSE bit. Fix pci_bar_enabled() to read this register instead for VFs. I don't see any way to access the PF's config space without a backpointer in the pci device ivars, so I added one. This fixes a regression where bhyve(8) fails to map the MSI-X table after commit 7fa233534736 ("bhyve: Map the MSI-X table unconditionally for passthrough") when a VF is passed through, since with that commit we use PCIOCBARMMAP to map the table and that ioctl always fails for VFs without this change. As a bonus, pciconf(8) now correctly reports the enablement of BARs for VFs. Reported and tested by: Raúl Muñoz <raul.munoz@custos.es> Reviewed by: rstone, jhb MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32839 --- sys/dev/pci/pci.c | 10 ++++++++++ sys/dev/pci/pci_iov.c | 1 + sys/dev/pci/pci_iov_private.h | 1 + 3 files changed, 12 insertions(+) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 702f9fc3aa05..7493ae1727fb 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -3151,6 +3151,16 @@ pci_bar_enabled(device_t dev, struct pci_map *pm) if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) && !(pm->pm_value & PCIM_BIOS_ENABLE)) return (0); +#ifdef PCI_IOV + if ((dinfo->cfg.flags & PCICFG_VF) != 0) { + struct pcicfg_iov *iov; + + iov = dinfo->cfg.iov; + cmd = pci_read_config(iov->iov_pf, + iov->iov_pos + PCIR_SRIOV_CTL, 2); + return ((cmd & PCIM_SRIOV_VF_MSE) != 0); + } +#endif cmd = pci_read_config(dev, PCIR_COMMAND, 2); if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) || PCI_BAR_MEM(pm->pm_value)) return ((cmd & PCIM_CMD_MEMEN) != 0); diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c index 6db2cf445843..f577640595a9 100644 --- a/sys/dev/pci/pci_iov.c +++ b/sys/dev/pci/pci_iov.c @@ -151,6 +151,7 @@ pci_iov_attach_method(device_t bus, device_t dev, nvlist_t *pf_schema, error = EBUSY; goto cleanup; } + iov->iov_pf = dev; iov->iov_pos = iov_pos; schema = pci_iov_build_schema(&pf_schema, &vf_schema); diff --git a/sys/dev/pci/pci_iov_private.h b/sys/dev/pci/pci_iov_private.h index 0d1dda871b44..be3456d4781f 100644 --- a/sys/dev/pci/pci_iov_private.h +++ b/sys/dev/pci/pci_iov_private.h @@ -37,6 +37,7 @@ struct pci_iov_bar { }; struct pcicfg_iov { + device_t iov_pf; struct cdev *iov_cdev; nvlist_t *iov_schema;