All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Helgaas <bhelgaas@google.com>
To: wdavis@nvidia.com
Cc: Joerg Roedel <joro@8bytes.org>,
	Terence Ripperda <tripperda@nvidia.com>,
	John Hubbard <jhubbard@nvidia.com>,
	Jerome Glisse <jglisse@redhat.com>,
	Mark Hounschell <markh@compro.net>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Jonathan Corbet <corbet@lwn.net>,
	"David S. Miller" <davem@davemloft.net>,
	Yijing Wang <wangyijing@huawei.com>,
	Alex Williamson <alex.williamson@redhat.com>,
	Dave Jiang <dave.jiang@intel.com>,
	iommu@lists.linux-foundation.org, linux-pci@vger.kernel.org
Subject: Re: [PATCH v3 7/7] x86: add pci-nommu implementation of map_resource
Date: Wed, 1 Jul 2015 11:45:20 -0500	[thread overview]
Message-ID: <20150701164520.GC13409@google.com> (raw)
In-Reply-To: <1432919686-32306-8-git-send-email-wdavis@nvidia.com>

On Fri, May 29, 2015 at 12:14:46PM -0500, wdavis@nvidia.com wrote:
> From: Will Davis <wdavis@nvidia.com>
> 
> Lookup the bus address of the resource by finding the parent host bridge,
> which may be different than the parent host bridge of the target device.
> 
> Signed-off-by: Will Davis <wdavis@nvidia.com>
> ---
>  arch/x86/kernel/pci-nommu.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
> index da15918..6384482 100644
> --- a/arch/x86/kernel/pci-nommu.c
> +++ b/arch/x86/kernel/pci-nommu.c
> @@ -38,6 +38,37 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
>  	return bus;
>  }
>  
> +static dma_addr_t nommu_map_resource(struct device *dev, struct resource *res,
> +				     unsigned long offset, size_t size,
> +				     enum dma_data_direction dir,
> +				     struct dma_attrs *attrs)
> +{
> +	struct pci_bus *bus;
> +	struct pci_host_bridge *bridge;
> +	struct resource_entry *window;
> +	resource_size_t bus_offset = 0;
> +	dma_addr_t dma_address;
> +
> +	/* Find the parent host bridge of the resource, and determine the
> +	 * relative offset.
> +	 */
> +	list_for_each_entry(bus, &pci_root_buses, node) {
> +		bridge = to_pci_host_bridge(bus->bridge);
> +		resource_list_for_each_entry(window, &bridge->windows) {
> +			if (resource_contains(window->res, res))
> +				bus_offset = window->offset;
> +		}
> +	}

I don't think this is safe.  Assume we have the following topology, and
we want to set it up so 0000:00:00.0 can perform peer-to-peer DMA to
0001:00:01.0:

  pci_bus 0000:00: root bus resource [mem 0x80000000-0xffffffff] (bus address [0x80000000-0xffffffff])
  pci 0000:00:00.0: ...
  pci_bus 0001:00: root bus resource [mem 0x180000000-0x1ffffffff] (bus address [0x80000000-0xffffffff])
  pci 0001:00:01.0: reg 0x10: [mem 0x180000000-0x1803fffff 64bit]

I assume the way this works is that the driver for 0000:00:00.0 would call
this function with 0001:00:01.0 and [mem 0x180000000-0x1803fffff 64bit].

We'll figure out that the resource belongs to 0001:00, so we return a
dma_addr of 0x80000000, which is the bus address as seen by 0001:00:01.0.
But if 0000:00:00.0 uses that address, it refers to something in the
0000:00 hierarchy, not the 0001:00 hierarchy.

We talked about pci_bus_address() and pcibios_resource_to_bus() earlier.
What's the subtlety that makes them unusable here?  I'd rather not add more
uses of the pci_root_buses list if we can avoid it.

> +	dma_address = (res->start - bus_offset) + offset;
> +	WARN_ON(size == 0);
> +	if (!check_addr("map_resource", dev, dma_address, size))
> +		return DMA_ERROR_CODE;
> +	flush_write_buffers();
> +	return dma_address;
> +}
> +
> +

