linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: Yinghai Lu <yinghai@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>,
	Matthew Wilcox <willy@linux.intel.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	David Miller <davem@davemloft.net>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Wei Yang <weiyang@linux.vnet.ibm.com>, TJ <linux@iam.tj>,
	Yijing Wang <wangyijing@huawei.com>,
	Khalid Aziz <khalid.aziz@oracle.com>,
	"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v10 02/59] sparc/PCI: Use correct bus address to resource offset
Date: Sat, 12 Mar 2016 05:26:35 -0600	[thread overview]
Message-ID: <20160312112634.GB27552@localhost> (raw)
In-Reply-To: <CAE9FiQX=ecBEuABmkfGwN3p3H5YU-XbXDguKKbArj6weQbbAPA@mail.gmail.com>

On Sat, Mar 12, 2016 at 12:22:06AM -0800, Yinghai Lu wrote:
> On Thu, Mar 10, 2016 at 10:24 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> >> pci_sun4v f02ae7f8: PCI host bridge to bus 0000:00
> >> pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
> >
> > Just double-checking that your ioport space really contains 256M ports.
> > It's fine if it does; it's just a little unusual.
> 
> Then according to davem, OF said so.
> ...
> >> @@ -733,30 +733,28 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
> >>  static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struct *vma,
> >>                                     enum pci_mmap_state mmap_state)
> >>  {
> >> -     struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
> >> -     unsigned long space_size, user_offset, user_size;
> >> -
> >> -     if (mmap_state == pci_mmap_io) {
> >> -             space_size = resource_size(&pbm->io_space);
> >> -     } else {
> >> -             space_size = resource_size(&pbm->mem_space);
> >> -     }
> >> +     unsigned long user_offset, user_size;
> >> +     struct resource res, *root_bus_res;
> >> +     struct pci_bus_region region;
> >>
> >>       /* Make sure the request is in range. */
> >>       user_offset = vma->vm_pgoff << PAGE_SHIFT;
> >>       user_size = vma->vm_end - vma->vm_start;
> >>
> >> -     if (user_offset >= space_size ||
> >> -         (user_offset + user_size) > space_size)
> >> +     region.start = user_offset;
> >> +     region.end = user_offset + user_size - 1;
> >> +     memset(&res, 0, sizeof(res));
> >> +     if (mmap_state == pci_mmap_io)
> >> +             res.flags = IORESOURCE_IO;
> >> +     else
> >> +             res.flags = IORESOURCE_MEM;
> >> +
> >> +     pcibios_bus_to_resource(pdev->bus, &res, &region);
> >> +     root_bus_res = pci_find_root_bus_resource(pdev->bus, &res);
> >> +     if (!root_bus_res)
> >>               return -EINVAL;
> >>
> >> -     if (mmap_state == pci_mmap_io) {
> >> -             vma->vm_pgoff = (pbm->io_space.start +
> >> -                              user_offset) >> PAGE_SHIFT;
> >> -     } else {
> >> -             vma->vm_pgoff = (pbm->mem_space.start +
> >> -                              user_offset) >> PAGE_SHIFT;
> >> -     }
> >> +     vma->vm_pgoff = res.start >> PAGE_SHIFT;
> >>
> >>       return 0;
> >
> > This needs to explain what's unique about sparc that means it needs
> > pci_find_root_bus_resource() when no other arch does.
> 
> I just follow the old code to get pbm->io_offset, mem_offset, mem64_offset.
> at the same use that to check boundary with that checking.

That's not enough of a reason to add a new interface.  I don't think
there is anything unique about sparc, so if the existing interfaces
work for all the other arches, they ought to work for sparc too.

> > This is used in the pci_mmap_resource() path.  I don't understand how
> > that path works on sparc.  I tried to work through the simple case of
> > a user mapping the first 4096 bytes of a BAR.  Assume the BAR is 4096
> > bytes in size:
> >
> >   # User does something like this:
> >   #   mmap(NULL, 4096, ..., "/sys/.../resourceN", 0);
> >
> >   pci_mmap_resource
> >
> >     # At entry, "vma->vm_pgoff" is the offset into the BAR (in pages).
> >     # In this case, the user wants the first page of the BAR, so
> >     # vma->vm_pgoff == 0.
> >
> >     # "res" is the the pdev->resource[n], which contains the CPU
> >     # physical address of the BAR.
> >
> >     pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)
> >       start = vma->vm_pgoff           # == 0
> >       size = 4096
> >       pci_start = 0                   # offset into BAR (PCI_MMAP_SYSFS case)
> >
> >       # we return 1 because [0x0000-0x0fff] is a valid area in this
> >       # BAR
> >
> >     pci_resource_to_user(pdev, i, res, &start, &end);
> >
> >     # On most platforms: pci_resource_to_user() copies res->start to
> >     # *start, so "start" is the CPU physical address of the
> >     # BAR.
> >
> >     # On sparc: pci_resource_to_user() calls pcibios_resource_to_bus()
> >     # (see below), so "start" is the PCI bus address of the BAR.
> >
> >     vma->vm_pgoff += start >> PAGE_SHIFT;
> >
> >     # On most platforms: "vma->vm_pgoff" is now the CPU physical page
> >     # number of the part of the BAR we're mapping.
> >
> >     # On sparc: "vma->vm_pgoff" is the PCI bus page number of the part
> >     # of the BAR we're mapping.  This seems wrong: doesn't the VM
> >     # system assume vm_pgoff is a CPU physical page number?
> >
> >     if (... && iomem_is_exclusive(start))
> >
> >     # On most platforms, "start" is a CPU physical address, and
> >     # iomem_is_exclusive() looks it up in the iomem_resource tree,
> >     # which contains resources of CPU physical addresses.
> >
> >     # On sparc, "start" is a PCI bus address.  How can this work in
> >     # iomem_is_exclusive()?  I assume the resources in iomem_resource
> >     # still contain CPU physical addresses, not PCI bus addresses,
> >     # don't they?
> 
> Good findings, that would break the sparc for a while.
> (we should use res->start instead)

