From 03a064b431eb5cb0a91012699ac1e4d6302b327d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:25:53 +0100 Subject: xtensa/PCI: Do not mmap PCI BARs to userspace as write-through These should be uncached, not write-through. Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/xtensa/kernel/pci.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index b848cc3dc913..5b73fc2f076c 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -333,25 +333,6 @@ __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; } -/* - * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci - * device mapping. - */ -static __inline__ void -__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - int prot = pgprot_val(vma->vm_page_prot); - - /* Set to write-through */ - prot = (prot & _PAGE_CA_MASK) | _PAGE_CA_WT; -#if 0 - if (!write_combine) - prot |= _PAGE_WRITETHRU; -#endif - vma->vm_page_prot = __pgprot(prot); -} - /* * Perform the actual remap of the pages for a PCI device mapping, as * appropriate for this architecture. The region in the process to map @@ -372,7 +353,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, if (ret < 0) return ret; - __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine); + vma->vm_page_prot = pgprot_device(vma->vm_page_prot); ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start,vma->vm_page_prot); -- cgit 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 --- arch/ia64/include/asm/pci.h | 2 ++ arch/powerpc/include/asm/pci.h | 5 +++-- arch/x86/include/asm/pci.h | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index c0835b0dc722..6283758474ad 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -51,6 +51,8 @@ extern unsigned long ia64_max_iommu_merge_mask; #define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) #define HAVE_PCI_MMAP +#define arch_can_pci_mmap_wc() 1 + extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); #define HAVE_PCI_LEGACY diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 93eded8d3843..b5b68c6a10b1 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -81,8 +81,9 @@ struct vm_area_struct; int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ -#define HAVE_PCI_MMAP 1 +/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */ +#define HAVE_PCI_MMAP 1 +#define arch_can_pci_mmap_wc() 1 extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t count); diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 1411dbed5e5e..f6e22c271efa 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef __KERNEL__ @@ -102,6 +103,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq); #define HAVE_PCI_MMAP +#define arch_can_pci_mmap_wc() pat_enabled() extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -- cgit 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 --- arch/arm/include/asm/pci.h | 2 -- arch/cris/include/asm/pci.h | 3 --- arch/ia64/include/asm/pci.h | 2 -- arch/microblaze/include/asm/pci.h | 3 --- arch/mips/include/asm/pci.h | 3 --- arch/mn10300/include/asm/pci.h | 3 --- arch/parisc/include/asm/pci.h | 3 --- arch/powerpc/include/asm/pci.h | 3 --- arch/sh/include/asm/pci.h | 3 +-- arch/sparc/include/asm/pci_64.h | 4 ---- arch/unicore32/include/asm/pci.h | 2 -- arch/x86/include/asm/pci.h | 4 ---- arch/xtensa/include/asm/pci.h | 4 ---- 13 files changed, 1 insertion(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 057d381f4e57..51118a0cabbc 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -29,8 +29,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) #define PCI_DMA_BUS_IS_PHYS (1) #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h index b1b289df04c7..65198cb46c85 100644 --- a/arch/cris/include/asm/pci.h +++ b/arch/cris/include/asm/pci.h @@ -42,9 +42,6 @@ struct pci_dev; #define PCI_DMA_BUS_IS_PHYS (1) #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); - #endif /* __KERNEL__ */ diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 6283758474ad..fc60b3d139f4 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -53,8 +53,6 @@ extern unsigned long ia64_max_iommu_merge_mask; #define HAVE_PCI_MMAP #define arch_can_pci_mmap_wc() 1 -extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); #define HAVE_PCI_LEGACY extern int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma, diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 2a120bb70e54..ab381d283fb9 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -46,9 +46,6 @@ extern int pci_domain_nr(struct pci_bus *bus); extern int pci_proc_domain(struct pci_bus *bus); struct vm_area_struct; -/* Map a range of PCI memory or I/O space for a device into user space */ -int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ #define HAVE_PCI_MMAP 1 diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 30d1129d8624..3141e2a8113a 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -111,9 +111,6 @@ extern void pcibios_set_master(struct pci_dev *dev); #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); - #define HAVE_ARCH_PCI_RESOURCE_TO_USER /* diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 51159fff025a..082b6de90936 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h @@ -74,9 +74,6 @@ static inline int pci_controller_num(struct pci_dev *dev) } #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, - int write_combine); #endif /* __KERNEL__ */ diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index defebd956585..bb9ea9003e08 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -201,7 +201,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); - #endif /* __ASM_PARISC_PCI_H */ diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index b5b68c6a10b1..55887d171205 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -77,9 +77,6 @@ extern int pci_domain_nr(struct pci_bus *bus); extern int pci_proc_domain(struct pci_bus *bus); struct vm_area_struct; -/* Map a range of PCI memory or I/O space for a device into user space */ -int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */ #define HAVE_PCI_MMAP 1 diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 644314f2b1ef..46abbc9983c9 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -66,8 +66,7 @@ extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; struct pci_dev; #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); + extern void pcibios_set_master(struct pci_dev *dev); /* Dynamic DMA mapping stuff. diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 2303635158f5..516fda70a1bb 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h @@ -45,10 +45,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) #define HAVE_ARCH_PCI_GET_UNMAPPED_AREA #define get_pci_unmapped_area get_fb_unmapped_area -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, - int write_combine); - static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { return PCI_IRQ_NONE; diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h index 37e55d018de5..a51290862acd 100644 --- a/arch/unicore32/include/asm/pci.h +++ b/arch/unicore32/include/asm/pci.h @@ -17,8 +17,6 @@ #include /* for PCIBIOS_MIN_* */ #define HAVE_PCI_MMAP -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); #endif /* __KERNEL__ */ #endif diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index f6e22c271efa..734cc9411b3a 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -104,10 +104,6 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq); #define HAVE_PCI_MMAP #define arch_can_pci_mmap_wc() pat_enabled() -extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, - int write_combine); - #ifdef CONFIG_PCI extern void early_quirks(void); diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index 5d6bd932ba4e..bb5510b28754 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h @@ -46,10 +46,6 @@ struct pci_dev; #define PCI_DMA_BUS_IS_PHYS (1) -/* Map a range of PCI memory or I/O space for a device into user space */ -int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); - /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ #define HAVE_PCI_MMAP 1 -- cgit 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 --- arch/microblaze/include/asm/pci.h | 3 ++- arch/powerpc/include/asm/pci.h | 1 + arch/sparc/include/asm/pci_64.h | 1 + arch/xtensa/include/asm/pci.h | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index ab381d283fb9..efd4983cb697 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -48,7 +48,8 @@ extern int pci_proc_domain(struct pci_bus *bus); struct vm_area_struct; /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ -#define HAVE_PCI_MMAP 1 +#define HAVE_PCI_MMAP 1 +#define arch_can_pci_mmap_io() 1 extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t count); diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 55887d171205..c8975dac535f 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -80,6 +80,7 @@ struct vm_area_struct; /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */ #define HAVE_PCI_MMAP 1 +#define arch_can_pci_mmap_io() 1 #define arch_can_pci_mmap_wc() 1 extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 516fda70a1bb..b957ca5527a3 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h @@ -42,6 +42,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) /* Platform support for /proc/bus/pci/X/Y mmap()s. */ #define HAVE_PCI_MMAP +#define arch_can_pci_mmap_io() 1 #define HAVE_ARCH_PCI_GET_UNMAPPED_AREA #define get_pci_unmapped_area get_fb_unmapped_area diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index bb5510b28754..e4f366a488d3 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h @@ -47,7 +47,8 @@ struct pci_dev; #define PCI_DMA_BUS_IS_PHYS (1) /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ -#define HAVE_PCI_MMAP 1 +#define HAVE_PCI_MMAP 1 +#define arch_can_pci_mmap_io() 1 #endif /* __KERNEL__ */ -- cgit From 382746376993cfa6d6c4e546c67384201c0f3a82 Mon Sep 17 00:00:00 2001 From: Yongji Xie Date: Mon, 10 Apr 2017 19:58:13 +0800 Subject: powerpc/powernv: Override pcibios_default_alignment() to force PCI devices to be page aligned Override pcibios_default_alignment() to set default alignment to PAGE_SIZE for all PCI devices on PowerNV platform. Thus sub-page BARs would not share a page and could be mapped into guest when VFIO passthrough them. Signed-off-by: Yongji Xie Signed-off-by: Bjorn Helgaas --- arch/powerpc/include/asm/machdep.h | 2 ++ arch/powerpc/kernel/pci-common.c | 8 ++++++++ arch/powerpc/platforms/powernv/pci-ioda.c | 7 +++++++ 3 files changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 5011b69107a7..f90b22c722e1 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -173,6 +173,8 @@ struct machdep_calls { /* Called after scan and before resource survey */ void (*pcibios_fixup_phb)(struct pci_controller *hose); + resource_size_t (*pcibios_default_alignment)(void); + #ifdef CONFIG_PCI_IOV void (*pcibios_fixup_sriov)(struct pci_dev *pdev); resource_size_t (*pcibios_iov_resource_alignment)(struct pci_dev *, int resno); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index ffda24a38dda..03a7c9f58126 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -233,6 +233,14 @@ void pcibios_reset_secondary_bus(struct pci_dev *dev) pci_reset_secondary_bus(dev); } +resource_size_t pcibios_default_alignment(void) +{ + if (ppc_md.pcibios_default_alignment) + return ppc_md.pcibios_default_alignment(); + + return 0; +} + #ifdef CONFIG_PCI_IOV resource_size_t pcibios_iov_resource_alignment(struct pci_dev *pdev, int resno) { diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 6901a06da2f9..0529d5630afd 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -3287,6 +3287,11 @@ static void pnv_pci_setup_bridge(struct pci_bus *bus, unsigned long type) } } +static resource_size_t pnv_pci_default_alignment(void) +{ + return PAGE_SIZE; +} + #ifdef CONFIG_PCI_IOV static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno) @@ -3820,6 +3825,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, hose->controller_ops = pnv_pci_ioda_controller_ops; } + ppc_md.pcibios_default_alignment = pnv_pci_default_alignment; + #ifdef CONFIG_PCI_IOV ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources; ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment; -- cgit 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 --- arch/arm/kernel/bios32.c | 3 ++- arch/cris/arch-v32/drivers/pci/bios.c | 3 ++- arch/ia64/pci/pci.c | 3 ++- arch/microblaze/pci/pci-common.c | 2 +- arch/mips/pci/pci.c | 3 ++- arch/mn10300/unit-asb2305/pci-asb2305.c | 3 ++- arch/parisc/kernel/pci.c | 3 ++- arch/powerpc/kernel/pci-common.c | 3 ++- arch/sh/drivers/pci/pci.c | 3 ++- arch/sparc/kernel/pci.c | 6 +++--- arch/unicore32/kernel/pci.c | 3 ++- arch/x86/pci/i386.c | 3 ++- arch/xtensa/kernel/pci.c | 3 ++- 13 files changed, 26 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 2f0e07735d1d..a4fc3f46eeae 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -597,7 +597,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, return start; } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { if (mmap_state == pci_mmap_io) diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 212266a2c5d9..a589686d5448 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -14,7 +14,8 @@ void pcibios_set_master(struct pci_dev *dev) pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long prot; diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 8f6ac2f8ae4c..053c688b15a5 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -419,7 +419,8 @@ pcibios_align_resource (void *data, const struct resource *res, } int -pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, +pci_mmap_page_range (struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long size = vma->vm_end - vma->vm_start; diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 13bc93242c0c..404fb38d06b7 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -278,7 +278,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, * * Returns a negative error code on failure, zero on success. */ -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { resource_size_t offset = diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f6325fa657fb..f189502041a6 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -58,7 +58,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, *end = rsrc->start + size; } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long prot; diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index b7ab8378964c..4abbbd54ac7d 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -211,7 +211,8 @@ void __init pcibios_resource_survey(void) pcibios_allocate_resources(1); } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long prot; diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 0903c6abd7a4..653877553acd 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -228,7 +228,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long prot; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index ffda24a38dda..6dda4a20de6e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -513,7 +513,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, * * Returns a negative error code on failure, zero on success. */ -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { resource_size_t offset = diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 84563e39a5b8..c8b36b7ceb98 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -269,7 +269,8 @@ void __ref pcibios_report_status(unsigned int status_mask, int warn) } } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { /* diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 015e55a7495d..7eceaa10836f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -862,9 +862,9 @@ static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vm * * Returns a negative error code on failure, zero on success. */ -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, - int write_combine) +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) { int ret; diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 62137d13c6f9..1b438857e91f 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -357,7 +357,8 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return 0; } -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long phys; diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 0a9f2caf358f..8ca5e5d9f251 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -411,7 +411,8 @@ static const struct vm_operations_struct pci_mmap_ops = { .access = generic_access_phys, }; -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long prot; diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 5b73fc2f076c..903963ee495d 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -343,7 +343,8 @@ __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, * * Returns a negative error code on failure, zero on success. */ -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, +int pci_mmap_page_range(struct pci_dev *dev, int bar, + struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { -- cgit 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 --- arch/arm64/include/asm/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index b9a7ba9ca44c..1fc19744ffe9 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -22,6 +22,8 @@ */ #define PCI_DMA_BUS_IS_PHYS (0) +#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 + extern int isa_dma_bridge_buggy; #ifdef CONFIG_PCI -- cgit From 00d2904ffeac067d7fe29c04edcfa0216102b4c2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:00 +0100 Subject: ARM/PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/arm/include/asm/pci.h | 1 + arch/arm/kernel/bios32.c | 20 -------------------- 2 files changed, 1 insertion(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 51118a0cabbc..396c92bcc0cf 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -29,6 +29,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) #define PCI_DMA_BUS_IS_PHYS (1) #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index a4fc3f46eeae..b259956365a0 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -597,26 +597,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, return start; } -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - /* - * Mark this as IO - */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - void __init pci_map_io_early(unsigned long pfn) { struct map_desc pci_io_desc = { -- cgit From 3efdd5fe0a363e308ed61d020f14371dfb5aab4a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:01 +0100 Subject: cris/PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas Acked-by: Jesper Nilsson --- arch/cris/arch-v32/drivers/pci/bios.c | 23 ----------------------- arch/cris/include/asm/pci.h | 1 + 2 files changed, 1 insertion(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index a589686d5448..394c2a73d5e2 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -14,29 +14,6 @@ void pcibios_set_master(struct pci_dev *dev) pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long prot; - - /* Leave vm_pgoff as-is, the PCI space address is the physical - * address on this platform. - */ - prot = pgprot_val(vma->vm_page_prot); - vma->vm_page_prot = __pgprot(prot); - - /* Write-combine setting is ignored, it is changed via the mtrr - * interfaces on this platform. - */ - if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h index 65198cb46c85..6e505332b3e3 100644 --- a/arch/cris/include/asm/pci.h +++ b/arch/cris/include/asm/pci.h @@ -42,6 +42,7 @@ struct pci_dev; #define PCI_DMA_BUS_IS_PHYS (1) #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #endif /* __KERNEL__ */ -- cgit From 35368f80403d32a993587c7f26cd3bcede3ed202 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:02 +0100 Subject: MIPS: PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/mips/include/asm/pci.h | 2 +- arch/mips/pci/pci.c | 25 ------------------------- 2 files changed, 1 insertion(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 3141e2a8113a..1000c1b4c875 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -110,7 +110,7 @@ extern unsigned long PCIBIOS_MIN_MEM; extern void pcibios_set_master(struct pci_dev *dev); #define HAVE_PCI_MMAP - +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #define HAVE_ARCH_PCI_RESOURCE_TO_USER /* diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f189502041a6..bd67ac74fe2d 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -57,28 +57,3 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, *start = fixup_bigphys_addr(rsrc->start, size); *end = rsrc->start + size; } - -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long prot; - - /* - * I/O space can be accessed via normal processor loads and stores on - * this platform but for now we elect not to do this and portable - * drivers should not do this anyway. - */ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - /* - * Ignore write-combine; for now only return uncached mappings. - */ - prot = pgprot_val(vma->vm_page_prot); - prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED; - vma->vm_page_prot = __pgprot(prot); - - return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot); -} -- cgit From 903bdbe271217f656d13767d8a3e74b8aabc54c2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:03 +0100 Subject: mn10300/PCI: Use generic pci_mmap_resource_range() This was setting vma->vm_flags |= VM_LOCKED. Not sure why... Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas Reviewed-by: David Howells --- arch/mn10300/include/asm/pci.h | 1 + arch/mn10300/unit-asb2305/pci-asb2305.c | 24 ------------------------ 2 files changed, 1 insertion(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 082b6de90936..d27654902f28 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h @@ -74,6 +74,7 @@ static inline int pci_controller_num(struct pci_dev *dev) } #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #endif /* __KERNEL__ */ diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index 4abbbd54ac7d..e0f4617c0c7a 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -210,27 +210,3 @@ void __init pcibios_resource_survey(void) pcibios_allocate_resources(0); pcibios_allocate_resources(1); } - -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long prot; - - /* Leave vm_pgoff as-is, the PCI space address is the physical - * address on this platform. - */ - vma->vm_flags |= VM_LOCKED; - - prot = pgprot_val(vma->vm_page_prot); - prot &= ~_PAGE_CACHE; - vma->vm_page_prot = __pgprot(prot); - - /* Write-combine setting is ignored */ - if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} -- cgit From 6a94ca14c389b00515b026cd35bcd074dec6f7ff Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:04 +0100 Subject: parisc: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/parisc/include/asm/pci.h | 1 + arch/parisc/kernel/pci.c | 29 ----------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index bb9ea9003e08..1de1a3f412ec 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -200,5 +200,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) } #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #endif /* __ASM_PARISC_PCI_H */ diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 653877553acd..13ee3569959a 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -227,35 +227,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, return start; } - -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long prot; - - /* - * I/O space can be accessed via normal processor loads and stores on - * this platform but for now we elect not to do this and portable - * drivers should not do this anyway. - */ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - if (write_combine) - return -EINVAL; - - /* - * Ignore write-combine; for now only return uncached mappings. - */ - prot = pgprot_val(vma->vm_page_prot); - prot |= _PAGE_NO_CACHE; - vma->vm_page_prot = __pgprot(prot); - - return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot); -} - /* * A driver is enabling the device. We make sure that all the appropriate * bits are set to allow the device to operate as the driver is expecting. -- cgit From adf7bde63f049ab0c3284a67898055bb11614c15 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:05 +0100 Subject: sh/PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/sh/drivers/pci/pci.c | 22 ---------------------- arch/sh/include/asm/pci.h | 1 + 2 files changed, 1 insertion(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c8b36b7ceb98..c99ee286b69f 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -269,28 +269,6 @@ void __ref pcibios_report_status(unsigned int status_mask, int warn) } } -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - /* - * I/O space can be accessed via normal processor loads and stores on - * this platform but for now we elect not to do this and portable - * drivers should not do this anyway. - */ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - /* - * Ignore write-combine; for now only return uncached mappings. - */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); -} - #ifndef CONFIG_GENERIC_IOMAP void __iomem *__pci_ioport_map(struct pci_dev *dev, diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 46abbc9983c9..17fa69bc814d 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -66,6 +66,7 @@ extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; struct pci_dev; #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE extern void pcibios_set_master(struct pci_dev *dev); -- cgit From 69c701ec1f97315dc0f482699f370887448e150e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:06 +0100 Subject: unicore32/PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/unicore32/include/asm/pci.h | 1 + arch/unicore32/kernel/pci.c | 24 ------------------------ 2 files changed, 1 insertion(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h index a51290862acd..ac5acdf4c4d0 100644 --- a/arch/unicore32/include/asm/pci.h +++ b/arch/unicore32/include/asm/pci.h @@ -17,6 +17,7 @@ #include /* for PCIBIOS_MIN_* */ #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #endif /* __KERNEL__ */ #endif diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 1b438857e91f..1053bca1f8aa 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -356,27 +356,3 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) } return 0; } - -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long phys; - - if (mmap_state == pci_mmap_io) - return -EINVAL; - - phys = vma->vm_pgoff; - - /* - * Mark this as IO - */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - if (remap_pfn_range(vma, vma->vm_start, phys, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} -- cgit From 5c2d5ce2ab4bd716b2125f15b2e0879143ac0563 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 12 Apr 2017 13:26:07 +0100 Subject: x86/PCI: Use generic pci_mmap_resource_range() Signed-off-by: David Woodhouse Signed-off-by: Bjorn Helgaas --- arch/x86/include/asm/pci.h | 1 + arch/x86/pci/i386.c | 48 ---------------------------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 734cc9411b3a..f513cc231151 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -104,6 +104,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq); #define HAVE_PCI_MMAP #define arch_can_pci_mmap_wc() pat_enabled() +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #ifdef CONFIG_PCI extern void early_quirks(void); diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 8ca5e5d9f251..68499cf82ccf 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -406,51 +406,3 @@ void __init pcibios_resource_survey(void) */ ioapic_insert_resources(); } - -static const struct vm_operations_struct pci_mmap_ops = { - .access = generic_access_phys, -}; - -int pci_mmap_page_range(struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - unsigned long prot; - - /* I/O space cannot be accessed via normal processor loads and - * stores on this platform. - */ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - prot = pgprot_val(vma->vm_page_prot); - - /* - * Return error if pat is not enabled and write_combine is requested. - * Caller can followup with UC MINUS request and add a WC mtrr if there - * is a free mtrr slot. - */ - if (!pat_enabled() && write_combine) - return -EINVAL; - - if (pat_enabled() && write_combine) - prot |= cachemode2protval(_PAGE_CACHE_MODE_WC); - else if (pat_enabled() || boot_cpu_data.x86 > 3) - /* - * ioremap() and ioremap_nocache() defaults to UC MINUS for now. - * To avoid attribute conflicts, request UC MINUS here - * as well. - */ - prot |= cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS); - - vma->vm_page_prot = __pgprot(prot); - - if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - vma->vm_ops = &pci_mmap_ops; - - return 0; -} -- cgit From 61eee41ae135517392d05cbf1177523a02f12727 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 7 Apr 2017 11:22:42 +0200 Subject: ia64: Remove redundant valid_mmap_phys_addr_range() from pci_mmap_page_range() We know we are within a valid MMIO BAR by the time this function gets called; there's no need to check. Signed-off-by: David Woodhouse Tested-by: Tony Luck --- arch/ia64/pci/pci.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 053c688b15a5..27020f30caa6 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -439,9 +439,6 @@ pci_mmap_page_range (struct pci_dev *dev, int bar, */ return -EINVAL; - if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) - return -EINVAL; - prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, vma->vm_page_prot); -- cgit From fcdb10d6b179fde41ca94d032afda8f4ed796b8e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 7 Apr 2017 12:01:00 +0200 Subject: ia64: Remove redundant checks for WC in pci_mmap_page_range() For a PCI MMIO BAR, phys_mem_access_prot() should always return UC or WC. And while a mixture of cached and uncached mappings is forbidden, we were already mixing WC and UC, which is OK. Just do as we're asked. Signed-off-by: David Woodhouse Tested-by: Tony Luck --- arch/ia64/pci/pci.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 27020f30caa6..7438e8c84cdd 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -423,9 +423,6 @@ pci_mmap_page_range (struct pci_dev *dev, int bar, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long size = vma->vm_end - vma->vm_start; - pgprot_t prot; - /* * I/O space cannot be accessed via normal processor loads and * stores on this platform. @@ -439,21 +436,10 @@ pci_mmap_page_range (struct pci_dev *dev, int bar, */ return -EINVAL; - prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, - vma->vm_page_prot); - - /* - * If the user requested WC, the kernel uses UC or WC for this region, - * and the chipset supports WC, we can use WC. Otherwise, we have to - * use the same attribute the kernel uses. - */ - if (write_combine && - ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC || - (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) && - efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) + if (write_combine) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); else - vma->vm_page_prot = prot; + vma->vm_page_prot = pgprot_device(vma->vm_page_prot); if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) -- cgit From d9c102de2caa733c3e718e1b032cd154a9994326 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 7 Apr 2017 12:10:53 +0200 Subject: ia64: Use generic pci_mmap_resource_range() Now that we eliminated the different behaviour in separately-reviewable commits, we can switch IA64 to the generic implementation. Signed-off-by: David Woodhouse Tested-by: Tony Luck --- arch/ia64/include/asm/pci.h | 1 + arch/ia64/pci/pci.c | 30 ------------------------------ 2 files changed, 1 insertion(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index fc60b3d139f4..6459f2d46200 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -51,6 +51,7 @@ extern unsigned long ia64_max_iommu_merge_mask; #define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) #define HAVE_PCI_MMAP +#define ARCH_GENERIC_PCI_MMAP_RESOURCE #define arch_can_pci_mmap_wc() 1 #define HAVE_PCI_LEGACY diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 7438e8c84cdd..4068bde623dc 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -418,36 +418,6 @@ pcibios_align_resource (void *data, const struct resource *res, return res->start; } -int -pci_mmap_page_range (struct pci_dev *dev, int bar, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - /* - * I/O space cannot be accessed via normal processor loads and - * stores on this platform. - */ - if (mmap_state == pci_mmap_io) - /* - * XXX we could relax this for I/O spaces for which ACPI - * indicates that the space is 1-to-1 mapped. But at the - * moment, we don't support multiple PCI address spaces and - * the legacy I/O space is not 1-to-1 mapped, so this is moot. - */ - return -EINVAL; - - if (write_combine) - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - else - vma->vm_page_prot = pgprot_device(vma->vm_page_prot); - - if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - /** * ia64_pci_get_legacy_mem - generic legacy mem routine * @bus: bus to get legacy memory base address for -- cgit From f1e209b7f80288a711268af9054a04d3f6900a6b Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 19 Apr 2017 17:48:52 +0100 Subject: ARM64: Implement pci_remap_cfgspace() interface The PCI bus specification (rev 3.0, 3.2.5 "Transaction Ordering and Posting") defines rules for PCI configuration space transactions ordering and posting, that state that configuration writes are non-posted transactions. This rule is reinforced by the ARM v8 architecture reference manual (issue A.k, Early Write Acknowledgment) that explicitly recommends that No Early Write Acknowledgment attribute should be used to map PCI configuration (write) transactions. Current ioremap interface on ARM64 implements mapping functions where the Early Write Acknowledgment hint is enabled, so they cannot be used to map PCI configuration space in a PCI specs compliant way. Implement an ARM64 specific pci_remap_cfgspace() interface that allows to map PCI config region with nGnRnE attributes, providing a remap function that complies with PCI specifications and the ARMv8 architecture reference manual recommendations. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Acked-by: Catalin Marinas Cc: Will Deacon --- arch/arm64/include/asm/io.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 0c00c87bb9dd..35b2e50f17fb 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -172,6 +172,16 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); #define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) #define iounmap __iounmap +/* + * PCI configuration space mapping function. + * + * The PCI specification disallows posted write configuration transactions. + * Add an arch specific pci_remap_cfgspace() definition that is implemented + * through nGnRnE device memory attribute as recommended by the ARM v8 + * Architecture reference manual Issue A.k B2.8.2 "Device memory". + */ +#define pci_remap_cfgspace(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRnE)) + /* * io{read,write}{16,32,64}be() macros */ -- cgit From b9cdbe6e39351f0ba6cc0c5bc218443f0898e123 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 19 Apr 2017 17:48:53 +0100 Subject: ARM: Implement pci_remap_cfgspace() interface The PCI bus specification (rev 3.0, 3.2.5 "Transaction Ordering and Posting") defines rules for PCI configuration space transactions ordering and posting, that state that configuration writes have to be non-posted transactions. Current ioremap interface on ARM provides mapping functions that provide "bufferable" writes transactions (ie ioremap uses MT_DEVICE memory type) aka posted writes, so PCI host controller drivers have no arch interface to remap PCI configuration space with memory attributes that comply with the PCI specifications for configuration space. Implement an ARM specific pci_remap_cfgspace() interface that allows to map PCI config memory regions with MT_UNCACHED memory type (ie strongly ordered - non-posted writes), providing a remap function that complies with PCI specifications for config space transactions. Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Arnd Bergmann Cc: Russell King --- arch/arm/include/asm/io.h | 10 ++++++++++ arch/arm/mm/ioremap.c | 7 +++++++ arch/arm/mm/nommu.c | 12 ++++++++++++ 3 files changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 42871fb8340e..2cfbc531f63b 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -186,6 +186,16 @@ static inline void pci_ioremap_set_mem_type(int mem_type) {} extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr); +/* + * PCI configuration space mapping function. + * + * The PCI specification does not allow configuration write + * transactions to be posted. Add an arch specific + * pci_remap_cfgspace() definition that is implemented + * through strongly ordered memory mappings. + */ +#define pci_remap_cfgspace pci_remap_cfgspace +void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size); /* * Now, pick up the machine-defined IO definitions */ diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index ff0eed23ddf1..fc91205ff46c 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -481,6 +481,13 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr) __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte)); } EXPORT_SYMBOL_GPL(pci_ioremap_io); + +void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size) +{ + return arch_ioremap_caller(res_cookie, size, MT_UNCACHED, + __builtin_return_address(0)); +} +EXPORT_SYMBOL_GPL(pci_remap_cfgspace); #endif /* diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 3b5c7aaf9c76..2a3f6002efbc 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -433,6 +433,18 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size) } EXPORT_SYMBOL(ioremap_wc); +#ifdef CONFIG_PCI + +#include + +void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size) +{ + return arch_ioremap_caller(res_cookie, size, MT_UNCACHED, + __builtin_return_address(0)); +} +EXPORT_SYMBOL_GPL(pci_remap_cfgspace); +#endif + void *arch_memremap_wb(phys_addr_t phys_addr, size_t size) { return (void *)phys_addr; -- cgit From 2c949ce38f4e81d7487f165fa3b8f77d74a2a6c4 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 27 Mar 2017 15:15:20 +0530 Subject: ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP The PCIe programming sequence in TRM suggests CLKSTCTRL of PCIe should be set to SW_WKUP. There are no issues when CLKSTCTRL is set to HW_AUTO in RC mode. However in EP mode, the host system is not able to access the MEMSPACE and setting the CLKSTCTRL to SW_WKUP fixes it. Acked-by: Tony Lindgren Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Bjorn Helgaas --- arch/arm/mach-omap2/clockdomains7xx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c index 6c679659cda5..67ebff829cf2 100644 --- a/arch/arm/mach-omap2/clockdomains7xx_data.c +++ b/arch/arm/mach-omap2/clockdomains7xx_data.c @@ -524,7 +524,7 @@ static struct clockdomain pcie_7xx_clkdm = { .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT, .wkdep_srcs = pcie_wkup_sleep_deps, .sleepdep_srcs = pcie_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain atl_7xx_clkdm = { -- cgit