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:
parent
dca34e2b69
commit
27df4148a6
|
@ -670,7 +670,7 @@ void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
|
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;
|
struct iommu_domain *domain;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -684,7 +684,7 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type *bus, int flags)
|
||||||
|
|
||||||
domain->ops = bus->iommu_ops;
|
domain->ops = bus->iommu_ops;
|
||||||
|
|
||||||
ret = domain->ops->domain_init(domain, flags);
|
ret = domain->ops->domain_init(domain);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
|
||||||
msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
|
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);
|
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)
|
if (!priv->pt.fl_table)
|
||||||
goto fail_nomem;
|
goto fail_nomem;
|
||||||
|
|
||||||
#ifdef CONFIG_IOMMU_PGTABLES_L2
|
priv->pt.redirect = 1;
|
||||||
priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(priv->pt.fl_table, 0, SZ_16K);
|
memset(priv->pt.fl_table, 0, SZ_16K);
|
||||||
domain->priv = priv;
|
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);
|
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 = {
|
static struct iommu_ops msm_iommu_ops = {
|
||||||
.domain_init = msm_iommu_domain_init,
|
.domain_init = msm_iommu_domain_init,
|
||||||
.domain_destroy = msm_iommu_domain_destroy,
|
.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,
|
.domain_has_cap = msm_iommu_domain_has_cap,
|
||||||
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
|
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
|
||||||
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
|
.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)
|
static int __init get_tex_class(int icp, int ocp, int mt, int nos)
|
||||||
|
|
|
@ -740,7 +740,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
|
||||||
mb();
|
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;
|
struct msm_iommu_priv *priv;
|
||||||
|
|
||||||
|
@ -748,9 +748,7 @@ static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
|
||||||
if (!priv)
|
if (!priv)
|
||||||
goto fail_nomem;
|
goto fail_nomem;
|
||||||
|
|
||||||
#ifdef CONFIG_IOMMU_PGTABLES_L2
|
priv->pt.redirect = 1;
|
||||||
priv->pt.redirect = flags & MSM_IOMMU_DOMAIN_PT_CACHEABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->list_attached);
|
INIT_LIST_HEAD(&priv->list_attached);
|
||||||
if (msm_iommu_pagetable_alloc(&priv->pt))
|
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);
|
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 = {
|
static struct iommu_ops msm_iommu_ops = {
|
||||||
.domain_init = msm_iommu_domain_init,
|
.domain_init = msm_iommu_domain_init,
|
||||||
.domain_destroy = msm_iommu_domain_destroy,
|
.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,
|
.domain_has_cap = msm_iommu_domain_has_cap,
|
||||||
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
|
.get_pt_base_addr = msm_iommu_get_pt_base_addr,
|
||||||
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
|
.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)
|
static int __init msm_iommu_init(void)
|
||||||
|
|
|
@ -468,6 +468,7 @@ int msm_register_domain(struct msm_iova_layout *layout)
|
||||||
struct msm_iova_data *data;
|
struct msm_iova_data *data;
|
||||||
struct mem_pool *pools;
|
struct mem_pool *pools;
|
||||||
struct bus_type *bus;
|
struct bus_type *bus;
|
||||||
|
int no_redirect;
|
||||||
|
|
||||||
if (!layout)
|
if (!layout)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -524,10 +525,14 @@ int msm_register_domain(struct msm_iova_layout *layout)
|
||||||
if (data->domain_num < 0)
|
if (data->domain_num < 0)
|
||||||
goto free_pools;
|
goto free_pools;
|
||||||
|
|
||||||
data->domain = iommu_domain_alloc(bus, layout->domain_flags);
|
data->domain = iommu_domain_alloc(bus);
|
||||||
if (!data->domain)
|
if (!data->domain)
|
||||||
goto free_domain_num;
|
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);
|
msm_iommu_set_client_name(data->domain, layout->client_name);
|
||||||
|
|
||||||
add_domain(data);
|
add_domain(data);
|
||||||
|
|
|
@ -677,7 +677,7 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata,
|
||||||
return ret;
|
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;
|
struct msm_iommu_priv *priv;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ enum iommu_attr {
|
||||||
DOMAIN_ATTR_GEOMETRY,
|
DOMAIN_ATTR_GEOMETRY,
|
||||||
DOMAIN_ATTR_PAGING,
|
DOMAIN_ATTR_PAGING,
|
||||||
DOMAIN_ATTR_WINDOWS,
|
DOMAIN_ATTR_WINDOWS,
|
||||||
|
DOMAIN_ATTR_COHERENT_HTW_DISABLE,
|
||||||
DOMAIN_ATTR_MAX,
|
DOMAIN_ATTR_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ enum iommu_attr {
|
||||||
* @pgsize_bitmap: bitmap of supported page sizes
|
* @pgsize_bitmap: bitmap of supported page sizes
|
||||||
*/
|
*/
|
||||||
struct iommu_ops {
|
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);
|
void (*domain_destroy)(struct iommu_domain *domain);
|
||||||
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
|
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
|
||||||
void (*detach_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 int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops);
|
||||||
extern bool iommu_present(struct bus_type *bus);
|
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 struct iommu_group *iommu_group_get_by_id(int id);
|
||||||
extern void iommu_domain_free(struct iommu_domain *domain);
|
extern void iommu_domain_free(struct iommu_domain *domain);
|
||||||
extern int iommu_attach_device(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;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ int kvm_iommu_map_guest(struct kvm *kvm)
|
||||||
|
|
||||||
mutex_lock(&kvm->slots_lock);
|
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) {
|
if (!kvm->arch.iommu_domain) {
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
Loading…
Reference in New Issue