Blob Blame History Raw
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Wed, 7 Jun 2017 21:05:57 +0200
Subject: drm/vc4/vc4_bo.c: always set bo->resv
Git-commit: 24bb206f32cdaa76c59444b62be51708dc16fbe8
Patch-mainline: v4.13-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

The bo->resv pointer could be NULL, leading to kernel oopses
like the one below.

This patch ensures that bo->resv is always set in vc4_create_object
ensuring that it is never NULL.

Thanks to Eric Anholt for pointing to the correct solution.

[   19.738487] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   19.746805] pgd = ffff8000275fc000
[   19.750319] [00000000] *pgd=0000000000000000
[   19.754715] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[   19.760369] Modules linked in: smsc95xx usbnet vc4 drm_kms_helper drm pwm_bcm2835 i2c_bcm2835 bcm2835_rng rng_core bcm2835_dma virt_dma
[   19.772767] CPU: 0 PID: 1297 Comm: Xorg Not tainted 4.12.0-rc1-rpi3 #58
[   19.779476] Hardware name: Raspberry Pi 3 Model B (DT)
[   19.784688] task: ffff800028268000 task.stack: ffff800026c08000
[   19.790705] PC is at ww_mutex_lock_interruptible+0x14/0xc0
[   19.796329] LR is at vc4_submit_cl_ioctl+0x4fc/0x998 [vc4]
...
[   20.240855] [<ffff0000088975f4>] ww_mutex_lock_interruptible+0x14/0xc0
[   20.247528] [<ffff0000009b3ea4>] vc4_submit_cl_ioctl+0x4fc/0x998 [vc4]
[   20.254372] [<ffff0000008f75f8>] drm_ioctl+0x180/0x438 [drm]
[   20.260120] [<ffff00000821383c>] do_vfs_ioctl+0xa4/0x7d0
[   20.265510] [<ffff000008213fe4>] SyS_ioctl+0x7c/0x98
[   20.270550] [<ffff000008082f30>] el0_svc_naked+0x24/0x28
[   20.275941] Code: d2800002 d5384103 910003fd f9800011 (c85ffc04)
[   20.282527] ---[ end trace 1f6bd640ff32ae12 ]---

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Link: http://patchwork.freedesktop.org/patch/msgid/14e68768-6c92-2d74-92fd-196dbc50d8f7@xs4all.nl

Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/vc4/vc4_bo.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -91,8 +91,7 @@ static void vc4_bo_destroy(struct vc4_bo
 	vc4->bo_stats.num_allocated--;
 	vc4->bo_stats.size_allocated -= obj->size;
 
-	if (bo->resv == &bo->_resv)
-		reservation_object_fini(bo->resv);
+	reservation_object_fini(&bo->_resv);
 
 	drm_gem_cma_free_object(obj);
 }
@@ -212,6 +211,8 @@ struct drm_gem_object *vc4_create_object
 	vc4->bo_stats.num_allocated++;
 	vc4->bo_stats.size_allocated += size;
 	mutex_unlock(&vc4->bo_lock);
+	bo->resv = &bo->_resv;
+	reservation_object_init(bo->resv);
 
 	return &bo->base.base;
 }
@@ -250,12 +251,7 @@ struct vc4_bo *vc4_bo_create(struct drm_
 			return ERR_PTR(-ENOMEM);
 		}
 	}
-	bo = to_vc4_bo(&cma_obj->base);
-
-	bo->resv = &bo->_resv;
-	reservation_object_init(bo->resv);
-
-	return bo;
+	return to_vc4_bo(&cma_obj->base);
 }
 
 int vc4_dumb_create(struct drm_file *file_priv,