@@ -963,17 +963,20 @@ void pci_remove_legacy_files(struct pci_bus *b)
int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
enum pci_mmap_api mmap_api)
{
- unsigned long nr, start, size, pci_start;
+ unsigned long nr, start, size, pci_offset;
+ resource_size_t pci_start, pci_end;
if (pci_resource_len(pdev, resno) == 0)
return 0;
nr = vma_pages(vma);
start = vma->vm_pgoff;
+ pci_resource_to_user(pdev, resno, &pdev->resource[resno],
+ &pci_start, &pci_end);
size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
- pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
- pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
- if (start >= pci_start && start < pci_start + size &&
- start + nr <= pci_start + size)
+ pci_offset = (mmap_api == PCI_MMAP_PROCFS) ?
+ pci_start >> PAGE_SHIFT : 0;
+ if (start >= pci_offset && start < pci_offset + size &&
+ start + nr <= pci_offset + size)
return 1;
return 0;
}
The addresses stored in PCI device resources for memory spaces correspond to CPU physical addresses, which do not necessarily map 1:1 to PCI bus addresses as programmed in PCI devices configuration spaces. Therefore, the changes applied by commits: 8c05cd08a7504b855c26526 3b519e4ea618b6943a82931 imply that the sanity checks carried out in pci_mmap_fits() to ensure that the user executes an mmap of a "real" pci resource are erroneous when executed through procfs. Some platforms (ie SPARC) expect the offset value to be passed in (procfs mapping) to be the PCI BAR configuration value as read from the PCI device configuration space, not the fixed-up CPU physical address that is present in PCI device resources. The required pgoff (offset in mmap syscall) value passed from userspace is supposed to represent the resource value exported through /proc/bus/pci/devices when the resource is mmapped though procfs (and 0 when the mapping is carried out through sysfs resource files), which corresponds to the PCI resource filtered through the pci_resource_to_user() API. This patch converts the PCI resource to the expected "user visible" value through pci_resource_to_user() before carrying out sanity checks in pci_mmap_fits() so that the check is carried out on the resource values as expected from the userspace mmap API. Cc: Arnd Bergmann <arnd@arndb.de> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Russell King <linux@arm.linux.org.uk> Cc: David S. Miller <davem@davemloft.net> Cc: Michal Simek <monstr@monstr.eu> Cc: Martin Wilck <martin.wilck@ts.fujitsu.com> Cc: Derrick J. Wong <djwong@us.ibm.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> --- drivers/pci/pci-sysfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)