diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
commit | a215aa7b9ab3759c047201199fba64d3042d7f13 (patch) | |
tree | bca37493d9b2233450e6d3ffced1261d0e4f71fe /drivers/pci | |
parent | d31199a77ef606f1d06894385f1852181ba6136b (diff) |
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/dmar.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci-stub.c | 3 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 22 | ||||
-rw-r--r-- | drivers/pci/pci.h | 7 | ||||
-rw-r--r-- | drivers/pci/proc.c | 2 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 23 |
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 | ||
708 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) | 708 | int 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 |
23 | extern void pci_cleanup_rom(struct pci_dev *dev); | 23 | extern void pci_cleanup_rom(struct pci_dev *dev); |
24 | #ifdef HAVE_PCI_MMAP | 24 | #ifdef HAVE_PCI_MMAP |
25 | enum 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 | }; | ||
25 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | 29 | extern 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 |
28 | int pci_probe_reset_function(struct pci_dev *dev); | 33 | int 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 | |||
2714 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2714 | DECLARE_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 | */ | ||
2730 | static 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 | } | ||
2737 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); | ||
2738 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | ||
2739 | #endif | ||
2717 | 2740 | ||
2718 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2741 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2719 | struct pci_fixup *end) | 2742 | struct pci_fixup *end) |