mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
msm: kgsl: Use dma_buf_get() to get dma_buf structure
Currently we don't ensure if vma->vm_file is associated with dma_buf. This can cause issues later when private_data from a non dma_buf file is used as dma_buf structure. Hence get the fd that is associated with vma->vm_file and use dma_buf_get() to get pointer to dma_buf structure. dma_buf_get() ensures that the file from the input fd is associated with dma_buf. Change-Id: Ib78aef8b16bedca5ca86d3a132278ff9f07dce73 Signed-off-by: Puranam V G Tejaswi <quic_pvgtejas@quicinc.com>
This commit is contained in:
parent
8fa497b77b
commit
7ddf19e973
1 changed files with 33 additions and 5 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <uapi/linux/msm_ion.h>
|
||||
|
|
@ -2583,6 +2583,15 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DMA_SHARED_BUFFER
|
||||
static int match_file(const void *p, struct file *file, unsigned int fd)
|
||||
{
|
||||
/*
|
||||
* We must return fd + 1 because iterate_fd stops searching on
|
||||
* non-zero return, but 0 is a valid fd.
|
||||
*/
|
||||
return (p == file) ? (fd + 1) : 0;
|
||||
}
|
||||
|
||||
static void _setup_cache_mode(struct kgsl_mem_entry *entry,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
|
|
@ -2619,6 +2628,8 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device,
|
|||
vma = find_vma(current->mm, hostptr);
|
||||
|
||||
if (vma && vma->vm_file) {
|
||||
int fd;
|
||||
|
||||
ret = check_vma_flags(vma, entry->memdesc.flags);
|
||||
if (ret) {
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
|
@ -2634,10 +2645,27 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Take a refcount because dma_buf_put() decrements the refcount */
|
||||
get_file(vma->vm_file);
|
||||
|
||||
dmabuf = vma->vm_file->private_data;
|
||||
/* Look for the fd that matches this vma file */
|
||||
fd = iterate_fd(current->files, 0, match_file, vma->vm_file);
|
||||
if (fd) {
|
||||
dmabuf = dma_buf_get(fd - 1);
|
||||
if (IS_ERR(dmabuf)) {
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
return PTR_ERR(dmabuf);
|
||||
}
|
||||
/*
|
||||
* It is possible that the fd obtained from iterate_fd
|
||||
* was closed before passing the fd to dma_buf_get().
|
||||
* Hence dmabuf returned by dma_buf_get() could be
|
||||
* different from vma->vm_file->private_data. Return
|
||||
* failure if this happens.
|
||||
*/
|
||||
if (dmabuf != vma->vm_file->private_data) {
|
||||
dma_buf_put(dmabuf);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
return -EBADF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dmabuf) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue