Message ID | 20250108101351.2599140-1-victor.liu@nxp.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | drm/display: bridge_connector: Do atomic check when necessary | expand |
On Wed, Jan 08, 2025 at 06:13:51PM +0800, Liu Ying wrote: > It's ok to pass atomic check successfully if an atomic commit tries to > disable the display pipeline which the connector belongs to. That is, > when the crtc or the best_encoder pointers in struct drm_connector_state > are NULL, drm_bridge_connector_atomic_check() should return 0 directly. > Without the check against the NULL pointers, drm_default_rgb_quant_range() > called by drm_atomic_helper_connector_hdmi_check() would dereference > the NULL pointer to_match in drm_match_cea_mode(). > [..] > [ 46.823581] pc : drm_default_rgb_quant_range+0x0/0x4c [drm] > [ 46.829244] lr : drm_atomic_helper_connector_hdmi_check+0xb0/0x6b0 [drm_display_helper] > [ 46.837293] sp : ffff80008364ba00 [..] > [ 46.911984] Call trace: > [ 46.914429] drm_default_rgb_quant_range+0x0/0x4c [drm] (P) > [ 46.920106] drm_bridge_connector_atomic_check+0x20/0x2c [drm_display_helper] > [ 46.927275] drm_atomic_helper_check_modeset+0x488/0xc78 [drm_kms_helper] > [ 46.934111] drm_atomic_helper_check+0x20/0xa4 [drm_kms_helper] > [ 46.940063] drm_atomic_check_only+0x4b8/0x984 [drm] > [ 46.945136] drm_atomic_commit+0x48/0xc4 [drm] > [ 46.949674] drm_framebuffer_remove+0x44c/0x530 [drm] > [ 46.954809] drm_mode_rmfb_work_fn+0x7c/0xa0 [drm] > [ 46.959687] process_one_work+0x150/0x294 > [ 46.963700] worker_thread+0x2dc/0x3dc > [ 46.967450] kthread+0x130/0x204 > [ 46.970679] ret_from_fork+0x10/0x20 > [ 46.974258] Code: d50323bf d65f03c0 52800041 17ffffe6 (b9400001) > [ 46.980350] ---[ end trace 0000000000000000 ]--- Please trim the backtrace in a way I trimmed it. Also you can drop the timestamps, they don't have useful information. > > Fixes: 8ec116ff21a9 ("drm/display: bridge_connector: provide atomic_check for HDMI bridges") > Signed-off-by: Liu Ying <victor.liu@nxp.com> > --- > drivers/gpu/drm/display/drm_bridge_connector.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c > index 32108307de66..587020a3f3e8 100644 > --- a/drivers/gpu/drm/display/drm_bridge_connector.c > +++ b/drivers/gpu/drm/display/drm_bridge_connector.c > @@ -343,6 +343,11 @@ static int drm_bridge_connector_atomic_check(struct drm_connector *connector, > { > struct drm_bridge_connector *bridge_connector = > to_drm_bridge_connector(connector); > + struct drm_connector_state *new_conn_state = > + drm_atomic_get_new_connector_state(state, connector); > + > + if (!new_conn_state->crtc || !new_conn_state->best_encoder) > + return 0; Unfortunately, this is not enough. Other drivers (e.g. sun4i) use drm_atomic_helper_connector_hdmi_check() at connector's atomic_check() function. Please move necessary checks to the helper itself. Also please add corresponding KUnit test: attempt to atomic_check() the unconnected HDMI connector, there is a test suite for the HDMI connector functions, but the atomic_check() for the disconnected connecor seems to be missing. > > if (bridge_connector->bridge_hdmi) > return drm_atomic_helper_connector_hdmi_check(connector, state); > -- > 2.34.1 >
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 32108307de66..587020a3f3e8 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -343,6 +343,11 @@ static int drm_bridge_connector_atomic_check(struct drm_connector *connector, { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); + struct drm_connector_state *new_conn_state = + drm_atomic_get_new_connector_state(state, connector); + + if (!new_conn_state->crtc || !new_conn_state->best_encoder) + return 0; if (bridge_connector->bridge_hdmi) return drm_atomic_helper_connector_hdmi_check(connector, state);
It's ok to pass atomic check successfully if an atomic commit tries to disable the display pipeline which the connector belongs to. That is, when the crtc or the best_encoder pointers in struct drm_connector_state are NULL, drm_bridge_connector_atomic_check() should return 0 directly. Without the check against the NULL pointers, drm_default_rgb_quant_range() called by drm_atomic_helper_connector_hdmi_check() would dereference the NULL pointer to_match in drm_match_cea_mode(). [ 46.189903] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ 46.189906] Mem abort info: [ 46.189908] ESR = 0x0000000096000004 [ 46.189910] EC = 0x25: DABT (current EL), IL = 32 bits [ 46.189914] SET = 0, FnV = 0 [ 46.189917] EA = 0, S1PTW = 0 [ 46.189919] FSC = 0x04: level 0 translation fault [ 46.189922] Data abort info: [ 46.189923] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 [ 46.189926] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 46.189929] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 46.189932] user pgtable: 4k pages, 48-bit VAs, pgdp=000000010b6b4000 [ 46.189936] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 [ 46.189945] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP [ 46.719532] Modules linked in: caam_jr caamhash_desc caamalg_desc dw_hdmi_cec crypto_engine snd_soc_hdmi_codec authenc libdes hantro_vpu mwifiex_pcie mwifiex v4l2_vp9 v4l2_h264 imx8 mp_hdmi_tx v4l2_jpeg v4l2_mem2mem dw_hdmi videobuf2_dma_contig videobuf2_memops ite_it6263 videobuf2_v4l2 snd_soc_simple_card drm_display_helper videodev snd_soc_wm8960 snd_soc_simple_ card_utils fsl_ldb samsung_dsim videobuf2_common etnaviv mc fsl_imx8_ddr_perf gpu_sched imx_lcdif adv7511 phy_fsl_samsung_hdmi drm_client_lib snd_soc_fsl_micfil drm_dma_helper cec imx8 mp_hdmi_pvi snd_soc_fsl_sai imx_pcm_dma snd_soc_fsl_utils rtc_snvs pwm_imx27 snvs_pwrkey flexcan caam can_dev error imx8mm_thermal imx_sdma coresight_tmc display_connector drm_kms_help er snd_soc_bt_sco imx_cpufreq_dt coresight_funnel coresight overlay bluetooth ecdh_generic ecc cfg80211 rfkill drm fuse backlight ipv6 [ 46.795415] CPU: 3 UID: 0 PID: 64 Comm: kworker/3:1 Not tainted 6.13.0-rc6-next-20250107-00009-g045f95f0de2e #1637 [ 46.805767] Hardware name: NXP i.MX8MPlus EVK board (DT) [ 46.811078] Workqueue: events drm_mode_rmfb_work_fn [drm] [ 46.816619] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 46.823581] pc : drm_default_rgb_quant_range+0x0/0x4c [drm] [ 46.829244] lr : drm_atomic_helper_connector_hdmi_check+0xb0/0x6b0 [drm_display_helper] [ 46.837293] sp : ffff80008364ba00 [ 46.840605] x29: ffff80008364ba10 x28: ffff0000c8955080 x27: ffff0000c2e1c700 [ 46.847743] x26: ffff0000d3887200 x25: ffff0000c2e1c700 x24: ffff0000d3887400 [ 46.854881] x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000c8955080 [ 46.862019] x20: 0000000000000001 x19: ffff0000d3887c00 x18: 00000000ffffffff [ 46.869157] x17: 0000000000000000 x16: 0000000000000000 x15: ffff800082ce6911 [ 46.876293] x14: 0000000000000001 x13: ffff8000827e4a88 x12: 00000000000015f0 [ 46.883435] x11: 0000000000000750 x10: ffff80008283ca88 x9 : ffff8000827e4a88 [ 46.890573] x8 : 00000000ffffefff x7 : 0000000000000038 x6 : ffff0000db2c3440 [ 46.897711] x5 : 0000000000000001 x4 : 0000000000000038 x3 : ffff0000db2c3440 [ 46.904847] x2 : 0000000000000000 x1 : 0000000000000001 x0 : 0000000000000000 [ 46.911984] Call trace: [ 46.914429] drm_default_rgb_quant_range+0x0/0x4c [drm] (P) [ 46.920106] drm_bridge_connector_atomic_check+0x20/0x2c [drm_display_helper] [ 46.927275] drm_atomic_helper_check_modeset+0x488/0xc78 [drm_kms_helper] [ 46.934111] drm_atomic_helper_check+0x20/0xa4 [drm_kms_helper] [ 46.940063] drm_atomic_check_only+0x4b8/0x984 [drm] [ 46.945136] drm_atomic_commit+0x48/0xc4 [drm] [ 46.949674] drm_framebuffer_remove+0x44c/0x530 [drm] [ 46.954809] drm_mode_rmfb_work_fn+0x7c/0xa0 [drm] [ 46.959687] process_one_work+0x150/0x294 [ 46.963700] worker_thread+0x2dc/0x3dc [ 46.967450] kthread+0x130/0x204 [ 46.970679] ret_from_fork+0x10/0x20 [ 46.974258] Code: d50323bf d65f03c0 52800041 17ffffe6 (b9400001) [ 46.980350] ---[ end trace 0000000000000000 ]--- Fixes: 8ec116ff21a9 ("drm/display: bridge_connector: provide atomic_check for HDMI bridges") Signed-off-by: Liu Ying <victor.liu@nxp.com> --- drivers/gpu/drm/display/drm_bridge_connector.c | 5 +++++ 1 file changed, 5 insertions(+)