Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 14:50:04 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/dist/drm/i915: i915_cmd_parser.c i915_gem.c
            i915_gem_render_state.c

Log Message:
Handle uvm object reference counts in uvm_map more carefully.

Acquire a reference unconditionally first; then let uvm_map consume
it on success, and release it ourselves on failure.

As we did before -- acquiring a fresh reference on success -- another
thread might release the reference with a concurrent uvm_unmap before
we could acquire it back, thereby destroying the object.

XXX pullup-7 in part (i915_gem_fault)
XXX pullup-8 in part (i915_gem_fault)


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 \
    src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c
cvs rdiff -u -r1.52 -r1.53 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c
cvs rdiff -u -r1.8 -r1.9 \
    src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c:1.16 src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c:1.17
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c:1.16	Mon Aug 27 14:46:38 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_cmd_parser.c	Mon Aug 27 14:50:04 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_cmd_parser.c,v 1.16 2018/08/27 14:46:38 riastradh Exp $	*/
+/*	$NetBSD: i915_cmd_parser.c,v 1.17 2018/08/27 14:50:04 riastradh Exp $	*/
 
 /*
  * Copyright © 2013 Intel Corporation
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_cmd_parser.c,v 1.16 2018/08/27 14:46:38 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_cmd_parser.c,v 1.17 2018/08/27 14:50:04 riastradh Exp $");
 
 #include "i915_drv.h"
 
@@ -928,16 +928,18 @@ static u32 *copy_batch(struct drm_i915_g
 	    - srcstart;
 	vaddr_t srcva = 0;	/* hint */
 
+	/* Acquire a reference for uvm_map to consume.  */
+	uao_reference(src_obj->base.filp);
+
 	/* XXX errno NetBSD->Linux */
 	ret = -uvm_map(kernel_map, &srcva, srclen, src_obj->base.filp,
 	    srcstart, PAGE_SIZE, UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
 		UVM_INH_NONE, UVM_ADV_SEQUENTIAL, UVM_FLAG_NOWAIT));
 	if (ret) {
+		uao_detach(src_obj->base.filp);
 		DRM_DEBUG_DRIVER("CMD: Failed to vmap batch: %d\n", ret);
 		goto unpin_src;
 	}
-	/* uvm_map consumes caller's reference on success.  */
-	uao_reference(src_obj->base.filp);
 	src_base = (const void *)srcva;
 #else
 	src_base = vmap_batch(src_obj, batch_start_offset, batch_len);
@@ -959,16 +961,18 @@ static u32 *copy_batch(struct drm_i915_g
 	const u32 dstlen = roundup(0 + batch_len, PAGE_SIZE) - dststart;
 	vaddr_t dstva = 0;	/* hint */
 
+	/* Acquire a reference for uvm_map to consume.  */
+	uao_reference(dest_obj->base.filp);
+
 	/* XXX errno NetBSD->Linux */
 	ret = -uvm_map(kernel_map, &dstva, dstlen, dest_obj->base.filp,
 	    dststart, PAGE_SIZE, UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
 		UVM_INH_NONE, UVM_ADV_SEQUENTIAL, UVM_FLAG_NOWAIT));
 	if (ret) {
+		uao_detach(dest_obj->base.filp);
 		DRM_DEBUG_DRIVER("CMD: Failed to vmap shadow batch: %d\n", ret);
 		goto unmap_src;
 	}
-	/* uvm_map consumes caller's reference on success.  */
-	uao_reference(dest_obj->base.filp);
 	dst = (void *)dstva;
 #else
 	dst = vmap_batch(dest_obj, 0, batch_len);

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.52 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.53
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c:1.52	Mon Aug 27 14:47:02 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem.c	Mon Aug 27 14:50:04 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_gem.c,v 1.52 2018/08/27 14:47:02 riastradh Exp $	*/
+/*	$NetBSD: i915_gem.c,v 1.53 2018/08/27 14:50:04 riastradh Exp $	*/
 
 /*
  * Copyright © 2008-2015 Intel Corporation
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem.c,v 1.52 2018/08/27 14:47:02 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem.c,v 1.53 2018/08/27 14:50:04 riastradh Exp $");
 
 #ifdef __NetBSD__
 #if 0				/* XXX uvmhist option?  */
@@ -1956,6 +1956,8 @@ i915_gem_mmap_ioctl(struct drm_device *d
 	}
 
 #ifdef __NetBSD__
+	/* Acquire a reference for uvm_map to consume.  */
+	uao_reference(obj->filp);
 	addr = (*curproc->p_emul->e_vm_default_addr)(curproc,
 	    (vaddr_t)curproc->p_vmspace->vm_daddr, args->size,
 	    curproc->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN);
@@ -1966,10 +1968,10 @@ i915_gem_mmap_ioctl(struct drm_device *d
 		(VM_PROT_READ | VM_PROT_WRITE), UVM_INH_COPY, UVM_ADV_NORMAL,
 		0));
 	if (ret) {
+		uao_detach(obj->filp);
 		drm_gem_object_unreference_unlocked(obj);
 		return ret;
 	}
-	uao_reference(obj->filp);
 	drm_gem_object_unreference_unlocked(obj);
 #else
 	addr = vm_mmap(obj->filp, 0, args->size,

Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c:1.8 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c:1.9
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c:1.8	Mon Aug 27 14:44:04 2018
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_render_state.c	Mon Aug 27 14:50:04 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: i915_gem_render_state.c,v 1.8 2018/08/27 14:44:04 riastradh Exp $	*/
+/*	$NetBSD: i915_gem_render_state.c,v 1.9 2018/08/27 14:50:04 riastradh Exp $	*/
 
 /*
  * Copyright © 2014 Intel Corporation
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_render_state.c,v 1.8 2018/08/27 14:44:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_render_state.c,v 1.9 2018/08/27 14:50:04 riastradh Exp $");
 
 #include "i915_drv.h"
 #include "intel_renderstate.h"
@@ -114,15 +114,17 @@ static int render_state_setup(struct ren
 
 #ifdef __NetBSD__
 	CTASSERT(PAGE_SIZE == 4096);
+	/* Acquire a reference for uvm_map to consume.  */
+	uao_reference(so->obj->base.filp);
 	kva = 0;		/* hint */
 	/* XXX errno NetBSD->Linux */
 	ret = -uvm_map(kernel_map, &kva, PAGE_SIZE, so->obj->base.filp, 0,
 	    sizeof(*d), UVM_MAPFLAG(UVM_PROT_W, UVM_PROT_W, UVM_INH_NONE,
 		UVM_ADV_NORMAL, 0));
-	if (ret)
+	if (ret) {
+		uao_detach(so->obj->base.filp);
 		return ret;
-	/* uvm_map consumes a reference on success.  */
-	uao_reference(so->obj->base.filp);
+	}
 	d = (void *)kva;
 #else
 	page = sg_page(so->obj->pages->sgl);

Reply via email to