Re: [PATCH 00/17] PCI resource mmap cleanup

From: David Woodhouse
Date: Fri Mar 24 2017 - 07:40:57 EST


On Wed, 2017-03-22 at 13:25 +0000, David Woodhouse wrote:
> This started out as a fairly trivial "add pci_mmap_page_range() forÂ
> ARM64" patch. But pci_mmap_page_range() is a vile interface, takingÂ
> "user visible" resource addresses converted with pci_resource_to_user()Â
> on those platforms unlucky enough to use that... and even in the *sane*Â
> sysfs-based mmap method, we convert through user addresses to call the
> platform-specific method.
>
> In most cases there's just no need for any of this crap. We can migrate
> most architectures to a generic implementation without much thought,
> and the few that aren't converted in this series can probably be added
> fairly easily too but need a little more arch-specific attention.
>
> Utterly untested for now; I'll do some testing while I deal with the
> inevitable bikeshedding.

I added PowerPC too. Rather than posting it here as patches 18/17 and
19/17 I'll just point atÂ
http://git.infradead.org/users/dwmw2/random-2.6.git/shortlog/refs/heads/pcimmap

To support pci_mmap_io I added a pci_iobar_pfn() function which the
arch must provide, to adjust vma->vm_pgoff to the physical address of
the I/O window of the appropriate PCI host controller. It looks
something like this:

int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
resource_size_t ioaddr = pci_resource_start(pdev, bar);

if (!hose)
return -EINVAL;

/* Convert to an offset within this PCI controller */
ioaddr -= (unsigned long)hose->io_base_virt - _IO_BASE;

vma->vm_pgoff += (ioaddr + hose->io_base_phys) >> PAGE_SHIFT;
return 0;
}

It looks like SPARC, xtensa and Microblaze can all do the same thing,
as they were all basically the same code in the first place.
That leaves IA64 as the last holdout, as the selection of vm_page_prot
there is rather complicated:

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))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = prot;


But I suspect it's *overcomplicated*, as the kernel should only ever be
mapping PCI memory BARs as UC or WC in the first place, so the middle
two checks in the if (write_combineâ) condition are redundant.

And if the efi_range_is_wc() check isn't gratuitous, perhaps that
should be in the generic code whenever CONFIG_EFI is set?

Tony?

> David Woodhouse (17):
> Â pci: Fix pci_mmap_fits() for HAVE_PCI_RESOURCE_TO_USER platforms
> Â pci: Fix another sanity check bug in /proc/pci mmap
> Â pci: Only allow WC mmap on prefetchable resources
> Â pci: Add arch_can_pci_mmap_wc() macro
> Â pci: Move multiple declarations of pci_mmap_page_range() to
> Â pci: Add HAVE_PCI_MMAP_IO to architectures which can mmap() I/O space
> Â pci: Use BAR index in sysfs attr->private instead of resource pointer
> Â pci: Add BAR index argument to pci_mmap_page_range()
> Â pci: Add pci_mmap_resource_range() and use it for ARM64
> Â arm: Use generic pci_mmap_resource_range()
> Â cris: Use generic pci_mmap_resource_range()
> Â mips: Use generic pci_mmap_resource_range()
> Â mn10300: Use generic pci_mmap_resource_range()
> Â parisc: Use generic pci_mmap_resource_range()
> Â sh: Use generic pci_mmap_resource_range()
> Â unicore: Use generic pci_mmap_resource_range()
> Â arm64: Do not expose PCI mmap through procfs
>
> ÂDocumentation/filesystems/sysfs-pci.txt |ÂÂ9 +++-
> Âarch/arm/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ3 +-
> Âarch/arm/kernel/bios32.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 19 -------
> Âarch/arm64/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ3 ++
> Âarch/cris/arch-v32/drivers/pci/bios.cÂÂÂ| 22 --------
> Âarch/cris/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ4 +-
> Âarch/ia64/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ4 +-
> Âarch/ia64/pci/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ3 +-
> Âarch/microblaze/include/asm/pci.hÂÂÂÂÂÂÂ|ÂÂ6 +--
> Âarch/microblaze/pci/pci-common.cÂÂÂÂÂÂÂÂ|ÂÂ2 +-
> Âarch/mips/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ5 +-
> Âarch/mips/pci/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 24 ---------
> Âarch/mn10300/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂ|ÂÂ4 +-
> Âarch/mn10300/unit-asb2305/pci-asb2305.c | 23 ---------
> Âarch/parisc/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ4 +-
> Âarch/parisc/kernel/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 28 ----------
> Âarch/powerpc/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂ|ÂÂ9 ++--
> Âarch/powerpc/kernel/pci-common.cÂÂÂÂÂÂÂÂ|ÂÂ3 +-
> Âarch/sh/drivers/pci/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 21 --------
> Âarch/sh/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ4 +-
> Âarch/sparc/include/asm/pci_64.hÂÂÂÂÂÂÂÂÂ|ÂÂ5 +-
> Âarch/sparc/kernel/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ6 +--
> Âarch/unicore32/include/asm/pci.hÂÂÂÂÂÂÂÂ|ÂÂ3 +-
> Âarch/unicore32/kernel/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂ| 23 ---------
> Âarch/x86/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ6 +--
> Âarch/x86/pci/i386.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ3 +-
> Âarch/xtensa/include/asm/pci.hÂÂÂÂÂÂÂÂÂÂÂ| 11 ++--
> Âarch/xtensa/kernel/pci.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ5 +-
> Âdrivers/pci/MakefileÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ|ÂÂ2 +-
> Âdrivers/pci/mmap.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 90 +++++++++++++++++++++++++++++++++
> Âdrivers/pci/pci-sysfs.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 77 +++++++++++++---------------
> Âdrivers/pci/proc.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 55 ++++++++++++++------
> Âinclude/linux/pci.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ| 19 +++++++
> Â33 files changed, 233 insertions(+), 272 deletions(-)
> Âcreate mode 100644 drivers/pci/mmap.c
>

Attachment: smime.p7s
Description: S/MIME cryptographic signature