提交 d5cc7d54 编写于 作者: X xuzaibo 提交者: Xie XiuQi

Add iommu share/unshare domain APIs

Feature or Bugfix:Feature
Signed-off-by: Nxuzaibo <xuzaibo@huawei.com>
上级 533224cb
...@@ -59,6 +59,9 @@ struct iommu_group { ...@@ -59,6 +59,9 @@ struct iommu_group {
int id; int id;
struct iommu_domain *default_domain; struct iommu_domain *default_domain;
struct iommu_domain *domain; struct iommu_domain *domain;
atomic_t domain_shared_ref; /* Number of user of current domain.
* The domain cannot be modified if ref > 0
*/
}; };
struct group_device { struct group_device {
...@@ -392,6 +395,7 @@ struct iommu_group *iommu_group_alloc(void) ...@@ -392,6 +395,7 @@ struct iommu_group *iommu_group_alloc(void)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
group->id = ret; group->id = ret;
atomic_set(&group->domain_shared_ref, 0);
ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype, ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype,
NULL, "%d", group->id); NULL, "%d", group->id);
...@@ -525,6 +529,26 @@ int iommu_group_set_name(struct iommu_group *group, const char *name) ...@@ -525,6 +529,26 @@ int iommu_group_set_name(struct iommu_group *group, const char *name)
} }
EXPORT_SYMBOL_GPL(iommu_group_set_name); EXPORT_SYMBOL_GPL(iommu_group_set_name);
struct iommu_domain *iommu_group_share_domain(struct iommu_group *group)
{
/* the domain can be shared only when the default domain is used */
/* todo: more shareable check */
if (group->domain != group->default_domain)
return ERR_PTR(-EINVAL);
atomic_inc(&group->domain_shared_ref);
return group->domain;
}
EXPORT_SYMBOL_GPL(iommu_group_share_domain);
struct iommu_domain *iommu_group_unshare_domain(struct iommu_group *group)
{
atomic_dec(&group->domain_shared_ref);
WARN_ON(atomic_read(&group->domain_shared_ref) < 0);
return group->domain;
}
EXPORT_SYMBOL_GPL(iommu_group_unshare_domain);
static int iommu_group_create_direct_mappings(struct iommu_group *group, static int iommu_group_create_direct_mappings(struct iommu_group *group,
struct device *dev) struct device *dev)
{ {
...@@ -1460,7 +1484,8 @@ static int __iommu_attach_group(struct iommu_domain *domain, ...@@ -1460,7 +1484,8 @@ static int __iommu_attach_group(struct iommu_domain *domain,
{ {
int ret; int ret;
if (group->default_domain && group->domain != group->default_domain) if ((group->default_domain && group->domain != group->default_domain) ||
atomic_read(&group->domain_shared_ref) > 0)
return -EBUSY; return -EBUSY;
ret = __iommu_group_for_each_dev(group, domain, ret = __iommu_group_for_each_dev(group, domain,
...@@ -1497,6 +1522,8 @@ static void __iommu_detach_group(struct iommu_domain *domain, ...@@ -1497,6 +1522,8 @@ static void __iommu_detach_group(struct iommu_domain *domain,
{ {
int ret; int ret;
WARN_ON(atomic_read(&group->domain_shared_ref) > 0);
if (!group->default_domain) { if (!group->default_domain) {
__iommu_group_for_each_dev(group, domain, __iommu_group_for_each_dev(group, domain,
iommu_group_do_detach_device); iommu_group_do_detach_device);
......
...@@ -346,6 +346,9 @@ extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr, ...@@ -346,6 +346,9 @@ extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,
void *data); void *data);
extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,
void *data); void *data);
extern struct iommu_domain *iommu_group_share_domain(struct iommu_group *group);
extern struct iommu_domain *iommu_group_unshare_domain(
struct iommu_group *group);
/* Window handling function prototypes */ /* Window handling function prototypes */
extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
...@@ -686,6 +689,17 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) ...@@ -686,6 +689,17 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
return NULL; return NULL;
} }
static inline
struct iommu_domain *iommu_group_share_domain(struct iommu_group *group)
{
return NULL;
}
static inline
struct iommu_domain *iommu_group_unshare_domain(struct iommu_group *group)
{
return NULL;
}
#endif /* CONFIG_IOMMU_API */ #endif /* CONFIG_IOMMU_API */
#ifdef CONFIG_IOMMU_DEBUGFS #ifdef CONFIG_IOMMU_DEBUGFS
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册