We haven't even gotten to the part that your patch changes.  If my
analysis is correct, this call to iomem_is_exclusive() is already
broken on sparc.  I think we need the following patches:

commit 4688b92991e43ab3b286d11e8f388b1b39d10b1b
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Sat Mar 12 04:27:39 2016 -0600

    PCI: Fix iomem_is_exclusive() checking in pci_mmap_resource()
    
    iomem_is_exclusive() requires a CPU physical address, but on some arches we
    supplied a PCI bus address instead.
    
    On most arches, pci_resource_to_user(res) returns "res->start", which is a
    CPU physical address.  But on microblaze, mips, powerpc, and sparc, it
    returns the PCI bus address corresponding to "res->start".
    
    The result is that pci_mmap_resource() may fail when it shouldn't (if the
    bus address happens to match an existing resource), or it may succeed when
    it should fail (if the resource is exclusive but the bus address doesn't
    match it).
    
    Call iomem_is_exclusive() with "res->start", which is always a CPU physical
    address, not the result of pci_resource_to_user().
    
    Fixes: e8de1481fd71 ("resource: allow MMIO exclusivity for device drivers")
    Suggested-by: Yinghai Lu <yinghai@kernel.org>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    CC: Arjan van de Ven <arjan@linux.intel.com>

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 95d9e7b..1559d67 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1004,6 +1004,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
+	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+		return -EINVAL;
+
 	if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
 		WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
 			current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
@@ -1020,10 +1023,6 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	pci_resource_to_user(pdev, i, res, &start, &end);
 	vma->vm_pgoff += start >> PAGE_SHIFT;
 	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
-
-	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(start))
-		return -EINVAL;
-
 	return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
 }
 
commit fd88769b8c4d840278137f9ca3968da5aa09c97f
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Sat Mar 12 05:10:11 2016 -0600

    alpha/PCI: Only check iomem_is_exclusive() for IORESOURCE_MEM, not IORESOURCE_IO
    
    The alpha pci_mmap_resource() is used for both IORESOURCE_MEM and
    IORESOURCE_IO resources, but iomem_is_exclusive() is only applicable for
    IORESOURCE_MEM.
    
    Call iomem_is_exclusive() only for IORESOURCE_MEM resources, and do it
    earlier to match the generic version of pci_mmap_resource().
    
    Fixes: 10a0ef39fbd1 ("PCI/alpha: pci sysfs resources")
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    CC: Ivan Kokshaysky <ink@jurassic.park.msu.ru>

diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 99e8d47..92c0d46 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -77,10 +77,10 @@ static int pci_mmap_resource(struct kobject *kobj,
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
-	if (!__pci_mmap_fits(pdev, i, vma, sparse))
+	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
 		return -EINVAL;
 
-	if (iomem_is_exclusive(res->start))
+	if (!__pci_mmap_fits(pdev, i, vma, sparse))
 		return -EINVAL;
 
 	pcibios_resource_to_bus(pdev->bus, &bar, res);

  reply	other threads:[~2016-03-12 11:26 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-25  2:11 [PATCH v10 00/59] PCI: Resource allocation cleanup for v4.6 Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 01/59] PCI: Add pci_find_root_bus_resource() Yinghai Lu
2016-03-10  3:54   ` Bjorn Helgaas
2016-03-11 21:21     ` Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 02/59] sparc/PCI: Use correct bus address to resource offset Yinghai Lu
2016-03-10 18:24   ` Bjorn Helgaas
2016-03-10 19:47     ` David Miller
2016-03-12  8:22     ` Yinghai Lu
2016-03-12 11:26       ` Bjorn Helgaas [this message]
2016-03-19  6:01         ` Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 03/59] sparc/PCI: Reserve legacy mmio after PCI mmio Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 04/59] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 05/59] sparc/PCI: Keep resource idx order with bridge register number Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 06/59] PCI: Kill wrong quirk about M7101 Yinghai Lu
2016-03-10 17:40   ` Bjorn Helgaas
2016-03-11 22:08     ` Yinghai Lu
2016-03-12  1:06       ` Linus Torvalds
2016-03-12  7:52       ` Meelis Roos
2016-03-12  8:26         ` Yinghai Lu
2016-03-12  8:39           ` Meelis Roos
2016-04-25 20:57             ` Bjorn Helgaas
2016-02-25  2:11 ` [PATCH v10 07/59] PCI: Ignore BAR for ALi M1533 PCI-ISA bridge Yinghai Lu
2016-03-10 17:54   ` Bjorn Helgaas
2016-03-11 22:21     ` Yinghai Lu
2016-02-25  2:11 ` [PATCH v10 08/59] powerpc/PCI: Keep resource idx order with bridge register number Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 09/59] powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 10/59] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 11/59] PCI: Check pref compatible bit for mem64 resource of PCIe device Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 12/59] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64 Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 13/59] PCI: Add has_mem64 for struct host_bridge Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 14/59] PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64 Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 15/59] PCI: Restore pref MMIO allocation logic for host bridge without mmio64 Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 16/59] PCI: Don't release fixed resource for realloc Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 17/59] PCI: Claim fixed resource during remove/rescan path Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 18/59] PCI: Set resource to FIXED for LSI devices Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 19/59] PCI: Separate realloc list checking after allocation Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 20/59] PCI: Treat optional as required in first try for bridge rescan Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 21/59] PCI: Get new realloc size for bridge for last try Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 22/59] PCI: Don't release sibling bridge resources during hotplug Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 23/59] PCI: Cleanup res_to_dev_res() printout Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 24/59] PCI: Reuse res_to_dev_res() in reassign_resources_sorted() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 25/59] PCI: Use correct align for optional only resources during sorting Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 26/59] PCI: Optimize bus min_align/size calculation during sizing Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 27/59] PCI: Optimize bus align/size calculation for optional " Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 28/59] PCI: Don't add too much optional size for hotplug bridge MMIO Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 29/59] PCI: Reorder resources list for required/optional resources Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 30/59] PCI: Remove duplicated code for resource sorting Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 31/59] PCI: Rename pdev_sort_resources() to pdev_assign_resources_prepare() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 32/59] PCI: Treat ROM resource as optional during realloc Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 33/59] PCI: Add debug printout during releasing partial assigned resources Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 34/59] PCI: Simplify res reference using in __assign_resources_sorted() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 35/59] PCI: Add __add_to_list() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 36/59] PCI: Cache window alignment value during bus sizing Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 37/59] PCI: Check if resource is allocated before trying to assign one Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 38/59] PCI: Separate out save_resources()/restore_resources() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 39/59] PCI: Move comment to pci_need_to_release() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 40/59] PCI: Separate required+optional assigning to another function Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 41/59] PCI: Skip required+optional if there is no optional Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 42/59] PCI: Move saved required resource list out of required+optional assigning Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 43/59] PCI: Add alt_size ressource allocation support Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 44/59] PCI: Add support for more than two alt_size entries under same bridge Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 45/59] PCI: Fix size calculation with old_size on rescan path Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 46/59] PCI: Don't add too much optional size for hotplug bridge io Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 47/59] PCI: Move ISA io port align out of calculate_iosize() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 48/59] PCI: Don't add too much io port for hotplug bridge with old size Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 49/59] PCI: Unify calculate_size() for io port and MMIO Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 50/59] PCI: Allow bridge optional only io port resource required size to be 0 Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 51/59] PCI: Unify skip_ioresource_align() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 52/59] PCI: Kill macro checking for bus io port sizing Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 53/59] resources: Make allocate_resource() return best fit resource Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 54/59] PCI, x86: Allocate from high in available window for MMIO Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 55/59] PCI: Add debug print out for min_align and alt_size Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 56/59] PCI, x86: Add pci=assign_pref_bars to reallocate pref BARs Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 57/59] PCI: Introduce resource_disabled() Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 58/59] PCI: Don't set flags to 0 when assign resource fail Yinghai Lu
2016-02-25  2:12 ` [PATCH v10 59/59] PCI: Only try to assign io port only for root bus that support it Yinghai Lu
2016-03-10 18:30 ` [PATCH v10 00/59] PCI: Resource allocation cleanup for v4.6 Bjorn Helgaas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160312112634.GB27552@localhost \
    --to=helgaas@kernel.org \
    --cc=arjan@linux.intel.com \
    --cc=benh@kernel.crashing.org \
    --cc=bhelgaas@google.com \
    --cc=davem@davemloft.net \
    --cc=khalid.aziz@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@iam.tj \
    --cc=wangyijing@huawei.com \
    --cc=weiyang@linux.vnet.ibm.com \
    --cc=willy@linux.intel.com \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).