linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] PCIe Host request to reserve IOVA
@ 2018-12-13 10:32 Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 1/3] PCI: Add dma-resv window list Srinath Mannam
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Srinath Mannam @ 2018-12-13 10:32 UTC (permalink / raw)
  To: Bjorn Helgaas, Robin Murphy, poza, Joerg Roedel,
	Lorenzo Pieralisi, Ray Jui
  Cc: bcm-kernel-feedback-list, linux-pci, iommu, linux-kernel, Srinath Mannam

Few SOCs have limitation that their PCIe host can't allow few inbound
address ranges.
Allowed inbound address ranges are listed in dma-ranges DT property and
this address ranges are required to do IOVA mapping.
Remaining address ranges have to be reserved in IOVA mapping.

PCIe Host driver of those SOCs has to list all address ranges which have
to reserve their IOVA address into PCIe host bridge resource entry list.
IOMMU framework will reserve these IOVAs while initializing IOMMU domain.

This patch set is based on Linux-4.19-rc1.

Changes from v1:
  - Addressed Oza review comments.

Srinath Mannam (3):
  PCI: Add dma-resv window list
  iommu/dma: IOVA reserve for PCI host reserve address list
  PCI: iproc: Add dma reserve resources to host

 drivers/iommu/dma-iommu.c           |  8 ++++++
 drivers/pci/controller/pcie-iproc.c | 51 ++++++++++++++++++++++++++++++++++++-
 drivers/pci/probe.c                 |  3 +++
 include/linux/pci.h                 |  1 +
 4 files changed, 62 insertions(+), 1 deletion(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] PCI: Add dma-resv window list
  2018-12-13 10:32 [PATCH v2 0/3] PCIe Host request to reserve IOVA Srinath Mannam
@ 2018-12-13 10:32 ` Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 2/3] iommu/dma: IOVA reserve for PCI host reserve address list Srinath Mannam
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Srinath Mannam @ 2018-12-13 10:32 UTC (permalink / raw)
  To: Bjorn Helgaas, Robin Murphy, poza, Joerg Roedel,
	Lorenzo Pieralisi, Ray Jui
  Cc: bcm-kernel-feedback-list, linux-pci, iommu, linux-kernel, Srinath Mannam

Add a dma_resv parameter in pci host bridge structure to hold resource
entries list of memory regions for which IOVAs have to reserve.

PCIe host driver will add resource entries to this list based on its
requirements.
Few inbound address ranges can't be allowed by few PCIe host, so those
address ranges will be add to this list to avoid IOMMU mapping.

While initializing IOMMU domain of PCI EPs connected to that host bridge
IOVAs for this given list of address ranges will be reserved.

Signed-off-by: Srinath Mannam <srinath.mannam@broadcom.com>
Based-on-patch-by: Oza Pawandeep <oza.oza@broadcom.com>
---
 drivers/pci/probe.c | 3 +++
 include/linux/pci.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ec78400..bbed0e7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -544,6 +544,7 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)
 		return NULL;
 
 	INIT_LIST_HEAD(&bridge->windows);
+	INIT_LIST_HEAD(&bridge->dma_resv);
 	bridge->dev.release = pci_release_host_bridge_dev;
 
 	/*
@@ -572,6 +573,7 @@ struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev,
 		return NULL;
 
 	INIT_LIST_HEAD(&bridge->windows);
+	INIT_LIST_HEAD(&bridge->dma_resv);
 	bridge->dev.release = devm_pci_release_host_bridge_dev;
 
 	return bridge;
@@ -581,6 +583,7 @@ EXPORT_SYMBOL(devm_pci_alloc_host_bridge);
 void pci_free_host_bridge(struct pci_host_bridge *bridge)
 {
 	pci_free_resource_list(&bridge->windows);
+	pci_free_resource_list(&bridge->dma_resv);
 
 	kfree(bridge);
 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e72ca8d..1f0a32a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -472,6 +472,7 @@ struct pci_host_bridge {
 	void		*sysdata;
 	int		busnr;
 	struct list_head windows;	/* resource_entry */
+	struct list_head dma_resv;	/* reserv dma ranges */
 	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] iommu/dma: IOVA reserve for PCI host reserve address list
  2018-12-13 10:32 [PATCH v2 0/3] PCIe Host request to reserve IOVA Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 1/3] PCI: Add dma-resv window list Srinath Mannam
@ 2018-12-13 10:32 ` Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 3/3] PCI: iproc: Add dma reserve resources to host Srinath Mannam
  2018-12-13 10:46 ` [PATCH v2 0/3] PCIe Host request to reserve IOVA poza
  3 siblings, 0 replies; 5+ messages in thread
From: Srinath Mannam @ 2018-12-13 10:32 UTC (permalink / raw)
  To: Bjorn Helgaas, Robin Murphy, poza, Joerg Roedel,
	Lorenzo Pieralisi, Ray Jui
  Cc: bcm-kernel-feedback-list, linux-pci, iommu, linux-kernel, Srinath Mannam

PCI host bridge has list of resource entries contain address ranges for
which IOVA address mapping has to be reserve.
These address ranges are the address holes in dma-ranges DT property.

It is similar to PCI IO resources address ranges reserving in IOMMU for
each EP connected to host bridge.

Signed-off-by: Srinath Mannam <srinath.mannam@broadcom.com>
Based-on-patch-by: Oza Pawandeep <oza.oza@broadcom.com>
---
 drivers/iommu/dma-iommu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 511ff9a..346da81 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -220,6 +220,14 @@ static void iova_reserve_pci_windows(struct pci_dev *dev,
 		hi = iova_pfn(iovad, window->res->end - window->offset);
 		reserve_iova(iovad, lo, hi);
 	}
+
+	/* Get reserved DMA windows from host bridge */
+	resource_list_for_each_entry(window, &bridge->dma_resv) {
+
+		lo = iova_pfn(iovad, window->res->start - window->offset);
+		hi = iova_pfn(iovad, window->res->end - window->offset);
+		reserve_iova(iovad, lo, hi);
+	}
 }
 
 static int iova_reserve_iommu_regions(struct device *dev,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] PCI: iproc: Add dma reserve resources to host
  2018-12-13 10:32 [PATCH v2 0/3] PCIe Host request to reserve IOVA Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 1/3] PCI: Add dma-resv window list Srinath Mannam
  2018-12-13 10:32 ` [PATCH v2 2/3] iommu/dma: IOVA reserve for PCI host reserve address list Srinath Mannam
