aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
commita215aa7b9ab3759c047201199fba64d3042d7f13 (patch)
treebca37493d9b2233450e6d3ffced1261d0e4f71fe /drivers/pci
parentd31199a77ef606f1d06894385f1852181ba6136b (diff)
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/dmar.c5
-rw-r--r--drivers/pci/pci-stub.c3
-rw-r--r--drivers/pci/pci-sysfs.c22
-rw-r--r--drivers/pci/pci.h7
-rw-r--r--drivers/pci/proc.c2
-rw-r--r--drivers/pci/quirks.c23
6 files changed, 54 insertions, 8 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0a19708074c2..a286959db67e 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1414,6 +1414,11 @@ int __init enable_drhd_fault_handling(void)
1414 (unsigned long long)drhd->reg_base_addr, ret); 1414 (unsigned long long)drhd->reg_base_addr, ret);
1415 return -1; 1415 return -1;
1416 } 1416 }
1417
1418 /*
1419 * Clear any previous faults.
1420 */
1421 dmar_fault(iommu->irq, iommu);
1417 } 1422 }
1418 1423
1419 return 0; 1424 return 0;
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index f7b68ca6cc98..4ae494bb1d50 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -54,6 +54,9 @@ static int __init pci_stub_init(void)
54 subdevice = PCI_ANY_ID, class=0, class_mask=0; 54 subdevice = PCI_ANY_ID, class=0, class_mask=0;
55 int fields; 55 int fields;
56 56
57 if (!strlen(id))
58 continue;
59
57 fields = sscanf(id, "%x:%x:%x:%x:%x:%x", 60 fields = sscanf(id, "%x:%x:%x:%x:%x:%x",
58 &vendor, &device, &subvendor, &subdevice, 61 &vendor, &device, &subvendor, &subdevice,
59 &class, &class_mask); 62 &class, &class_mask);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index b5a7d9bfcb24..4835a02ec017 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -705,17 +705,21 @@ void pci_remove_legacy_files(struct pci_bus *b)
705 705
706#ifdef HAVE_PCI_MMAP 706#ifdef HAVE_PCI_MMAP
707 707
708int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) 708int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
709 enum pci_mmap_api mmap_api)
709{ 710{
710 unsigned long nr, start, size; 711 unsigned long nr, start, size, pci_start;
711 712
713 if (pci_resource_len(pdev, resno) == 0)
714 return 0;
712 nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 715 nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
713 start = vma->vm_pgoff; 716 start = vma->vm_pgoff;
714 size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; 717 size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
715 if (start < size && size - start >= nr) 718 pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
719 pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
720 if (start >= pci_start && start < pci_start + size &&
721 start + nr <= pci_start + size)
716 return 1; 722 return 1;
717 WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
718 current->comm, start, start+nr, pci_name(pdev), resno, size);
719 return 0; 723 return 0;
720} 724}
721 725
@@ -745,8 +749,14 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
745 if (i >= PCI_ROM_RESOURCE) 749 if (i >= PCI_ROM_RESOURCE)
746 return -ENODEV; 750 return -ENODEV;
747 751
748 if (!pci_mmap_fits(pdev, i, vma)) 752 if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
753 WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
754 "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
755 current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
756 pci_name(pdev), i,
757 pci_resource_start(pdev, i), pci_resource_len(pdev, i));
749 return -EINVAL; 758 return -EINVAL;
759 }
750 760
751 /* pci_mmap_page_range() expects the same kind of entry as coming 761 /* pci_mmap_page_range() expects the same kind of entry as coming
752 * from /proc/bus/pci/ which is a "user visible" value. If this is 762 * from /proc/bus/pci/ which is a "user visible" value. If this is
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6beb11b617a9..1001b1d7e041 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -22,8 +22,13 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev);
22#endif 22#endif
23extern void pci_cleanup_rom(struct pci_dev *dev); 23extern void pci_cleanup_rom(struct pci_dev *dev);
24#ifdef HAVE_PCI_MMAP 24#ifdef HAVE_PCI_MMAP
25enum pci_mmap_api {
26 PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
27 PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */
28};
25extern int pci_mmap_fits(struct pci_dev *pdev, int resno, 29extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
26 struct vm_area_struct *vma); 30 struct vm_area_struct *vmai,
31 enum pci_mmap_api mmap_api);
27#endif 32#endif
28int pci_probe_reset_function(struct pci_dev *dev); 33int pci_probe_reset_function(struct pci_dev *dev);
29 34
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 01f0306525a5..4aae016c79d0 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -260,7 +260,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
260 260
261 /* Make sure the caller is mapping a real resource for this device */ 261 /* Make sure the caller is mapping a real resource for this device */
262 for (i = 0; i < PCI_ROM_RESOURCE; i++) { 262 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
263 if (pci_mmap_fits(dev, i, vma)) 263 if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS))
264 break; 264 break;
265 } 265 }
266 266
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 857ae01734a6..32ae8188c094 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2714,6 +2714,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m
2714DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); 2714DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
2715#endif /*CONFIG_MMC_RICOH_MMC*/ 2715#endif /*CONFIG_MMC_RICOH_MMC*/
2716 2716
2717#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
2718#define VTUNCERRMSK_REG 0x1ac
2719#define VTD_MSK_SPEC_ERRORS (1 << 31)
2720/*
2721 * This is a quirk for masking vt-d spec defined errors to platform error
2722 * handling logic. With out this, platforms using Intel 7500, 5500 chipsets
2723 * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based
2724 * on the RAS config settings of the platform) when a vt-d fault happens.
2725 * The resulting SMI caused the system to hang.
2726 *
2727 * VT-d spec related errors are already handled by the VT-d OS code, so no
2728 * need to report the same error through other channels.
2729 */
2730static void vtd_mask_spec_errors(struct pci_dev *dev)
2731{
2732 u32 word;
2733
2734 pci_read_config_dword(dev, VTUNCERRMSK_REG, &word);
2735 pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS);
2736}
2737DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
2738DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
2739#endif
2717 2740
2718static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2741static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2719 struct pci_fixup *end) 2742 struct pci_fixup *end)