From c37c1b5474224748c7fdee50d3e1fba474407def Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Fri, 3 Apr 2020 20:33:56 +0530 Subject: [PATCH] gpu: nvgpu: fix null pointer access in nvgpu_vm_find_mapping mapped_buffer sgt is deallocated by dma_buf_unmap_attachment in the function nvgpu_vm_find_mapping if it is previously mapped. Debug print referred to the sgt page after deallocating hence move it before deallocation. Fix below null pointer dereference issue: [ 34.692659] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 ... [ 34.699820] Hardware name: Jetson-AGX (DT) [ 34.709136] pc : nvgpu_vm_find_mapping+0xcc/0x240 [nvgpu] [ 34.714377] lr : nvgpu_vm_find_mapping+0xa4/0x240 [nvgpu] ... [ 34.804523] Call trace: [ 34.807093] nvgpu_vm_find_mapping+0xcc/0x240 [nvgpu] [ 34.812195] nvgpu_vm_map+0xd4/0x480 [nvgpu] [ 34.816168] nvgpu_vm_map_linux+0x15c/0x1c8 [nvgpu] [ 34.821237] nvgpu_vm_map_buffer+0x14c/0x270 [nvgpu] [ 34.825962] gk20a_as_dev_ioctl+0x320/0xfe0 [nvgpu] [ 34.830955] do_vfs_ioctl+0xb8/0xa40 [ 34.834449] ksys_ioctl+0x80/0xb8 [ 34.837430] __arm64_sys_ioctl+0x1c/0x28 [ 34.841630] el0_svc_handler+0x80/0x1a8 [ 34.845129] el0_svc+0x8/0xc [ 34.848106] Code: f9400021 d360ff3a b9406a62 f940007c (f9400034) [ 34.854227] ---[ end trace 1d8c4efb211dc317 ]--- Bug 2834141 Change-Id: I281ac21071fcc2e3e6f3685798c8e77daba6d4a4 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2323361 Tested-by: Debarshi Dutta Tested-by: mobile promotions Reviewed-by: automaticguardword Reviewed-by: Debarshi Dutta Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/os/linux/vm.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/vm.c b/drivers/gpu/nvgpu/os/linux/vm.c index 094451880..5b21bce92 100644 --- a/drivers/gpu/nvgpu/os/linux/vm.c +++ b/drivers/gpu/nvgpu/os/linux/vm.c @@ -153,20 +153,12 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, if (mapped_buffer->flags != flags) return NULL; - /* - * If we find the mapping here then that means we have mapped it already - * and the prior pin and get must be undone. - */ - gk20a_mm_unpin(os_buf->dev, os_buf->dmabuf, - mapped_buffer->os_priv.attachment, - mapped_buffer->os_priv.sgt); - dma_buf_put(os_buf->dmabuf); - nvgpu_log(g, gpu_dbg_map, "gv: 0x%04x_%08x + 0x%-7zu " "[dma: 0x%010llx, pa: 0x%010llx] " "pgsz=%-3dKb as=%-2d " - "flags=0x%x apt=%s (reused)", + "flags=0x%x apt=%s (already pinned, " + "reused in case of dmabuf drvdata, unpinned otherwise)", u64_hi32(mapped_buffer->addr), u64_lo32(mapped_buffer->addr), os_buf->dmabuf->size, (u64)sg_dma_address(mapped_buffer->os_priv.sgt->sgl), @@ -176,6 +168,15 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, mapped_buffer->flags, nvgpu_aperture_str(gk20a_dmabuf_aperture(g, os_buf->dmabuf))); + /* + * If we find the mapping here then that means we have mapped it already + * and the prior pin and get must be undone. + */ + gk20a_mm_unpin(os_buf->dev, os_buf->dmabuf, + mapped_buffer->os_priv.attachment, + mapped_buffer->os_priv.sgt); + dma_buf_put(os_buf->dmabuf); + return mapped_buffer; }