@ 2018-12-13 10:32 ` Srinath Mannam
  2018-12-13 10:46 ` [PATCH v2 0/3] PCIe Host request to reserve IOVA poza
  3 siblings, 0 replies; 5+ messages in thread
From: Srinath Mannam @ 2018-12-13 10:32 UTC (permalink / raw)
  To: Bjorn Helgaas, Robin Murphy, poza, Joerg Roedel,
	Lorenzo Pieralisi, Ray Jui
  Cc: bcm-kernel-feedback-list, linux-pci, iommu, linux-kernel, Srinath Mannam

IPROC host has the limitation that it can use only those address ranges
given by dma-ranges property as inbound address.
So that the memory address holes in dma-ranges should be reserved to
allocate as DMA address.

Inbound address of host accessed by pcie devices will not be translated
before it comes to IOMMU or directly to PE.
But the limitation of this host is, access to few address ranges are
ignored. So that IOVA ranges for these address ranges have to be reserved.

All such addresses ranges are created as resource entries by parsing
dma-ranges DT parameter and add to dma_resv list of pci host bridge.

Ex:
dma-ranges = < \
  0x43000000 0x00 0x80000000 0x00 0x80000000 0x00 0x80000000 \
  0x43000000 0x08 0x00000000 0x08 0x00000000 0x08 0x00000000 \
  0x43000000 0x80 0x00000000 0x80 0x00000000 0x40 0x00000000>

In the above example of dma-ranges, memory address from
0x0 - 0x80000000,
0x100000000 - 0x800000000,
0x1000000000 - 0x8000000000 and
0x10000000000 - 0xffffffffffffffff.
are not allowed to use as inbound addresses.
So that we need to add these address ranges to dma_resv list to reserve
corresponding IOVA address ranges.

Signed-off-by: Srinath Mannam <srinath.mannam@broadcom.com>
Based-on-patch-by: Oza Pawandeep <oza.oza@broadcom.com>
---
 drivers/pci/controller/pcie-iproc.c | 51 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index 3160e93..636e92d 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -1154,25 +1154,74 @@ static int iproc_pcie_setup_ib(struct iproc_pcie *pcie,
 	return ret;
 }
 
