drm/vc4/vc4_bo.c: always set bo->resv

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
This commit is contained in:
Hans Verkuil 2017-06-07 21:05:57 +02:00 committed by Eric Anholt
parent dc629141c3
commit 24bb206f32

View File

@ -91,8 +91,7 @@ static void vc4_bo_destroy(struct vc4_bo *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(struct drm_device *dev, size_t size)
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_device *dev, size_t unaligned_size,
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,