svn commit: r350662 - in head/sys: dev/acpica i386/pci

John Baldwin jhb at FreeBSD.org
Tue Aug 6 23:15:05 UTC 2019


Author: jhb
Date: Tue Aug  6 23:15:04 2019
New Revision: 350662
URL: https://svnweb.freebsd.org/changeset/base/350662

Log:
  Detect invalid PCI devices more correctly in PCI interrupt router drivers.
  
  - Check for an invalid device (vendor is invalid) before reading the
    header type register when examining function 0 of a possible device.
  - When iterating over functions of a device, reject any device whose
    16-bit vendor is invalid rather than requiring the full 32-bit
    vendor+device to be all 1's.  In practice the latter check is
    probably fine, but checking the vendor is what the PCI spec
    recommends.
  
  Reviewed by:	imp
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D21147

Modified:
  head/sys/dev/acpica/acpi_pci_link.c
  head/sys/i386/pci/pci_pir.c

Modified: head/sys/dev/acpica/acpi_pci_link.c
==============================================================================
--- head/sys/dev/acpica/acpi_pci_link.c	Tue Aug  6 23:04:59 2019	(r350661)
+++ head/sys/dev/acpica/acpi_pci_link.c	Tue Aug  6 23:15:04 2019	(r350662)
@@ -580,6 +580,9 @@ acpi_pci_link_search_irq(int bus, int device, int pin)
 	uint8_t func, maxfunc;
 
 	/* See if we have a valid device at function 0. */
+	value = pci_cfgregread(bus, device, 0, PCIR_VENDOR, 2);
+	if (value == PCIV_INVALID)
+		return (PCI_INVALID_IRQ);
 	value = pci_cfgregread(bus, device, 0, PCIR_HDRTYPE, 1);
 	if ((value & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
 		return (PCI_INVALID_IRQ);
@@ -590,8 +593,8 @@ acpi_pci_link_search_irq(int bus, int device, int pin)
 
 	/* Scan all possible functions at this device. */
 	for (func = 0; func <= maxfunc; func++) {
-		value = pci_cfgregread(bus, device, func, PCIR_DEVVENDOR, 4);
-		if (value == 0xffffffff)
+		value = pci_cfgregread(bus, device, func, PCIR_VENDOR, 2);
+		if (value == PCIV_INVALID)
 			continue;
 		value = pci_cfgregread(bus, device, func, PCIR_INTPIN, 1);
 

Modified: head/sys/i386/pci/pci_pir.c
==============================================================================
--- head/sys/i386/pci/pci_pir.c	Tue Aug  6 23:04:59 2019	(r350661)
+++ head/sys/i386/pci/pci_pir.c	Tue Aug  6 23:15:04 2019	(r350662)
@@ -257,8 +257,8 @@ pci_pir_create_links(struct PIR_entry *entry, struct P
 }
 
 /*
- * Look to see if any of the function on the PCI device at bus/device have
- * an interrupt routed to intpin 'pin' by the BIOS.
+ * Look to see if any of the functions on the PCI device at bus/device
+ * have an interrupt routed to intpin 'pin' by the BIOS.
  */
 static uint8_t
 pci_pir_search_irq(int bus, int device, int pin)
@@ -267,6 +267,9 @@ pci_pir_search_irq(int bus, int device, int pin)
 	uint8_t func, maxfunc;
 
 	/* See if we have a valid device at function 0. */
+	value = pci_cfgregread(bus, device, 0, PCIR_VENDOR, 2);
+	if (value == PCIV_INVALID)
+		return (PCI_INVALID_IRQ);
 	value = pci_cfgregread(bus, device, 0, PCIR_HDRTYPE, 1);
 	if ((value & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
 		return (PCI_INVALID_IRQ);
@@ -277,8 +280,8 @@ pci_pir_search_irq(int bus, int device, int pin)
 
 	/* Scan all possible functions at this device. */
 	for (func = 0; func <= maxfunc; func++) {
-		value = pci_cfgregread(bus, device, func, PCIR_DEVVENDOR, 4);
-		if (value == 0xffffffff)
+		value = pci_cfgregread(bus, device, func, PCIR_VENDOR, 2);
+		if (value == PCIV_INVALID)
 			continue;
 		value = pci_cfgregread(bus, device, func, PCIR_INTPIN, 1);
 


More information about the svn-src-all mailing list