Skip to content

Commit 18d7de8

Browse files
Huan Yangvivekkreddy
authored andcommitted
udmabuf: fix vmap_udmabuf error page set
Currently vmap_udmabuf set page's array by each folio. But, ubuf->folios is only contain's the folio's head page. That mean we repeatedly mapped the folio head page to the vmalloc area. Due to udmabuf can use hugetlb, if HVO enabled, tail page may not exist, so, we can't use page array to map, instead, use pfn array. By this, we removed page usage in udmabuf totally. Fixes: 5e72b2b ("udmabuf: convert udmabuf driver to use folios") Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-4-link@vivo.com
1 parent 1c0844c commit 18d7de8

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

drivers/dma-buf/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ config UDMABUF
3636
depends on DMA_SHARED_BUFFER
3737
depends on MEMFD_CREATE || COMPILE_TEST
3838
depends on MMU
39+
select VMAP_PFN
3940
help
4041
A driver to let userspace turn memfd regions into dma-bufs.
4142
Qemu can use this to create host dmabufs for guest framebuffers.

drivers/dma-buf/udmabuf.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,29 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
103103
static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
104104
{
105105
struct udmabuf *ubuf = buf->priv;
106-
struct page **pages;
106+
unsigned long *pfns;
107107
void *vaddr;
108108
pgoff_t pg;
109109

110110
dma_resv_assert_held(buf->resv);
111111

112-
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
113-
if (!pages)
112+
/**
113+
* HVO may free tail pages, so just use pfn to map each folio
114+
* into vmalloc area.
115+
*/
116+
pfns = kvmalloc_array(ubuf->pagecount, sizeof(*pfns), GFP_KERNEL);
117+
if (!pfns)
114118
return -ENOMEM;
115119

116-
for (pg = 0; pg < ubuf->pagecount; pg++)
117-
pages[pg] = &ubuf->folios[pg]->page;
120+
for (pg = 0; pg < ubuf->pagecount; pg++) {
121+
unsigned long pfn = folio_pfn(ubuf->folios[pg]);
118122

119-
vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
120-
kvfree(pages);
123+
pfn += ubuf->offsets[pg] >> PAGE_SHIFT;
124+
pfns[pg] = pfn;
125+
}
126+
127+
vaddr = vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL);
128+
kvfree(pfns);
121129
if (!vaddr)
122130
return -EINVAL;
123131

0 commit comments

Comments
 (0)