From: Jordan Crouse <jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 6/7] iommu: Add dynamic domains
Date: Tue, 7 Mar 2017 09:39:54 -0700 [thread overview]
Message-ID: <1488904795-870-7-git-send-email-jcrouse@codeaurora.org> (raw)
In-Reply-To: <1488904795-870-1-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Add an API to create a dynamic domain from an existing domain.
A dynamic domain is a special IOMMU domain that is attached to
the same device as the parent domain but is backed by separate
pagetables. Devices such as GPUs that support asynchronous
methods for switching pagetables can create dynamic domains for
each individual instance and map memory into them.
The hardware can use the physical address of the pagetable
(as queried by DOMAIN_ATTR_TTBR0) to asynchronously switch the
hardware to the desired pagetable when needed.
Dynamic domains must be created from existing attached
non-dynamic domains. The domains will share configuration
(pagetable format, context bank, etc). Dynamic domains do not
modify the hardware directly - they are typically a
wrapper for the pagetable memory and facilitate using the other
IOMMU APIs to map and unmap buffers.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---
drivers/iommu/iommu.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/iommu.h | 17 ++++++++++++++++-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9a2f196..4ba593b 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1079,6 +1079,31 @@ void iommu_domain_free(struct iommu_domain *domain)
}
EXPORT_SYMBOL_GPL(iommu_domain_free);
+struct iommu_domain *iommu_domain_create_dynamic(struct iommu_domain *parent)
+{
+ struct iommu_domain *child;
+ int ret;
+
+ if (!parent || !parent->ops || !parent->ops->domain_init_dynamic)
+ return NULL;
+
+ child = parent->ops->domain_alloc(IOMMU_DOMAIN_DYNAMIC);
+ if (child == NULL)
+ return NULL;
+
+ child->ops = parent->ops;
+ child->type = IOMMU_DOMAIN_DYNAMIC;
+ child->pgsize_bitmap = parent->pgsize_bitmap;
+
+ ret = child->ops->domain_init_dynamic(parent, child);
+ if (!ret)
+ return child;
+
+ child->ops->domain_free(child);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(iommu_domain_create_dynamic);
+
static int __iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
@@ -1097,6 +1122,10 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
struct iommu_group *group;
int ret;
+ /* Don't try to attach dynamic domains */
+ if (!domain || domain->type == IOMMU_DOMAIN_DYNAMIC)
+ return -EINVAL;
+
group = iommu_group_get(dev);
/* FIXME: Remove this when groups a mandatory for iommu drivers */
if (group == NULL)
@@ -1135,6 +1164,10 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
+ /* Don't try to detach dynamic domains */
+ if (!domain || domain->type == IOMMU_DOMAIN_DYNAMIC)
+ return;
+
group = iommu_group_get(dev);
/* FIXME: Remove this when groups a mandatory for iommu drivers */
if (group == NULL)
@@ -1508,6 +1541,10 @@ int iommu_domain_get_attr(struct iommu_domain *domain,
ret = -ENODEV;
break;
+ case DOMAIN_ATTR_DYNAMIC:
+ *((unsigned int *) data) =
+ !!(domain->type & __IOMMU_DOMAIN_DYNAMIC);
+ break;
default:
if (!domain->ops->domain_get_attr)
return -EINVAL;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 544cfc6..5b538d0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -57,7 +57,7 @@ struct iommu_domain_geometry {
#define __IOMMU_DOMAIN_DMA_API (1U << 1) /* Domain for use in DMA-API
implementation */
#define __IOMMU_DOMAIN_PT (1U << 2) /* Domain is identity mapped */
-
+#define __IOMMU_DOMAIN_DYNAMIC (1U << 3) /* Domain is dynamic */
/*
* This are the possible domain-types
*
@@ -69,12 +69,18 @@ struct iommu_domain_geometry {
* IOMMU_DOMAIN_DMA - Internally used for DMA-API implementations.
* This flag allows IOMMU drivers to implement
* certain optimizations for these domains
+ * IOMMU_DOMAIN_DYNAMIC - The domain is dynamic and bound to a parent
+ * domain. This allows the driver to implement
+ * multiple domains on one device with different
+ * attributes
*/
#define IOMMU_DOMAIN_BLOCKED (0U)
#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT)
#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
#define IOMMU_DOMAIN_DMA (__IOMMU_DOMAIN_PAGING | \
__IOMMU_DOMAIN_DMA_API)
+#define IOMMU_DOMAIN_DYNAMIC (__IOMMU_DOMAIN_PAGING | \
+ __IOMMU_DOMAIN_DYNAMIC)
struct iommu_domain {
unsigned type;
@@ -116,6 +122,7 @@ enum iommu_attr {
DOMAIN_ATTR_NESTING, /* two stages of translation */
DOMAIN_ATTR_ENABLE_TTBR1,
DOMAIN_ATTR_TTBR0,
+ DOMAIN_ATTR_DYNAMIC,
DOMAIN_ATTR_MAX,
};
@@ -160,6 +167,7 @@ struct iommu_dm_region {
* @domain_set_windows: Set the number of windows for a domain
* @domain_get_windows: Return the number of windows for a domain
* @of_xlate: add OF master IDs to iommu grouping
+ * @domain_init_dynamic: Initialize a dynamic domain based on a parent domain
* @pgsize_bitmap: bitmap of all possible supported page sizes
*/
struct iommu_ops {
@@ -203,6 +211,9 @@ struct iommu_ops {
int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
+ int (*domain_init_dynamic)(struct iommu_domain *parent,
+ struct iommu_domain *child);
+
unsigned long pgsize_bitmap;
};
@@ -280,6 +291,10 @@ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
phys_addr_t offset, u64 size,
int prot);
extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr);
+
+extern struct iommu_domain *iommu_domain_create_dynamic(
+ struct iommu_domain *parent);
+
/**
* report_iommu_fault() - report about an IOMMU fault to the IOMMU framework
* @domain: the iommu domain where the fault has happened
--
1.9.1
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno
next prev parent reply other threads:[~2017-03-07 16:39 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-07 16:39 [PATCH 0/7] RFC: iommu/arm-smmu-v2: Dynamic domains Jordan Crouse
[not found] ` <1488904795-870-1-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-03-07 16:39 ` [PATCH 1/7] iommu/arm-smmu: save the pgtbl_cfg in the domain Jordan Crouse
2017-03-07 16:39 ` [PATCH 2/7] iommu: Add DOMAIN_ATTR_ENABLE_TTBR1 Jordan Crouse
2017-03-07 16:39 ` [PATCH 3/7] iommu/arm-smmu: Add support for TTBR1 Jordan Crouse
2017-03-07 16:39 ` [PATCH 4/7] iommu: introduce TTBR0 domain attribute Jordan Crouse
2017-03-07 16:39 ` [PATCH 5/7] iommu/arm-smmu: add support for TTBR0 attribute Jordan Crouse
2017-03-07 16:39 ` Jordan Crouse [this message]
2017-03-07 16:39 ` [PATCH 7/7] iommu/arm-smmu: add support for dynamic domains Jordan Crouse
[not found] ` <1488904795-870-8-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-03-07 18:11 ` Mark Rutland
2017-03-07 20:40 ` Jordan Crouse
2017-03-07 17:22 ` [Freedreno] [PATCH 0/7] RFC: iommu/arm-smmu-v2: Dynamic domains Jordan Crouse
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=1488904795-870-7-git-send-email-jcrouse@codeaurora.org \
--to=jcrouse-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
--cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.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