+static int
+iproc_pcie_add_dma_resv_range(struct device *dev, struct list_head *resources,
+			      uint64_t start, uint64_t end)
+{
+	struct resource *res;
+
+	res = devm_kzalloc(dev, sizeof(struct resource), GFP_KERNEL);
+	if (!res)
+		return -ENOMEM;
+
+	res->start = (resource_size_t)start;
+	res->end = (resource_size_t)end;
+	pci_add_resource_offset(resources, res, 0);
+
+	return 0;
+}
+
 static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
 {
+	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	int ret;
+	uint64_t start, end;
+	LIST_HEAD(resources);
 
 	/* Get the dma-ranges from DT */
 	ret = of_pci_dma_range_parser_init(&parser, pcie->dev->of_node);
 	if (ret)
 		return ret;
 
+	start = 0;
 	for_each_of_pci_range(&parser, &range) {
+		end = range.pci_addr;
+		/* dma-ranges list expected in sorted order */
+		if (end < start) {
+			ret = -EINVAL;
+			goto out;
+		}
 		/* Each range entry corresponds to an inbound mapping region */
 		ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_MEM);
 		if (ret)
-			return ret;
+			goto out;
+
+		if (end - start) {
+			ret = iproc_pcie_add_dma_resv_range(pcie->dev,
+							    &resources,
+							    start, end);
+			if (ret)
+				goto out;
+		}
+		start = range.pci_addr + range.size;
 	}
 
+	end = DMA_BIT_MASK(sizeof(dma_addr_t) * BITS_PER_BYTE);
+	if (end - start) {
+		ret = iproc_pcie_add_dma_resv_range(pcie->dev, &resources,
+						    start, end);
+		if (ret)
+			goto out;
+	}
+
+	list_splice_init(&resources, &host->dma_resv);
+
 	return 0;
+out:
+	pci_free_resource_list(&resources);
+	return ret;
 }
 
 static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/3] PCIe Host request to reserve IOVA
  2018-12-13 10:32 [PATCH v2 0/3] PCIe Host request to reserve IOVA Srinath Mannam
                   ` (2 preceding siblings ...)
  2018-12-13 10:32 ` [PATCH v2 3/3] PCI: iproc: Add dma reserve resources to host Srinath Mannam
@ 2018-12-13 10:46 ` poza
  3 siblings, 0 replies; 5+ messages in thread
From: poza @ 2018-12-13 10:46 UTC (permalink / raw)
  To: Srinath Mannam
  Cc: Bjorn Helgaas, Robin Murphy, Joerg Roedel, Lorenzo Pieralisi,
	Ray Jui, bcm-kernel-feedback-list, linux-pci, iommu,
	linux-kernel

On 2018-12-13 16:02, Srinath Mannam wrote:
> Few SOCs have limitation that their PCIe host can't allow few inbound
> address ranges.
> Allowed inbound address ranges are listed in dma-ranges DT property and
> this address ranges are required to do IOVA mapping.
> Remaining address ranges have to be reserved in IOVA mapping.
> 
> PCIe Host driver of those SOCs has to list all address ranges which 
> have
> to reserve their IOVA address into PCIe host bridge resource entry 
> list.
> IOMMU framework will reserve these IOVAs while initializing IOMMU 
> domain.
> 
> This patch set is based on Linux-4.19-rc1.
> 
> Changes from v1:
>   - Addressed Oza review comments.
> 
> Srinath Mannam (3):
>   PCI: Add dma-resv window list
>   iommu/dma: IOVA reserve for PCI host reserve address list
>   PCI: iproc: Add dma reserve resources to host
> 
>  drivers/iommu/dma-iommu.c           |  8 ++++++
>  drivers/pci/controller/pcie-iproc.c | 51 
> ++++++++++++++++++++++++++++++++++++-
>  drivers/pci/probe.c                 |  3 +++
>  include/linux/pci.h                 |  1 +
>  4 files changed, 62 insertions(+), 1 deletion(-)

Looks good to me.

Reviewed-by: Oza Pawandeep <poza@codeaurora.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-12-13 10:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-13 10:32 [PATCH v2 0/3] PCIe Host request to reserve IOVA Srinath Mannam
2018-12-13 10:32 ` [PATCH v2 1/3] PCI: Add dma-resv window list Srinath Mannam
2018-12-13 10:32 ` [PATCH v2 2/3] iommu/dma: IOVA reserve for PCI host reserve address list Srinath Mannam
2018-12-13 10:32 ` [PATCH v2 3/3] PCI: iproc: Add dma reserve resources to host Srinath Mannam
2018-12-13 10:46 ` [PATCH v2 0/3] PCIe Host request to reserve IOVA poza

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).