drm/rockchip: vop2: Make sure get the current plane state when calculate bandwidth

Fix dereference of invalid  virtual address when get a cleanuped
plane state:

[   17.908207] Unable to handle kernel NULL pointer dereference at
virtual address 000000000000000c
[   17.911560] Mem abort info:
[   17.911809]   ESR = 0x96000006
[   17.912081]   Exception class = DABT (current EL), IL = 32 bits
[   17.912624]   SET = 0, FnV = 0
[   17.912910]   EA = 0, S1PTW = 0
[   17.913189] Data abort info:
[   17.913466]   ISV = 0, ISS = 0x00000006
[   17.913809]   CM = 0, WnR = 0
[   17.914083] user pgtable: 4k pages, 39-bit VAs, pgdp =
00000000435c7e47
[   17.914681] [000000000000000c] pgd=000000007a6d7003,
pud=000000007a6d7003, pmd=0000000000000000
[   17.915473] Internal error: Oops: 96000006 [#1] SMP
[   17.915907] Modules linked in: bcmdhd
[   17.916240] Process weston (pid: 548, stack limit =
0x00000000f6c6eefe)
[   17.916825] CPU: 0 PID: 548 Comm: weston Not tainted 4.19.154 #312
[   17.917368] Hardware name: Rockchip RK3566 EVB1 DDR4 V10 Linux Board
(DT)
[   17.917970] pstate: 40400009 (nZcv daif +PAN -UAO)
[   17.918417] pc : vop2_crtc_bandwidth+0x21c/0x2dc
[   17.918825] lr : vop2_crtc_bandwidthwhen

[   17.632811] refcount_t: increment on 0; use-after-free.
[   17.632883] WARNING: CPU: 0 PID: 546 at lib/refcount.c:153
refcount_inc_checked+0x38/0x44

[   17.632896] Modules linked in: bcmdhd
[   17.632922] CPU: 0 PID: 546 Comm: weston Not tainted 4.19.154 #311
[   17.632934] Hardware name: Rockchip RK3566 EVB1 DDR4 V10 Linux Board
(DT)
[   17.632943] pstate: 40400009 (nZcv daif +PAN -UAO)
[   17.632951] pc : refcount_inc_checked+0x38/0x44
[   17.632958] lr : refcount_inc_checked+0x38/0x44
[   17.635052] Call trace:
[   17.635069]  refcount_inc_checked+0x38/0x44
[   17.635088]  drm_mode_object_get+0x40/0x4c
[   17.635104]  __drm_atomic_helper_plane_duplicate_state+0x3c/0x50
[   17.635119]  vop2_atomic_plane_duplicate_state+0x4c/0x74
[   17.635129]  drm_atomic_get_plane_state+0xd0/0x154
[   17.635137]  rockchip_atomic_helper_update_plane+0x64/0x128
[   17.635146]  __setplane_atomic+0x148/0x160
[   17.635160]  drm_mode_setplane+0x1f0/0x24c
[   17.635171]  drm_ioctl_kernel+0x8c/0xfc
[   17.635184]  drm_ioctl+0x324/0x3b8
[   17.635204]  vfs_ioctl+0x58/0x68
[   17.635215]  do_vfs_ioctl+0xb4/0x9d4
[   17.635228]  ksys_ioctl+0x50/0x80
[   17.635237]  __arm64_sys_ioctl+0x28/0x38
[   17.635255]  el0_svc_common.constprop.0+0xe8/0x168
[   17.635267]  el0_svc_handler+0x70/0x8c
[   17.635282]  el0_svc+0x8/0xc

Change-Id: I95f6445ff5008c3505ad0cc68b2d005a196cd881
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
Andy Yan
2020-11-12 19:14:16 +08:00
committed by Tao Huang
parent 2f9fd14733
commit 4ac05f48e3

View File

@@ -2327,8 +2327,8 @@ static size_t vop2_crtc_bandwidth(struct drm_crtc *crtc,
if (!pbandwidth)
return -ENOMEM;
drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
pstate = drm_atomic_get_plane_state(state, plane);
if (pstate->crtc != crtc || !pstate->fb)
pstate = drm_atomic_get_new_plane_state(state, plane);
if (!pstate || pstate->crtc != crtc || !pstate->fb)
continue;
vpstate = to_vop2_plane_state(pstate);