| From dhobsong@igel.co.jp Mon Oct 29 00:53:04 2012 |
| From: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Date: Mon, 29 Oct 2012 16:50:47 +0900 |
| Subject: [PATCH v2 30/58] iommu/core: pass a user-provided token to fault handlers |
| To: greg@kroah.com, laurent.pinchart@ideasonboard.com, horms@verge.net.au |
| Cc: ltsi-dev@lists.linuxfoundation.org, dhobsong@igel.co.jp |
| Message-ID: <1351497075-32717-31-git-send-email-dhobsong@igel.co.jp> |
| |
| |
| From: Ohad Ben-Cohen <ohad@wizery.com> |
| |
| Sometimes a single IOMMU user may have to deal with several |
| different IOMMU devices (e.g. remoteproc). |
| |
| When an IOMMU fault happens, such users have to regain their |
| context in order to deal with the fault. |
| |
| Users can't use the private fields of neither the iommu_domain nor |
| the IOMMU device, because those are already used by the IOMMU core |
| and low level driver (respectively). |
| |
| This patch just simply allows users to pass a private token (most |
| notably their own context pointer) to iommu_set_fault_handler(), |
| and then makes sure it is provided back to the users whenever |
| an IOMMU fault happens. |
| |
| The patch also adopts remoteproc to the new fault handling |
| interface, but the real functionality using this (recovery of |
| remote processors) will only be added later in a subsequent patch |
| set. |
| |
| Cc: Fernando Guzman Lugo <fernando.lugo@ti.com> |
| Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> |
| Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> |
| (cherry picked from commit 77ca23323594589ac8cba1c8d59bfe7e85d3cb8b) |
| |
| Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| --- |
| drivers/iommu/iommu.c | 5 ++++- |
| drivers/remoteproc/remoteproc_core.c | 4 ++-- |
| include/linux/iommu.h | 10 ++++++---- |
| 3 files changed, 12 insertions(+), 7 deletions(-) |
| |
| diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c |
| index 2198b2d..8b9ded8 100644 |
| --- a/drivers/iommu/iommu.c |
| +++ b/drivers/iommu/iommu.c |
| @@ -119,6 +119,7 @@ EXPORT_SYMBOL_GPL(iommu_present); |
| * iommu_set_fault_handler() - set a fault handler for an iommu domain |
| * @domain: iommu domain |
| * @handler: fault handler |
| + * @token: user data, will be passed back to the fault handler |
| * |
| * This function should be used by IOMMU users which want to be notified |
| * whenever an IOMMU fault happens. |
| @@ -127,11 +128,13 @@ EXPORT_SYMBOL_GPL(iommu_present); |
| * error code otherwise. |
| */ |
| void iommu_set_fault_handler(struct iommu_domain *domain, |
| - iommu_fault_handler_t handler) |
| + iommu_fault_handler_t handler, |
| + void *token) |
| { |
| BUG_ON(!domain); |
| |
| domain->handler = handler; |
| + domain->handler_token = token; |
| } |
| EXPORT_SYMBOL_GPL(iommu_set_fault_handler); |
| |
| diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c |
| index 7591b97..0142e52 100644 |
| --- a/drivers/remoteproc/remoteproc_core.c |
| +++ b/drivers/remoteproc/remoteproc_core.c |
| @@ -78,7 +78,7 @@ typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail); |
| * the recovery of the remote processor. |
| */ |
| static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, |
| - unsigned long iova, int flags) |
| + unsigned long iova, int flags, void *token) |
| { |
| dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags); |
| |
| @@ -117,7 +117,7 @@ static int rproc_enable_iommu(struct rproc *rproc) |
| return -ENOMEM; |
| } |
| |
| - iommu_set_fault_handler(domain, rproc_iommu_fault); |
| + iommu_set_fault_handler(domain, rproc_iommu_fault, rproc); |
| |
| ret = iommu_attach_device(domain, dev); |
| if (ret) { |
| diff --git a/include/linux/iommu.h b/include/linux/iommu.h |
| index d937580..450293f 100644 |
| --- a/include/linux/iommu.h |
| +++ b/include/linux/iommu.h |
| @@ -35,12 +35,13 @@ struct iommu_domain; |
| #define IOMMU_FAULT_WRITE 0x1 |
| |
| typedef int (*iommu_fault_handler_t)(struct iommu_domain *, |
| - struct device *, unsigned long, int); |
| + struct device *, unsigned long, int, void *); |
| |
| struct iommu_domain { |
| struct iommu_ops *ops; |
| void *priv; |
| iommu_fault_handler_t handler; |
| + void *handler_token; |
| }; |
| |
| #define IOMMU_CAP_CACHE_COHERENCY 0x1 |
| @@ -95,7 +96,7 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, |
| extern int iommu_domain_has_cap(struct iommu_domain *domain, |
| unsigned long cap); |
| extern void iommu_set_fault_handler(struct iommu_domain *domain, |
| - iommu_fault_handler_t handler); |
| + iommu_fault_handler_t handler, void *token); |
| extern int iommu_device_group(struct device *dev, unsigned int *groupid); |
| |
| /** |
| @@ -132,7 +133,8 @@ static inline int report_iommu_fault(struct iommu_domain *domain, |
| * invoke it. |
| */ |
| if (domain->handler) |
| - ret = domain->handler(domain, dev, iova, flags); |
| + ret = domain->handler(domain, dev, iova, flags, |
| + domain->handler_token); |
| |
| return ret; |
| } |
| @@ -191,7 +193,7 @@ static inline int domain_has_cap(struct iommu_domain *domain, |
| } |
| |
| static inline void iommu_set_fault_handler(struct iommu_domain *domain, |
| - iommu_fault_handler_t handler) |
| + iommu_fault_handler_t handler, void *token) |
| { |
| } |
| |
| -- |
| 1.7.5.4 |
| |