From f6e47884e7f588094bf7b824c839a9ee33f2aa55 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 20 Mar 2011 21:09:12 +0000 Subject: [PATCH] drm/i915: Avoid unmapping pages from a NULL address space Found by gem_stress. As we perform retirement from a workqueue, it is possible for us to free and unbind objects after the last close on the device, and so after the address space has been torn down and reset to NULL: BUG: unable to handle kernel NULL pointer dereference at 00000054 IP: [] mutex_lock+0xf/0x27 *pde = 00000000 Oops: 0002 [#1] SMP last sysfs file: /sys/module/vt/parameters/default_utf8 Pid: 5, comm: kworker/u:0 Not tainted 2.6.38+ #214 EIP: 0060:[] EFLAGS: 00010206 CPU: 1 EIP is at mutex_lock+0xf/0x27 EAX: 00000054 EBX: 00000054 ECX: 00000000 EDX: 00012fff ESI: 00000028 EDI: 00000000 EBP: f706fe20 ESP: f706fe18 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 Process kworker/u:0 (pid: 5, ti=f706e000 task=f7060d00 task.ti=f706e000) Stack: f5aa3c60 00000000 f706fe74 c107e7df 00000246 dea55380 00000054 f5aa3c60 f706fe44 00000061 f70b4000 c13fff84 00000008 f706fe54 00000000 00000000 00012f00 00012fff 00000028 c109e575 f6b36700 00100000 00000000 f706fe90 Call Trace: [] unmap_mapping_range+0x7d/0x1e6 [] ? mntput_no_expire+0x52/0xb6 [] i915_gem_release_mmap+0x49/0x58 [] i915_gem_object_unbind+0x4c/0x125 [] i915_gem_free_object_tail+0x1d/0xdb [] i915_gem_free_object+0x3d/0x41 [] ? drm_gem_object_free+0x0/0x27 [] drm_gem_object_free+0x25/0x27 [] kref_put+0x39/0x42 [] drm_gem_object_unreference+0x16/0x18 [] i915_gem_object_move_to_inactive+0xba/0xbe [] i915_gem_retire_requests_ring+0x16e/0x1a5 [] i915_gem_retire_requests+0x48/0x63 [] i915_gem_retire_work_handler+0x4c/0x117 [] process_one_work+0x140/0x21b [] ? __need_more_worker+0x13/0x2a [] ? need_to_create_worker+0x1c/0x35 [] ? i915_gem_retire_work_handler+0x0/0x117 [] worker_thread+0xd4/0x14b [] ? worker_thread+0x0/0x14b [] kthread+0x68/0x6d [] ? kthread+0x0/0x6d [] kernel_thread_helper+0x6/0x10 Code: 00 e8 98 fe ff ff 5d c3 55 89 e5 3e 8d 74 26 00 ba 01 00 00 00 e8 84 fe ff ff 5d c3 55 89 e5 53 8d 64 24 fc 3e 8d 74 26 00 89 c3 ff 08 79 05 e8 ab ff ff ff 89 e0 25 00 e0 ff ff 89 43 10 58 EIP: [] mutex_lock+0xf/0x27 SS:ESP 0068:f706fe18 CR2: 0000000000000054 Signed-off-by: Chris Wilson Reviewed-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c9bdaf208a91..7ce3f353af33 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1356,9 +1356,10 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) if (!obj->fault_mappable) return; - unmap_mapping_range(obj->base.dev->dev_mapping, - (loff_t)obj->base.map_list.hash.key<base.size, 1); + if (obj->base.dev->dev_mapping) + unmap_mapping_range(obj->base.dev->dev_mapping, + (loff_t)obj->base.map_list.hash.key<base.size, 1); obj->fault_mappable = false; } -- 2.39.5