You added an extra blank line here (there was already an extra one before
nommu_sync_sg_for_device(), which is probably what you copied).

>  /* Map a set of buffers described by scatterlist in streaming
>   * mode for DMA.  This is the scatter-gather version of the
>   * above pci_map_single interface.  Here the scatter gather list
> @@ -93,6 +124,7 @@ struct dma_map_ops nommu_dma_ops = {
>  	.free			= dma_generic_free_coherent,
>  	.map_sg			= nommu_map_sg,
>  	.map_page		= nommu_map_page,
> +	.map_resource		= nommu_map_resource,
>  	.sync_single_for_device = nommu_sync_single_for_device,
>  	.sync_sg_for_device	= nommu_sync_sg_for_device,
>  	.is_phys		= 1,
> -- 
> 2.4.0
> 

  reply	other threads:[~2015-07-01 16:45 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-29 17:14 [PATCH v3 0/7] IOMMU/DMA map_resource support for peer-to-peer wdavis
2015-05-29 17:14 ` wdavis
2015-05-29 17:14 ` [PATCH v3 1/7] dma-debug: add checking for map/unmap_resource wdavis
2015-05-29 17:14   ` wdavis
2015-05-29 17:14 ` [PATCH v3 2/7] DMA-API: Introduce dma_(un)map_resource wdavis
2015-05-29 17:14   ` wdavis
2015-05-29 17:14 ` [PATCH v3 3/7] dma-mapping: pci: add pci_(un)map_resource wdavis
2015-05-29 17:14   ` wdavis
2015-07-01 16:06   ` Bjorn Helgaas
     [not found]     ` <20150701160606.GA13409-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2015-07-01 18:31       ` Bjorn Helgaas
2015-07-01 18:31         ` Bjorn Helgaas
2015-07-06 15:16         ` Will Davis
2015-07-06 15:16           ` Will Davis
2015-05-29 17:14 ` [PATCH v3 4/7] DMA-API: Add dma_(un)map_resource() documentation wdavis
2015-05-29 17:14   ` wdavis
2015-05-29 17:14 ` [PATCH v3 5/7] iommu/amd: Implement (un)map_resource wdavis
2015-05-29 17:14   ` wdavis
2015-07-01 16:13   ` Bjorn Helgaas
2015-05-29 17:14 ` [PATCH v3 6/7] iommu/vt-d: implement (un)map_resource wdavis
2015-05-29 17:14   ` wdavis
2015-05-29 17:14 ` [PATCH v3 7/7] x86: add pci-nommu implementation of map_resource wdavis
2015-05-29 17:14   ` wdavis
2015-07-01 16:45   ` Bjorn Helgaas [this message]
2015-07-01 18:14     ` Will Davis
2015-07-01 18:14       ` Will Davis
2015-07-07 15:34       ` Bjorn Helgaas
     [not found]         ` <20150707153428.GA14784-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2015-07-07 18:59           ` Will Davis
2015-07-07 18:59             ` Will Davis
2015-06-15 15:49 ` [PATCH v3 0/7] IOMMU/DMA map_resource support for peer-to-peer William Davis
2015-07-01 15:11   ` William Davis

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=20150701164520.GC13409@google.com \
    --to=bhelgaas@google.com \
    --cc=alex.williamson@redhat.com \
    --cc=corbet@lwn.net \
    --cc=dave.jiang@intel.com \
    --cc=davem@davemloft.net \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jglisse@redhat.com \
    --cc=jhubbard@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=markh@compro.net \
    --cc=tripperda@nvidia.com \
    --cc=wangyijing@huawei.com \
    --cc=wdavis@nvidia.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.