iommu: msm: move L2 redirect to a domain attribute

We will soon be removing the `flags' parameter from iommu_domain_alloc
and iommu_ops.domain_init. In preparation for this, move the L2 redirect
flag to a domain attribute.

We now no longer need the extra parameter to iommu_domain_alloc which
was added in [8984b0e30df: "drivers: iommu: Add flags to
iommu_domain_alloc"] since we're changing the way L2 redirect is
configured. Remove it.

Change-Id: Ie0d15767ca08211740d22568683fae01e8123a26
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
Mitchel Humpherys 2014-08-07 15:11:59 -07:00
parent dca34e2b69
commit 27df4148a6
7 changed files with 142 additions and 16 deletions

View File

@ -670,7 +670,7 @@ void iommu_set_fault_handler(struct iommu_domain *domain,
}
EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
struct iommu_domain *iommu_domain_alloc(struct bus_type *bus, int flags)
struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
{
struct iommu_domain *domain;
int ret;
@ -684,7 +684,7 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type *bus, int flags)
domain->ops = bus->iommu_ops;
ret = domain->ops->domain_init(domain, flags);
ret = domain->ops->domain_init(domain);
if (ret)
goto out_free;

View File

@ -424,7 +424,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
}
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
static int msm_iommu_domain_init(struct iommu_domain *domain)
{
struct msm_iommu_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@ -438,9 +438,7 @@ static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
if (!priv->pt.fl_table)
goto fail_nomem;
#ifdef CONFIG_IOMMU_PGTABLES_L2
priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
#endif
priv->pt.redirect = 1;
memset(priv->pt.fl_table, 0, SZ_16K);
domain->priv = priv;
@ -1381,6 +1379,66 @@ static phys_addr_t msm_iommu_get_pt_base_addr(struct iommu_domain *domain)
return __pa(priv->pt.fl_table);
}
#ifdef CONFIG_IOMMU_PGTABLES_L2
static void __do_set_redirect(struct iommu_domain *domain, void *data)
{
struct msm_iommu_priv *priv;
int *no_redirect = data;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
priv->pt.redirect = !(*no_redirect);
mutex_unlock(&msm_iommu_lock);
}
static void __do_get_redirect(struct iommu_domain *domain, void *data)
{
struct msm_iommu_priv *priv;
int *no_redirect = data;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
*no_redirect = !priv->pt.redirect;
mutex_unlock(&msm_iommu_lock);
}
#else
static void __do_set_redirect(struct iommu_domain *domain, void *data)
{
}
static void __do_get_redirect(struct iommu_domain *domain, void *data)
{
}
#endif
static int msm_iommu_domain_set_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
{
switch (attr) {
case DOMAIN_ATTR_COHERENT_HTW_DISABLE:
__do_set_redirect(domain, data);
break;
default:
return -EINVAL;
}
return 0;
}
static int msm_iommu_domain_get_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
{
switch (attr) {
case DOMAIN_ATTR_COHERENT_HTW_DISABLE:
__do_get_redirect(domain, data);
break;
default:
return -EINVAL;
}
return 0;
}
static struct iommu_ops msm_iommu_ops = {
.domain_init = msm_iommu_domain_init,
.domain_destroy = msm_iommu_domain_destroy,
@ -1394,6 +1452,8 @@ static struct iommu_ops msm_iommu_ops = {
.domain_has_cap = msm_iommu_domain_has_cap,
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
.domain_set_attr = msm_iommu_domain_set_attr,
.domain_get_attr = msm_iommu_domain_get_attr,
};
static int __init get_tex_class(int icp, int ocp, int mt, int nos)

View File

@ -740,7 +740,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
mb();
}
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
static int msm_iommu_domain_init(struct iommu_domain *domain)
{
struct msm_iommu_priv *priv;
@ -748,9 +748,7 @@ static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
if (!priv)
goto fail_nomem;
#ifdef CONFIG_IOMMU_PGTABLES_L2
priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
#endif
priv->pt.redirect = 1;
INIT_LIST_HEAD(&priv->list_attached);
if (msm_iommu_pagetable_alloc(&priv->pt))
@ -1451,6 +1449,66 @@ static void msm_iommu_build_dump_regs_table(void)
DUMP_REG_INIT(DUMP_REG_CBFRSYNRA_N, CBFRSYNRA, 1, DRT_GLOBAL_REG_N);
}
#ifdef CONFIG_IOMMU_PGTABLES_L2
static void __do_set_redirect(struct iommu_domain *domain, void *data)
{
struct msm_iommu_priv *priv;
int *no_redirect = data;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
priv->pt.redirect = !(*no_redirect);
mutex_unlock(&msm_iommu_lock);
}
static void __do_get_redirect(struct iommu_domain *domain, void *data)
{
struct msm_iommu_priv *priv;
int *no_redirect = data;
mutex_lock(&msm_iommu_lock);
priv = domain->priv;
*no_redirect = !priv->pt.redirect;
mutex_unlock(&msm_iommu_lock);
}
#else
static void __do_set_redirect(struct iommu_domain *domain, void *data)
{
}
static void __do_get_redirect(struct iommu_domain *domain, void *data)
{
}
#endif
static int msm_iommu_domain_set_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
{
switch (attr) {
case DOMAIN_ATTR_COHERENT_HTW_DISABLE:
__do_set_redirect(domain, data);
break;
default:
return -EINVAL;
}
return 0;
}
static int msm_iommu_domain_get_attr(struct iommu_domain *domain,
enum iommu_attr attr, void *data)
{
switch (attr) {
case DOMAIN_ATTR_COHERENT_HTW_DISABLE:
__do_get_redirect(domain, data);
break;
default:
return -EINVAL;
}
return 0;
}
static struct iommu_ops msm_iommu_ops = {
.domain_init = msm_iommu_domain_init,
.domain_destroy = msm_iommu_domain_destroy,
@ -1464,6 +1522,8 @@ static struct iommu_ops msm_iommu_ops = {
.domain_has_cap = msm_iommu_domain_has_cap,
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
.domain_set_attr = msm_iommu_domain_set_attr,
.domain_get_attr = msm_iommu_domain_get_attr,
};
static int __init msm_iommu_init(void)

View File

@ -468,6 +468,7 @@ int msm_register_domain(struct msm_iova_layout *layout)
struct msm_iova_data *data;
struct mem_pool *pools;
struct bus_type *bus;
int no_redirect;
if (!layout)
return -EINVAL;
@ -524,10 +525,14 @@ int msm_register_domain(struct msm_iova_layout *layout)
if (data->domain_num < 0)
goto free_pools;
data->domain = iommu_domain_alloc(bus, layout->domain_flags);
data->domain = iommu_domain_alloc(bus);
if (!data->domain)
goto free_domain_num;
no_redirect = !(layout->domain_flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE);
iommu_domain_set_attr(data->domain,
DOMAIN_ATTR_COHERENT_HTW_DISABLE, &no_redirect);
msm_iommu_set_client_name(data->domain, layout->client_name);
add_domain(data);

View File

@ -677,7 +677,7 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata,
return ret;
}
static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
static int msm_iommu_domain_init(struct iommu_domain *domain)
{
struct msm_iommu_priv *priv;

View File

@ -66,6 +66,7 @@ enum iommu_attr {
DOMAIN_ATTR_GEOMETRY,
DOMAIN_ATTR_PAGING,
DOMAIN_ATTR_WINDOWS,
DOMAIN_ATTR_COHERENT_HTW_DISABLE,
DOMAIN_ATTR_MAX,
};
@ -88,7 +89,7 @@ enum iommu_attr {
* @pgsize_bitmap: bitmap of supported page sizes
*/
struct iommu_ops {
int (*domain_init)(struct iommu_domain *domain, int flags);
int (*domain_init)(struct iommu_domain *domain);
void (*domain_destroy)(struct iommu_domain *domain);
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
@ -133,7 +134,7 @@ struct iommu_ops {
extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops);
extern bool iommu_present(struct bus_type *bus);
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus, int flags);
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
extern struct iommu_group *iommu_group_get_by_id(int id);
extern void iommu_domain_free(struct iommu_domain *domain);
extern int iommu_attach_device(struct iommu_domain *domain,
@ -239,7 +240,7 @@ static inline bool iommu_present(struct bus_type *bus)
return false;
}
static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus, int flags)
static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
{
return NULL;
}

View File

@ -244,7 +244,7 @@ int kvm_iommu_map_guest(struct kvm *kvm)
mutex_lock(&kvm->slots_lock);
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type, 0);
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
if (!kvm->arch.iommu_domain) {
r = -ENOMEM;
goto out_unlock;