Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a5834e4 authored by Gal Pressman's avatar Gal Pressman Committed by Doug Ledford
Browse files

RDMA/efa: Handle mmap insertions overflow



When inserting a new mmap entry to the xarray we should check for
'mmap_page' overflow as it is limited to 32 bits.

Fixes: 40909f66 ("RDMA/efa: Add EFA verbs implementation")
Signed-off-by: default avatarGal Pressman <galpress@amazon.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 52925434
Loading
Loading
Loading
Loading
+16 −5
Original line number Original line Diff line number Diff line
@@ -204,6 +204,7 @@ static u64 mmap_entry_insert(struct efa_dev *dev, struct efa_ucontext *ucontext,
			     void *obj, u64 address, u64 length, u8 mmap_flag)
			     void *obj, u64 address, u64 length, u8 mmap_flag)
{
{
	struct efa_mmap_entry *entry;
	struct efa_mmap_entry *entry;
	u32 next_mmap_page;
	int err;
	int err;


	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -216,15 +217,19 @@ static u64 mmap_entry_insert(struct efa_dev *dev, struct efa_ucontext *ucontext,
	entry->mmap_flag = mmap_flag;
	entry->mmap_flag = mmap_flag;


	xa_lock(&ucontext->mmap_xa);
	xa_lock(&ucontext->mmap_xa);
	if (check_add_overflow(ucontext->mmap_xa_page,
			       (u32)(length >> PAGE_SHIFT),
			       &next_mmap_page))
		goto err_unlock;

	entry->mmap_page = ucontext->mmap_xa_page;
	entry->mmap_page = ucontext->mmap_xa_page;
	ucontext->mmap_xa_page += DIV_ROUND_UP(length, PAGE_SIZE);
	ucontext->mmap_xa_page = next_mmap_page;
	err = __xa_insert(&ucontext->mmap_xa, entry->mmap_page, entry,
	err = __xa_insert(&ucontext->mmap_xa, entry->mmap_page, entry,
			  GFP_KERNEL);
			  GFP_KERNEL);
	if (err)
		goto err_unlock;

	xa_unlock(&ucontext->mmap_xa);
	xa_unlock(&ucontext->mmap_xa);
	if (err){
		kfree(entry);
		return EFA_MMAP_INVALID;
	}


	ibdev_dbg(
	ibdev_dbg(
		&dev->ibdev,
		&dev->ibdev,
@@ -232,6 +237,12 @@ static u64 mmap_entry_insert(struct efa_dev *dev, struct efa_ucontext *ucontext,
		entry->obj, entry->address, entry->length, get_mmap_key(entry));
		entry->obj, entry->address, entry->length, get_mmap_key(entry));


	return get_mmap_key(entry);
	return get_mmap_key(entry);

err_unlock:
	xa_unlock(&ucontext->mmap_xa);
	kfree(entry);
	return EFA_MMAP_INVALID;

}
}


int efa_query_device(struct ib_device *ibdev,
int efa_query_device(struct ib_device *ibdev,