All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Niklas Söderlund" <niklas.soderlund@ragnatech.se>
To: Magnus Damm <magnus.damm@gmail.com>
Cc: linux-renesas-soc@vger.kernel.org
Subject: Re: [PATCH/RFC] iommu/ipmmu-vmsa: IPMMU SYS-DMAC iova mapping workaround
Date: Tue, 27 Sep 2016 08:20:18 +0200	[thread overview]
Message-ID: <20160927062018.GD16263@bigcity.dyn.berto.se> (raw)
In-Reply-To: <20160920115433.14772.84308.sendpatchset@little-apple>

Hi Magnus,

On 2016-09-20 20:54:33 +0900, Magnus Damm wrote:
> From: Magnus Damm <damm+renesas@opensource.se>
> 
> Here's some prototype code that works around the lack of software
> support for mapping I/O devices to the SYS-DMAC hardware via the
> DMA Engine framework when using IOMMU.
> 
> The code itself is one big layering violation that goes through
> the DT and unconditionally maps I/O devices using DMACs via the
> IPMMU device instance into iova space with a 1:1 mapping.
> 
> This very short term prototype will for instance automatically make
> the SCIF serial port function with the IPMMU hardware in case the
> SYS-DMAC is hooked up to the IPMMU device.
> 
> Not to be confused with the more long term solution to allow the
> DMA Engine framework to map I/O device memory dynamically.

Good news, Vinod queued the dma_{map,unmap}_resource API and rcar-dmac 
usage of it yesterday \o/.

> 
> Not-Yet-Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
> ---
> 
>  Applies on top of: renesas-drivers-2016-09-13-v4.8-rc6
> 
>  drivers/iommu/ipmmu-vmsa.c |   75 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 75 insertions(+)
> 
> --- 0001/drivers/iommu/ipmmu-vmsa.c
> +++ work/drivers/iommu/ipmmu-vmsa.c	2016-09-20 20:03:37.620607110 +0900
> @@ -19,6 +19,7 @@
>  #include <linux/iommu.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/of_iommu.h>
>  #include <linux/platform_device.h>
>  #include <linux/sizes.h>
> @@ -625,6 +626,78 @@ static void ipmmu_domain_free(struct iom
>  	kfree(domain);
>  }
>  
> +static void ipmmu_workaround_map(struct iommu_domain *io_domain,
> +				 struct device *dma_dev, struct resource *res)
> +{
> +	phys_addr_t phys_addr;
> +
> +	dev_info(dma_dev, "map %pr\n", res);
> +
> +	phys_addr = iommu_iova_to_phys(io_domain, res->start);
> +	if (phys_addr)
> +		return;
> +
> +	iommu_map(io_domain, res->start, res->start,
> +		  ALIGN(resource_size(res), SZ_4K),
> +		  IOMMU_READ | IOMMU_WRITE);
> +}
> +
> +static void ipmmu_workaround_dt(struct iommu_domain *io_domain,
> +				struct device *dev,
> +				void (*match)(struct iommu_domain *io_domain,
> +					      struct device *dma_dev,
> +					      struct resource *res))
> +{
> +	struct device_node *np = NULL;
> +	struct of_phandle_args dma_spec;
> +	struct resource r;
> +	int i, cnt;
> +	bool found;
> +
> +	/* Locate I/O devices using the DMAC and map their registers */
> +	while ((np = of_find_all_nodes(np))) {
> +		if (!of_find_property(np, "dmas", NULL))
> +			continue;
> +
> +		cnt = of_property_count_strings(np, "dma-names");
> +		if (cnt < 0)
> +			continue;
> +
> +		found = false;
> +		for (i = 0; i < cnt; i++) {
> +			if (of_parse_phandle_with_args(np, "dmas",
> +						       "#dma-cells", i,
> +						       &dma_spec))
> +				continue;
> +
> +			if (dma_spec.np == dev->of_node)
> +				found = true;
> +
> +			of_node_put(dma_spec.np);
> +		}
> +
> +		if (!found)
> +			continue;
> +
> +		i = 0;
> +		while (!of_address_to_resource(np, i, &r)) {
> +			match(io_domain, dev, &r);
> +			i++;
> +		}
> +	}
> +}
> +
> +static void ipmmu_workaround(struct iommu_domain *io_domain,
> +			     struct device *dev)
> +{
> +	/* only apply workaround for DMA controllers */
> +	if (!strstr(dev_name(dev), "dma-controller"))
> +		return;
> +
> +	dev_info(dev, "Adding iommu workaround to map I/O devices for DMACs\n");
> +	ipmmu_workaround_dt(io_domain, dev, ipmmu_workaround_map);
> +}
> +
>  static int ipmmu_attach_device(struct iommu_domain *io_domain,
>  			       struct device *dev)
>  {
> @@ -678,6 +751,8 @@ static int ipmmu_attach_device(struct io
>  	if (ret < 0)
>  		return ret;
>  
> +	ipmmu_workaround(io_domain, dev);
> +
>  	for (i = 0; i < archdata->num_utlbs; ++i)
>  		ipmmu_utlb_enable(domain, archdata->utlbs[i]);
>  

-- 
Regards,
Niklas S�derlund

  reply	other threads:[~2016-09-27  6:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-20 11:54 [PATCH/RFC] iommu/ipmmu-vmsa: IPMMU SYS-DMAC iova mapping workaround Magnus Damm
2016-09-27  6:20 ` Niklas Söderlund [this message]
2016-09-27  6:43   ` Magnus Damm
2016-09-27 10:11     ` Niklas Söderlund

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=20160927062018.GD16263@bigcity.dyn.berto.se \
    --to=niklas.soderlund@ragnatech.se \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=magnus.damm@gmail.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.