aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMajd Dibbiny <majd@mellanox.com>2017-12-24 06:54:56 -0500
committerJason Gunthorpe <jgg@mellanox.com>2017-12-27 17:24:40 -0500
commitad9a3668a434faca1339789ed2f043d679199309 (patch)
tree6ae4f8fc84efe4a0db5750a696c24bc06dddbb09
parent4c009af473b2026caaa26107e34d7cc68dad7756 (diff)
IB/mlx5: Serialize access to the VMA list
User-space applications can do mmap and munmap directly at any time. Since the VMA list is not protected with a mutex, concurrent accesses to the VMA list from the mmap and munmap can cause data corruption. Add a mutex around the list. Cc: <stable@vger.kernel.org> # v4.7 Fixes: 7c2344c3bbf9 ("IB/mlx5: Implements disassociate_ucontext API") Reviewed-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Majd Dibbiny <majd@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/hw/mlx5/main.c8
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h4
2 files changed, 12 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index b4ef4d9b6ce5..8ac50de2b242 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1463,6 +1463,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1463 } 1463 }
1464 1464
1465 INIT_LIST_HEAD(&context->vma_private_list); 1465 INIT_LIST_HEAD(&context->vma_private_list);
1466 mutex_init(&context->vma_private_list_mutex);
1466 INIT_LIST_HEAD(&context->db_page_list); 1467 INIT_LIST_HEAD(&context->db_page_list);
1467 mutex_init(&context->db_page_mutex); 1468 mutex_init(&context->db_page_mutex);
1468 1469
@@ -1624,7 +1625,9 @@ static void mlx5_ib_vma_close(struct vm_area_struct *area)
1624 * mlx5_ib_disassociate_ucontext(). 1625 * mlx5_ib_disassociate_ucontext().
1625 */ 1626 */
1626 mlx5_ib_vma_priv_data->vma = NULL; 1627 mlx5_ib_vma_priv_data->vma = NULL;
1628 mutex_lock(mlx5_ib_vma_priv_data->vma_private_list_mutex);
1627 list_del(&mlx5_ib_vma_priv_data->list); 1629 list_del(&mlx5_ib_vma_priv_data->list);
1630 mutex_unlock(mlx5_ib_vma_priv_data->vma_private_list_mutex);
1628 kfree(mlx5_ib_vma_priv_data); 1631 kfree(mlx5_ib_vma_priv_data);
1629} 1632}
1630 1633
@@ -1644,10 +1647,13 @@ static int mlx5_ib_set_vma_data(struct vm_area_struct *vma,
1644 return -ENOMEM; 1647 return -ENOMEM;
1645 1648
1646 vma_prv->vma = vma; 1649 vma_prv->vma = vma;
1650 vma_prv->vma_private_list_mutex = &ctx->vma_private_list_mutex;
1647 vma->vm_private_data = vma_prv; 1651 vma->vm_private_data = vma_prv;
1648 vma->vm_ops = &mlx5_ib_vm_ops; 1652 vma->vm_ops = &mlx5_ib_vm_ops;
1649 1653
1654 mutex_lock(&ctx->vma_private_list_mutex);
1650 list_add(&vma_prv->list, vma_head); 1655 list_add(&vma_prv->list, vma_head);
1656 mutex_unlock(&ctx->vma_private_list_mutex);
1651 1657
1652 return 0; 1658 return 0;
1653} 1659}
@@ -1690,6 +1696,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
1690 * mlx5_ib_vma_close. 1696 * mlx5_ib_vma_close.
1691 */ 1697 */
1692 down_write(&owning_mm->mmap_sem); 1698 down_write(&owning_mm->mmap_sem);
1699 mutex_lock(&context->vma_private_list_mutex);
1693 list_for_each_entry_safe(vma_private, n, &context->vma_private_list, 1700 list_for_each_entry_safe(vma_private, n, &context->vma_private_list,
1694 list) { 1701 list) {
1695 vma = vma_private->vma; 1702 vma = vma_private->vma;
@@ -1704,6 +1711,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
1704 list_del(&vma_private->list); 1711 list_del(&vma_private->list);
1705 kfree(vma_private); 1712 kfree(vma_private);
1706 } 1713 }
1714 mutex_unlock(&context->vma_private_list_mutex);
1707 up_write(&owning_mm->mmap_sem); 1715 up_write(&owning_mm->mmap_sem);
1708 mmput(owning_mm); 1716 mmput(owning_mm);
1709 put_task_struct(owning_process); 1717 put_task_struct(owning_process);
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 6dd8cac78de2..2c5f3533bbc9 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -115,6 +115,8 @@ enum {
115struct mlx5_ib_vma_private_data { 115struct mlx5_ib_vma_private_data {
116 struct list_head list; 116 struct list_head list;
117 struct vm_area_struct *vma; 117 struct vm_area_struct *vma;
118 /* protect vma_private_list add/del */
119 struct mutex *vma_private_list_mutex;
118}; 120};
119 121
120struct mlx5_ib_ucontext { 122struct mlx5_ib_ucontext {
@@ -129,6 +131,8 @@ struct mlx5_ib_ucontext {
129 /* Transport Domain number */ 131 /* Transport Domain number */
130 u32 tdn; 132 u32 tdn;
131 struct list_head vma_private_list; 133 struct list_head vma_private_list;
134 /* protect vma_private_list add/del */
135 struct mutex vma_private_list_mutex;
132 136
133 unsigned long upd_xlt_page; 137 unsigned long upd_xlt_page;
134 /* protect ODP/KSM */ 138 /* protect ODP/KSM */