svn commit: r214203 - head/sys/dev/pci
John Baldwin
jhb at FreeBSD.org
Fri Oct 22 11:42:03 UTC 2010
Author: jhb
Date: Fri Oct 22 11:42:02 2010
New Revision: 214203
URL: http://svn.freebsd.org/changeset/base/214203
Log:
- Add a new PCI quirk to whitelist an old chipset that doesn't support
PCI-express or PCI-X capabilities if we are running in a virtual machine.
- Whitelist the Intel 82440 chipset used by QEMU.
Tested by: jfv
MFC after: 1 week
Modified:
head/sys/dev/pci/pci.c
Modified: head/sys/dev/pci/pci.c
==============================================================================
--- head/sys/dev/pci/pci.c Fri Oct 22 11:22:19 2010 (r214202)
+++ head/sys/dev/pci/pci.c Fri Oct 22 11:42:02 2010 (r214203)
@@ -182,6 +182,7 @@ struct pci_quirk {
int type;
#define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */
#define PCI_QUIRK_DISABLE_MSI 2 /* MSI/MSI-X doesn't work */
+#define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */
int arg1;
int arg2;
};
@@ -218,6 +219,12 @@ struct pci_quirk pci_quirks[] = {
*/
{ 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 },
+ /*
+ * Some virtualization environments emulate an older chipset
+ * but support MSI just fine. QEMU uses the Intel 82440.
+ */
+ { 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 },
+
{ 0 }
};
@@ -1834,6 +1841,23 @@ pci_msi_device_blacklisted(device_t dev)
}
/*
+ * Returns true if a specified chipset supports MSI when it is
+ * emulated hardware in a virtual machine.
+ */
+static int
+pci_msi_vm_chipset(device_t dev)
+{
+ struct pci_quirk *q;
+
+ for (q = &pci_quirks[0]; q->devid; q++) {
+ if (q->devid == pci_get_devid(dev) &&
+ q->type == PCI_QUIRK_ENABLE_MSI_VM)
+ return (1);
+ }
+ return (0);
+}
+
+/*
* Determine if MSI is blacklisted globally on this sytem. Currently,
* we just check for blacklisted chipsets as represented by the
* host-PCI bridge at device 0:0:0. In the future, it may become
@@ -1849,8 +1873,14 @@ pci_msi_blacklisted(void)
return (0);
/* Blacklist all non-PCI-express and non-PCI-X chipsets. */
- if (!(pcie_chipset || pcix_chipset))
+ if (!(pcie_chipset || pcix_chipset)) {
+ if (vm_guest != VM_GUEST_NO) {
+ dev = pci_find_bsf(0, 0, 0);
+ if (dev != NULL)
+ return (pci_msi_vm_chipset(dev) == 0);
+ }
return (1);
+ }
dev = pci_find_bsf(0, 0, 0);
if (dev != NULL)
More information about the svn-src-all
mailing list