Files
linux-nvgpu/drivers/gpu/nvgpu/os/linux/dmabuf.c
Sagar Kamble 9f8d5acfbb gpu: nvgpu: fix the return value from gk20a_mm_pin
The return value in case of failure of dma_buf_attach and
dma_buf_map_attachment was ignored and NULL was returned.
This would lead to following null pointer access. Fix it.

[  293.622880] Unable to handle kernel NULL pointer dereference
               at virtual address 0000000000000000
...
[  293.711860] Hardware name: quill (DT)
[  293.720393] pc : nvgpu_linux_sgt_create+0x14/0xa8 [nvgpu]
[  293.725871] lr : nvgpu_vm_map_linux+0x104/0x1c8 [nvgpu]
...
[  293.813934] Call trace:
[  293.816455]  nvgpu_linux_sgt_create+0x14/0xa8 [nvgpu]
[  293.821573]  nvgpu_vm_map_linux+0x104/0x1c8 [nvgpu]
[  293.826515]  nvgpu_vm_map_buffer+0x120/0x290 [nvgpu]
[  293.831542]  gk20a_as_dev_ioctl+0x364/0xfb8 [nvgpu]
[  293.836416]  ksys_ioctl+0x17c/0xba8
[  293.839899]  __arm64_sys_ioctl+0x18/0x28
[  293.843817]  do_el0_svc+0xf8/0x1b8
[  293.847214]  el0_sync_handler+0x11c/0x28c
[  293.851217]  el0_sync+0x140/0x180

Bug 2834141

Change-Id: I0d9e863d0326946c8091bfb1b907b62b055f7272
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2332204
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2020-12-15 14:13:28 -06:00

103 lines
2.9 KiB
C

/*
* Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/scatterlist.h>
#include <nvgpu/comptags.h>
#include <nvgpu/enabled.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/linux/vm.h>
#include <nvgpu/bug.h>
#include <nvgpu/fence.h>
#include "platform_gk20a.h"
#include "dmabuf.h"
#include "dmabuf_priv.h"
#include "os_linux.h"
#include "dmabuf_vidmem.h"
enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g,
struct dma_buf *dmabuf)
{
#ifdef CONFIG_NVGPU_DGPU
struct gk20a *buf_owner = nvgpu_vidmem_buf_owner(dmabuf);
bool unified_memory = nvgpu_is_enabled(g, NVGPU_MM_UNIFIED_MEMORY);
if (buf_owner == NULL) {
/* Not nvgpu-allocated, assume system memory */
return APERTURE_SYSMEM;
} else if ((buf_owner == g) && unified_memory) {
/* Looks like our video memory, but this gpu doesn't support
* it. Warn about a bug and bail out */
nvgpu_do_assert_print(g,
"dmabuf is our vidmem but we don't have local vidmem");
return APERTURE_INVALID;
} else if (buf_owner != g) {
/* Someone else's vidmem */
return APERTURE_INVALID;
} else {
/* Yay, buf_owner == g */
return APERTURE_VIDMEM;
}
#else
return APERTURE_SYSMEM;
#endif
}
struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf,
struct dma_buf_attachment **attachment)
{
#ifdef CONFIG_NVGPU_DMABUF_HAS_DRVDATA
return gk20a_mm_pin_has_drvdata(dev, dmabuf, attachment);
#else
struct dma_buf_attachment *attach = NULL;
struct gk20a *g = get_gk20a(dev);
struct sg_table *sgt = NULL;
attach = dma_buf_attach(dmabuf, dev);
if (IS_ERR(attach)) {
nvgpu_err(g, "Failed to attach dma_buf (err = %ld)!",
PTR_ERR(attach));
return ERR_CAST(attach);
}
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
if (IS_ERR(sgt)) {
dma_buf_detach(dmabuf, attach);
nvgpu_err(g, "Failed to map attachment (err = %ld)!",
PTR_ERR(sgt));
return ERR_CAST(sgt);
}
*attachment = attach;
return sgt;
#endif
}
void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf,
struct dma_buf_attachment *attachment,
struct sg_table *sgt)
{
#ifdef CONFIG_NVGPU_DMABUF_HAS_DRVDATA
gk20a_mm_unpin_has_drvdata(dev, dmabuf, attachment, sgt);
#else
dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
dma_buf_detach(dmabuf, attachment);
#endif
}