svn commit: r293076 - user/ngie/stable-10-libnv/sys/dev/pci
Garrett Cooper
ngie at FreeBSD.org
Sun Jan 3 06:33:47 UTC 2016
Author: ngie
Date: Sun Jan 3 06:33:46 2016
New Revision: 293076
URL: https://svnweb.freebsd.org/changeset/base/293076
Log:
MFC r279448:
r279448 (by rstone):
Emulate the Device ID and Vendor ID registers for VFs
The SR-IOV standard requires VFs to read all-ones when the VID
and DID registers are read. The VMM (hypervisor) is required to
emulate them instead. Make pci_read_config() do this emulation.
Change pci_user.c to use pci_read_config() to read config space
registers instead of going directly to the pcib so that the
emulated VID/DID registers work correctly on VFs. This is
required both for pciconf and bhyve PCI passthrough.
Modified:
user/ngie/stable-10-libnv/sys/dev/pci/pci.c
user/ngie/stable-10-libnv/sys/dev/pci/pci_user.c
Directory Properties:
user/ngie/stable-10-libnv/ (props changed)
Modified: user/ngie/stable-10-libnv/sys/dev/pci/pci.c
==============================================================================
--- user/ngie/stable-10-libnv/sys/dev/pci/pci.c Sun Jan 3 06:25:22 2016 (r293075)
+++ user/ngie/stable-10-libnv/sys/dev/pci/pci.c Sun Jan 3 06:33:46 2016 (r293076)
@@ -4995,6 +4995,37 @@ pci_read_config_method(device_t dev, dev
struct pci_devinfo *dinfo = device_get_ivars(child);
pcicfgregs *cfg = &dinfo->cfg;
+#ifdef PCI_IOV
+ /*
+ * SR-IOV VFs don't implement the VID or DID registers, so we have to
+ * emulate them here.
+ */
+ if (cfg->flags & PCICFG_VF) {
+ if (reg == PCIR_VENDOR) {
+ switch (width) {
+ case 4:
+ return (cfg->device << 16 | cfg->vendor);
+ case 2:
+ return (cfg->vendor);
+ case 1:
+ return (cfg->vendor & 0xff);
+ default:
+ return (0xffffffff);
+ }
+ } else if (reg == PCIR_DEVICE) {
+ switch (width) {
+ /* Note that an unaligned 4-byte read is an error. */
+ case 2:
+ return (cfg->device);
+ case 1:
+ return (cfg->device & 0xff);
+ default:
+ return (0xffffffff);
+ }
+ }
+ }
+#endif
+
return (PCIB_READ_CONFIG(device_get_parent(dev),
cfg->bus, cfg->slot, cfg->func, reg, width));
}
Modified: user/ngie/stable-10-libnv/sys/dev/pci/pci_user.c
==============================================================================
--- user/ngie/stable-10-libnv/sys/dev/pci/pci_user.c Sun Jan 3 06:25:22 2016 (r293075)
+++ user/ngie/stable-10-libnv/sys/dev/pci/pci_user.c Sun Jan 3 06:33:46 2016 (r293076)
@@ -492,7 +492,7 @@ pci_list_vpd(device_t dev, struct pci_li
static int
pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
- device_t pcidev, brdev;
+ device_t pcidev;
void *confdata;
const char *name;
struct devlist *devlist_head;
@@ -922,37 +922,25 @@ getconfexit:
io->pi_sel.pc_bus, io->pi_sel.pc_dev,
io->pi_sel.pc_func);
if (pcidev) {
- brdev = device_get_parent(
- device_get_parent(pcidev));
-
#ifdef PRE7_COMPAT
if (cmd == PCIOCWRITE || cmd == PCIOCWRITE_OLD)
#else
if (cmd == PCIOCWRITE)
#endif
- PCIB_WRITE_CONFIG(brdev,
- io->pi_sel.pc_bus,
- io->pi_sel.pc_dev,
- io->pi_sel.pc_func,
+ pci_write_config(pcidev,
io->pi_reg,
io->pi_data,
io->pi_width);
#ifdef PRE7_COMPAT
else if (cmd == PCIOCREAD_OLD)
io_old->pi_data =
- PCIB_READ_CONFIG(brdev,
- io->pi_sel.pc_bus,
- io->pi_sel.pc_dev,
- io->pi_sel.pc_func,
+ pci_read_config(pcidev,
io->pi_reg,
io->pi_width);
#endif
else
io->pi_data =
- PCIB_READ_CONFIG(brdev,
- io->pi_sel.pc_bus,
- io->pi_sel.pc_dev,
- io->pi_sel.pc_func,
+ pci_read_config(pcidev,
io->pi_reg,
io->pi_width);
error = 0;
More information about the svn-src-user
mailing list