From ae749c7ab475de2c9c427058db19921c91846e89 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:54 +0100 Subject: PCI: Add arch_can_pci_mmap_wc() macro Most of the almost-identical versions of pci_mmap_page_range() silently ignore the 'write_combine' argument and give uncached mappings. Yet we allow the PCIIOC_WRITE_COMBINE ioctl in /proc/bus/pci, expose the 'resourceX_wc' file in sysfs, and allow an attempted mapping to apparently succeed. To fix this, introduce a macro arch_can_pci_mmap_wc() which indicates whether the platform can do a write-combining mapping. On x86 this ends up being pat_enabled(), while the few other platforms that support it can just set it to a literal '1'. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index eb3da1a04e6c..e614fb42d8bb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1626,6 +1626,10 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } #include +#ifndef arch_can_pci_mmap_wc +#define arch_can_pci_mmap_wc() 0 +#endif + #ifndef pci_root_bus_fwnode #define pci_root_bus_fwnode(bus) NULL #endif -- cgit v1.2.3 From 11df19546fe4a6135cdae62e96a1e25b3fabf6ea Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:55 +0100 Subject: PCI: Move multiple declarations of pci_mmap_page_range() to We can declare it even on platforms where it isn't going to be defined. There's no need to have it littered through the various files. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e614fb42d8bb..e7bb4b62cc97 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1626,6 +1626,13 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } #include +/* Map a range of PCI memory or I/O space for a device into user space. + * Architectures provide this function if they set HAVE_PCI_MMAP, and + * it accepts the 'write_combine' argument when arch_can_pci_mmap_wc() + * evaluates to nonzero. */ +int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + #ifndef arch_can_pci_mmap_wc #define arch_can_pci_mmap_wc() 0 #endif -- cgit v1.2.3 From e854d8b2a82ef76521ad2bed68211fde0511d417 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:56 +0100 Subject: PCI: Add arch_can_pci_mmap_io() on architectures which can mmap() I/O space This is relatively esoteric, and knowing that we don't have it makes life easier in some cases rather than just an eventual -EINVAL from pci_mmap_page_range(). Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e7bb4b62cc97..590cfcf6acf5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1636,6 +1636,9 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, #ifndef arch_can_pci_mmap_wc #define arch_can_pci_mmap_wc() 0 #endif +#ifndef arch_can_pci_mmap_io +#define arch_can_pci_mmap_io() 0 +#endif #ifndef pci_root_bus_fwnode #define pci_root_bus_fwnode(bus) NULL -- cgit v1.2.3 From f66e225828c1b046c7db1db65b0dd2d135f6a2da Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:58 +0100 Subject: PCI: Add BAR index argument to pci_mmap_page_range() In all cases we know which BAR it is. Passing it in means that arch code (or generic code; watch this space) won't have to go looking for it again. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 590cfcf6acf5..7173a677d6dd 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1630,7 +1630,8 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } * Architectures provide this function if they set HAVE_PCI_MMAP, and * it accepts the 'write_combine' argument when arch_can_pci_mmap_wc() * evaluates to nonzero. */ -int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *pdev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); #ifndef arch_can_pci_mmap_wc -- cgit v1.2.3 From f719582435afe9c7985206e42d804ea6aa315d33 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:59 +0100 Subject: PCI: Add pci_mmap_resource_range() and use it for ARM64 Starting to leave behind the legacy of the pci_mmap_page_range() interface which takes "user-visible" BAR addresses. This takes just the resource and offset. For now, both APIs coexist and depending on the platform, one is implemented as a wrapper around the other. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 7173a677d6dd..98a72abcf361 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1626,10 +1626,21 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } #include -/* Map a range of PCI memory or I/O space for a device into user space. - * Architectures provide this function if they set HAVE_PCI_MMAP, and - * it accepts the 'write_combine' argument when arch_can_pci_mmap_wc() - * evaluates to nonzero. */ +/* These two functions provide almost identical functionality. Depennding + * on the architecture, one will be implemented as a wrapper around the + * other (in drivers/pci/mmap.c). + * + * pci_mmap_resource_range() maps a specific BAR, and vm->vm_pgoff + * is expected to be an offset within that region. + * + * pci_mmap_page_range() is the legacy architecture-specific interface, + * which accepts a "user visible" resource address converted by + * pci_resource_to_user(), as used in the legacy mmap() interface in + * /proc/bus/pci/. + */ +int pci_mmap_resource_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); int pci_mmap_page_range(struct pci_dev *pdev, int bar, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -- cgit v1.2.3 From 2bea36fd1af440e1853e431459a0bf929266cd52 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:08 +0100 Subject: PCI: Add I/O BAR support to generic pci_mmap_resource_range() This will need to call into an arch-provided pci_iobar_pfn() function. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 98a72abcf361..9f302444d4ac 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1648,8 +1648,12 @@ int pci_mmap_page_range(struct pci_dev *pdev, int bar, #ifndef arch_can_pci_mmap_wc #define arch_can_pci_mmap_wc() 0 #endif + #ifndef arch_can_pci_mmap_io #define arch_can_pci_mmap_io() 0 +#define pci_iobar_pfn(pdev, bar, vma) (-EINVAL) +#else +int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma); #endif #ifndef pci_root_bus_fwnode -- cgit v1.2.3