Date: Sun, 3 Jan 2016 06:33:46 +0000 (UTC) From: Garrett Cooper <ngie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r293076 - user/ngie/stable-10-libnv/sys/dev/pci Message-ID: <201601030633.u036XkIk079410@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601030633.u036XkIk079410>