diff options
| -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 |
3 files changed, 23 insertions, 8 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index b5a7d9bfcb24..25accc9dda3b 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_SYSFS) ? |
| 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 f5c7c382765f..7d33f6673868 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 297b72c880a1..ea00647f4732 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
| @@ -257,7 +257,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 257 | 257 | ||
| 258 | /* Make sure the caller is mapping a real resource for this device */ | 258 | /* Make sure the caller is mapping a real resource for this device */ |
| 259 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { | 259 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { |
| 260 | if (pci_mmap_fits(dev, i, vma)) | 260 | if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) |
| 261 | break; | 261 | break; |
| 262 | } | 262 | } |
| 263 | 263 | ||
