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

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
...@@ -204,6 +204,7 @@ static u64 mmap_entry_insert(struct efa_dev *dev, struct efa_ucontext *ucontext, ...@@ -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, ...@@ -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, ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment