Skip to content

Commit 6aa3c12

Browse files
Hans Westgaard Ryjfvogel
authored andcommitted
rds: Handle unsupported rdma request to fs dax memory
RDS doesn't support RDMA on memory apertures that require On Demand Paging (ODP), such as FS DAX memory. User applications can try to use RDS to perform RDMA over such memories and since it doesn't report any failure, it can lead to unexpected issues like memory corruption because of other processes can issue file operations like ftruncate while memory is registered for RDMA. The patch adds a check so that such an attempt to RDMA to/from memory apertures requiring ODP will fail. Using 'get_user_pages_longterm' instead of 'get_user_pages_fast' when allocating memory gives us checking for FS DAX memory. 'get_user_pages_longterm' will fail with errorcode -ENOTSUPP if FS DAX memory is detected. Orabug: 30731395 Signed-off-by: Hans Westgaard Ry <[email protected]> Reviewed-by: Santosh Shilimkar <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]> Orabug: 30820081 UEK5 => UEK6 (cherry picked from commit 09ad94c) cherry-pick-repo=UEK/production/linux-uek.git Conflicts: net/rds/rdma.c No merge conflict, but Linux-5.4 compatibility: Adjusted to account for API change: 932f4a6 ("mm/gup: replace get_user_pages_longterm() with FOLL_LONGTERM") Signed-off-by: Gerd Rausch <[email protected]> Reviewed-by: Sharath Srinivasan <[email protected]>
1 parent 99e0dcf commit 6aa3c12

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

net/rds/rdma.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <linux/pagemap.h>
3434
#include <linux/rbtree.h>
3535
#include <linux/dma-mapping.h> /* for DMA_*_DEVICE */
36-
36+
#include <linux/sched/mm.h>
3737
#include "rds.h"
3838

3939
/*
@@ -163,14 +163,20 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
163163
struct page **pages, int write)
164164
{
165165
int ret;
166+
struct mm_struct *mm = current->mm;
167+
int gup_flags = FOLL_LONGTERM | (write ? FOLL_WRITE : 0);
166168

167-
ret = get_user_pages_fast(user_addr, nr_pages, write, pages);
169+
mmgrab(mm);
170+
down_read(&mm->mmap_sem);
171+
ret = get_user_pages(user_addr, nr_pages, gup_flags, pages, NULL);
168172

169173
if (ret >= 0 && (unsigned) ret < nr_pages) {
170174
while (ret--)
171175
put_page(pages[ret]);
172176
ret = -EFAULT;
173177
}
178+
up_read(&mm->mmap_sem);
179+
mmdrop(mm);
174180

175181
return ret;
176182
}

0 commit comments

Comments
 (0)