Hi,
While working on Apalis iMX6 with four displays, I encountered the following crash:
... [ 2.978166] imx-drm display-subsystem: trying to bring up master [ 2.984368] imx-drm display-subsystem: Looking for component 0 [ 2.990236] imx-drm display-subsystem: master has incomplete components [ 2.998774] imx-parallel-display parallel-display-controller0: adding component (ops imx_pd_ops) [ 3.007697] imx-drm display-subsystem: trying to bring up master [ 3.013812] imx-drm display-subsystem: Looking for component 0 [ 3.019679] imx-drm display-subsystem: master has incomplete components [ 3.027117] imx-parallel-display parallel-display-controller1: adding component (ops imx_pd_ops) [ 3.036016] imx-drm display-subsystem: trying to bring up master [ 3.042128] imx-drm display-subsystem: Looking for component 0 [ 3.047990] imx-drm display-subsystem: master has incomplete components [ 3.055667] imx_ldb_probe [ 3.058336] imx-ldb ldb: adding component (ops imx_ldb_ops) [ 3.064021] imx-drm display-subsystem: trying to bring up master [ 3.070061] imx-drm display-subsystem: Looking for component 0 [ 3.075996] imx-drm display-subsystem: master has incomplete components [ 3.083712] dwhdmi-imx 120000.hdmi: adding component (ops dw_hdmi_imx_ops) [ 3.090709] imx-drm display-subsystem: trying to bring up master [ 3.096747] imx-drm display-subsystem: Looking for component 0 [ 3.102682] imx-drm display-subsystem: master has incomplete components [ 3.115134] panel-simple panel: Linked as a consumer to regulator.13 [ 3.123207] etnaviv-gpu 130000.gpu: adding component (ops gpu_ops) [ 3.129424] imx-drm display-subsystem: trying to bring up master [ 3.135550] imx-drm display-subsystem: Looking for component 0 [ 3.141491] imx-drm display-subsystem: master has incomplete components [ 3.149460] etnaviv-gpu 134000.gpu: adding component (ops gpu_ops) [ 3.155772] imx-drm display-subsystem: trying to bring up master [ 3.161886] imx-drm display-subsystem: Looking for component 0 [ 3.167751] imx-drm display-subsystem: master has incomplete components [ 3.175988] etnaviv-gpu 2204000.gpu: adding component (ops gpu_ops) [ 3.182386] imx-drm display-subsystem: trying to bring up master [ 3.188426] imx-drm display-subsystem: Looking for component 0 [ 3.194367] imx-drm display-subsystem: master has incomplete components [ 3.202629] etnaviv etnaviv: trying to bring up master [ 3.207806] etnaviv etnaviv: Looking for component 0 [ 3.212887] etnaviv etnaviv: found component 130000.gpu, duplicate 0 [ 3.219275] etnaviv etnaviv: Looking for component 1 [ 3.224345] etnaviv etnaviv: found component 134000.gpu, duplicate 0 [ 3.230796] etnaviv etnaviv: Looking for component 2 [ 3.235791] etnaviv etnaviv: found component 2204000.gpu, duplicate 0 [ 3.243093] etnaviv etnaviv: binding 130000.gpu (ops gpu_ops) [ 3.250918] etnaviv etnaviv: bound 130000.gpu (ops gpu_ops) [ 3.256547] etnaviv etnaviv: binding 134000.gpu (ops gpu_ops) [ 3.263052] etnaviv etnaviv: bound 134000.gpu (ops gpu_ops) [ 3.268678] etnaviv etnaviv: binding 2204000.gpu (ops gpu_ops) [ 3.275268] etnaviv etnaviv: bound 2204000.gpu (ops gpu_ops) [ 3.281064] etnaviv-gpu 130000.gpu: model: GC2000, revision: 5108 [ 3.299883] etnaviv-gpu 134000.gpu: model: GC320, revision: 5007 [ 3.319255] etnaviv-gpu 2204000.gpu: model: GC355, revision: 1215 [ 3.325491] etnaviv-gpu 2204000.gpu: Ignoring GPU with VG and FE2.0 [ 3.334102] [drm] Initialized etnaviv 1.2.0 20151214 for etnaviv on minor 0 [ 3.346005] imx-ipuv3-crtc imx-ipuv3-crtc.2: adding component (ops ipu_crtc_ops) [ 3.353520] imx-drm display-subsystem: trying to bring up master [ 3.359596] imx-drm display-subsystem: Looking for component 0 [ 3.365518] imx-drm display-subsystem: found component imx-ipuv3-crtc.2, duplicate 0 [ 3.373342] imx-drm display-subsystem: Looking for component 1 [ 3.379206] imx-drm display-subsystem: master has incomplete components [ 3.386415] imx-ipuv3-crtc imx-ipuv3-crtc.3: adding component (ops ipu_crtc_ops) [ 3.393901] imx-drm display-subsystem: trying to bring up master [ 3.399939] imx-drm display-subsystem: Looking for component 0 [ 3.405852] imx-drm display-subsystem: Looking for component 1 [ 3.411770] imx-drm display-subsystem: found component imx-ipuv3-crtc.3, duplicate 0 [ 3.419542] imx-drm display-subsystem: Looking for component 2 [ 3.425456] imx-drm display-subsystem: master has incomplete components [ 3.432224] imx-ipuv3 2400000.ipu: IPUv3H probed [ 3.438945] imx-ipuv3-crtc imx-ipuv3-crtc.6: adding component (ops ipu_crtc_ops) [ 3.446435] imx-drm display-subsystem: trying to bring up master [ 3.452526] imx-drm display-subsystem: Looking for component 0 [ 3.458389] imx-drm display-subsystem: Looking for component 1 [ 3.464336] imx-drm display-subsystem: Looking for component 2 [ 3.470202] imx-drm display-subsystem: found component imx-ipuv3-crtc.6, duplicate 0 [ 3.478040] imx-drm display-subsystem: Looking for component 3 [ 3.483969] imx-drm display-subsystem: master has incomplete components [ 3.491183] imx-ipuv3-crtc imx-ipuv3-crtc.7: adding component (ops ipu_crtc_ops) [ 3.498612] imx-drm display-subsystem: trying to bring up master [ 3.504758] imx-drm display-subsystem: Looking for component 0 [ 3.510679] imx-drm display-subsystem: Looking for component 1 [ 3.516541] imx-drm display-subsystem: Looking for component 2 [ 3.522470] imx-drm display-subsystem: Looking for component 3 [ 3.528336] imx-drm display-subsystem: found component imx-ipuv3-crtc.7, duplicate 0 [ 3.536169] imx-drm display-subsystem: Looking for component 4 [ 3.542110] imx-drm display-subsystem: found component 120000.hdmi, duplicate 0 [ 3.549449] imx-drm display-subsystem: Looking for component 5 [ 3.555430] imx-drm display-subsystem: found component ldb, duplicate 0 [ 3.562134] imx-drm display-subsystem: Looking for component 6 [ 3.567999] imx-drm display-subsystem: found component parallel-display-controller1, duplicate 0 [ 3.576873] imx-drm display-subsystem: Looking for component 7 [ 3.582788] imx-drm display-subsystem: found component 120000.hdmi, duplicate 1 [ 3.590126] imx-drm display-subsystem: Looking for component 8 [ 3.596057] imx-drm display-subsystem: found component ldb, duplicate 1 [ 3.602752] imx-drm display-subsystem: Looking for component 9 [ 3.608615] imx-drm display-subsystem: found component parallel-display-controller0, duplicate 0 [ 3.617487] imx-drm display-subsystem: Looking for component 10 [ 3.623488] imx-drm display-subsystem: found component 120000.hdmi, duplicate 1 [ 3.630884] imx-drm display-subsystem: Looking for component 11 [ 3.636843] imx-drm display-subsystem: found component ldb, duplicate 1 [ 3.643537] imx-drm display-subsystem: Looking for component 12 [ 3.649486] imx-drm display-subsystem: found component 120000.hdmi, duplicate 1 [ 3.656881] imx-drm display-subsystem: Looking for component 13 [ 3.662891] imx-drm display-subsystem: found component ldb, duplicate 1 [ 3.670184] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013). [ 3.676937] [drm] No driver support for vblank timestamp query. [ 3.682982] imx-drm display-subsystem: binding imx-ipuv3-crtc.2 (ops ipu_crtc_ops) [ 3.691707] imx-drm display-subsystem: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) [ 3.699155] imx-drm display-subsystem: binding imx-ipuv3-crtc.3 (ops ipu_crtc_ops) [ 3.707122] imx-drm display-subsystem: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) [ 3.714637] imx-drm display-subsystem: binding imx-ipuv3-crtc.6 (ops ipu_crtc_ops) [ 3.722667] imx-drm display-subsystem: bound imx-ipuv3-crtc.6 (ops ipu_crtc_ops) [ 3.730111] imx-drm display-subsystem: binding imx-ipuv3-crtc.7 (ops ipu_crtc_ops) [ 3.738068] imx-drm display-subsystem: bound imx-ipuv3-crtc.7 (ops ipu_crtc_ops) [ 3.745580] imx-drm display-subsystem: binding 120000.hdmi (ops dw_hdmi_imx_ops) [ 3.753241] drm_encoder_init, encoder ec861894 [ 3.758489] dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP (DWC HDMI 3D TX PHY) [ 3.769712] dwhdmi-imx 120000.hdmi: registered DesignWare HDMI I2C bus driver [ 3.781163] imx-drm display-subsystem: bound 120000.hdmi (ops dw_hdmi_imx_ops) [ 3.788441] imx-drm display-subsystem: binding ldb (ops imx_ldb_ops) [ 3.794902] imx_ldb_bind, imx_ldb ec0da010 [ 3.799818] drm_encoder_init, encoder ec0da388 [ 3.804363] drm_encoder_init, ret 0 [ 3.807908] imx_ldb_register, encoder ec0da388 [ 3.812432] imx_ldb_register, ret 0 [ 3.815951] imx_ldb_bind encoder LVDS-46, ec0da388 ->func c0e6371c [ 3.822227] imx_ldb_bind, done [ 3.825331] imx-drm display-subsystem: bound ldb (ops imx_ldb_ops) [ 3.831614] imx-drm display-subsystem: binding parallel-display-controller1 (ops imx_pd_ops) [ 3.840285] drm_encoder_init, encoder ec8a2b78 [ 3.844931] imx-drm display-subsystem: Linked as a consumer to panel [ 3.851472] imx-drm display-subsystem: bound parallel-display-controller1 (ops imx_pd_ops) [ 3.859785] imx-drm display-subsystem: binding parallel-display-controller0 (ops imx_pd_ops) [ 3.868561] imx-drm display-subsystem: failed to bind parallel-display-controller0 (ops imx_pd_ops): -517 [ 3.878225] imx-drm display-subsystem: Dropping the link to panel [ 3.884679] imx_ldb_unbind [ 3.887421] imx_ldb_unbind, encoder LVDS-46, ec0da388 ->func c0e6371c [ 3.893950] imx_ldb_unbind, encoder (null), ec0da838 ->func 0 [ 3.899723] imx_ldb_unbind, done [ 3.908345] imx_drm_bind, component_bind_all, ret -517 [ 3.913638] drm_mode_config_cleanup, encoder TMDS-44, ec861894 ->funcs c0e63a18 [ 3.921260] drm_mode_config_cleanup, calling encoder->funcs->destroy! [ 3.927897] drm_encoder_cleanup, encoder ec861894 [ 3.932717] drm_mode_config_cleanup, encoder (null), ec0da388 ->funcs 0 [ 3.939356] drm_mode_config_cleanup, calling encoder->funcs->destroy! [ 3.946050] Unable to handle kernel NULL pointer dereference at virtual address 00000004 [ 3.954238] pgd = (ptrval) [ 3.956973] [00000004] *pgd=00000000 [ 3.960650] Internal error: Oops: 5 [#1] SMP ARM [ 3.965283] Modules linked in: [ 3.968364] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.0-rc3+ #314 [ 3.974901] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 3.981455] PC is at drm_mode_config_cleanup+0x304/0x364 [ 3.986787] LR is at vprintk_emit+0xd8/0x258 [ 3.991070] pc : [<c066f544>] lr : [<c01a7c64>] psr: 60000013 [ 3.997347] sp : ec0d5a10 ip : ec0d5960 fp : ec0d5a6c [ 4.002583] r10: c112d4c4 r9 : c112d490 r8 : c112d464 [ 4.007819] r7 : fffffffc r6 : ec446000 r5 : fffffffc r4 : ec4464d4 [ 4.014357] r3 : 00000000 r2 : f411825b r1 : ffffff30 r0 : ec0da388 [ 4.020898] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 4.028046] Control: 10c5387d Table: 1000404a DAC: 00000051 [ 4.033802] Process swapper/0 (pid: 1, stack limit = 0x(ptrval)) [ 4.039820] Stack: (0xec0d5a10 to 0xec0d6000) [ 4.044192] 5a00: c01a8bb0 c01a7f8c ffffffec 00000000 [ 4.052386] 5a20: c1408908 fffffdfb c147bd78 ec2e5c10 ec0d5a5c ec0d5a40 c01a8404 f411825b [ 4.060578] 5a40: ec0d5a64 ec446000 fffffdfb c147bd78 ec2e5c10 0000000e ec800990 c147cc24 [ 4.068770] 5a60: ec0d5a8c ec0d5a70 c067ae74 c066f24c ec805ac0 00000118 ec8009c0 ef6d5d98 [ 4.076962] 5a80: ec0d5acc ec0d5a90 c06a17a8 c067ae00 00000001 ec830400 ec830400 00000104 [ 4.085154] 5aa0: c147bee0 ec8009c0 00000000 ec830400 c147cc1c 00000000 c147bee0 00000000 [ 4.093345] 5ac0: ec0d5aec ec0d5ad0 c06a18d0 c06a157c ec83fde0 ec83fc10 c147bee0 00000000 [ 4.101536] 5ae0: ec0d5b04 ec0d5af0 c067bbbc c06a1820 ec83fc10 00000000 ec0d5b24 ec0d5b08 [ 4.109728] 5b00: c06aa8d8 c067bb54 ec83fc10 c1c752cc c1c752d0 00000000 ec0d5b5c ec0d5b28 [ 4.117921] 5b20: c06a8204 c06aa894 ec83fc10 ec83fd88 ec0d5b5c ec83fc10 c147bee0 ec83fc10 [ 4.126112] 5b40: ec0d5be4 00000001 c1c75288 00000000 ec0d5b8c ec0d5b60 c06a85c0 c06a7fe0 [ 4.134304] 5b60: ec0d5b8c ec0d5b70 c147bee0 00000001 ec83fc10 ec0d5be4 00000001 c1c75288 [ 4.142495] 5b80: ec0d5bac ec0d5b90 c06a88ec c06a8558 00000000 ec0d5be4 c06a8848 c1408908 [ 4.150687] 5ba0: ec0d5bdc ec0d5bb0 c06a6010 c06a8854 ec0d5bdc ec1582d4 ec7b2fd4 f411825b [ 4.158879] 5bc0: ec83fc10 ec83fc44 c1408908 ec83fc10 ec0d5c14 ec0d5be0 c06a7f20 c06a5fc0 [ 4.167070] 5be0: c1c75288 ec83fc10 00000001 f411825b ec2e5410 ec83fc18 c147d410 ec83fc10 [ 4.175262] 5c00: ec83fc10 c1408908 ec0d5c24 ec0d5c18 c06a89d0 c06a7e58 ec0d5c44 ec0d5c28 [ 4.183453] 5c20: c06a7094 c06a89c8 ec83fc18 ec2e5410 00000000 ec83fc10 ec0d5c94 ec0d5c48 [ 4.191644] 5c40: c06a389c c06a7010 c0d0af58 00000000 c1408908 00000007 ec83fc00 ec83fc10 [ 4.199836] 5c60: ec0d5c88 f411825b c06a2358 00000000 00000007 ec83fc00 ec83fc10 ec83fc00 [ 4.208027] 5c80: ec2e5410 c147c8b8 ec0d5cbc ec0d5c98 c06aa6a4 c06a3498 ef6f2818 00000007 [ 4.216218] 5ca0: 00000003 ec2e5410 ec83fc00 ec2e5410 ec0d5d4c ec0d5cc0 c06957fc c06aa598 [ 4.224409] 5cc0: 00000080 ec84f300 00000000 00000000 ec80e610 00000000 c147c938 00000004 [ 4.232601] 5ce0: 400100d0 ffe000fd 400100d0 ffe000fd 400100d0 ffe000fd 4077ffff ffe7e1fd [ 4.240794] 5d00: 23fffffe 8880fff0 f98fe7d0 fff81fff 400100d0 ffe000fd 00000000 f411825b [ 4.248986] 5d20: c06c0260 ec2e5410 00000000 c147c8ec 00000000 00000000 c147c8ec 00000000 [ 4.257179] 5d40: ec0d5d6c ec0d5d50 c06aa8d8 c0694d9c ec2e5410 c1c752cc c1c752d0 00000000 [ 4.265371] 5d60: ec0d5da4 ec0d5d70 c06a8204 c06aa894 ec2e5410 ec2e5588 ec0d5da4 ec2e5410 [ 4.273564] 5d80: c147c8ec c147c8ec c1408908 00000000 c06aa888 c147d410 ec0d5dd4 ec0d5da8 [ 4.281757] 5da0: c06a85c0 c06a7fe0 c06aa888 c147d410 ec2e5410 ec2e5444 c147c8ec c1408908 [ 4.289948] 5dc0: 00000000 c06aa888 ec0d5df4 ec0d5dd8 c06a8820 c06a8558 00000000 c147c8ec [ 4.298140] 5de0: c06a8708 c1408908 ec0d5e24 ec0d5df8 c06a5f4c c06a8714 ec0d5e1c ec1582a4 [ 4.306333] 5e00: ec2b8ad0 f411825b c147c8ec ec839100 c147d410 c14f5310 ec0d5e34 ec0d5e28 [ 4.314524] 5e20: c06a7a40 c06a5ee0 ec0d5e64 ec0d5e38 c06a738c c06a7a2c c1131978 00000003 [ 4.322717] 5e40: ec0d5e64 c147c8ec 00000002 c14f5610 00000003 00000000 ec0d5e7c ec0d5e68 [ 4.330908] 5e60: c06a96fc c06a71ec c0e6e380 00000002 ec0d5eb4 ec0d5e80 c06aaa04 c06a968c [ 4.339101] 5e80: c0e6e374 c0e6e37c c0196b58 c1408930 c1408908 00000000 c135e474 c14e9f60 [ 4.347293] 5ea0: c14e8bfc ffffe000 ec0d5ec4 ec0d5eb8 c135e490 c06aa9b4 ec0d5f44 ec0d5ec8 [ 4.355485] 5ec0: c0103194 c135e480 0000011b 00000000 ec0d5f44 ec0d5e00 c0155dcc c13006d0 [ 4.363676] 5ee0: 00000000 f411825b ffffe000 00000000 60000013 c14e9f60 c139884c c1408930 [ 4.371868] 5f00: ec0d5f2c ec0d5f10 c0196b58 c0196a4c c1465094 f411825b 00000007 c13b2aa0 [ 4.380059] 5f20: c1507200 00000007 c14e9f60 c1398850 c1408930 ffffe000 ec0d5f94 ec0d5f48 [ 4.388250] 5f40: c1301354 c0103118 00000006 00000006 00000000 c13006c4 c0d232b0 c0224304 [ 4.396442] 5f60: c122e548 0000011b ec0d5f8c 00000000 c0d1b4d8 00000000 00000000 00000000 [ 4.404633] 5f80: 00000000 00000000 ec0d5fac ec0d5f98 c0d1b4e8 c1300f8c 00000000 c0d1b4d8 [ 4.412824] 5fa0: 00000000 ec0d5fb0 c01010b4 c0d1b4e4 00000000 00000000 00000000 00000000 [ 4.421015] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.429205] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 4.437389] Backtrace: [ 4.439868] [<c066f240>] (drm_mode_config_cleanup) from [<c067ae74>] (imx_drm_bind+0x80/0x14c) [ 4.448496] r10:c147cc24 r9:ec800990 r8:0000000e r7:ec2e5c10 r6:c147bd78 r5:fffffdfb [ 4.456335] r4:ec446000 [ 4.458893] [<c067adf4>] (imx_drm_bind) from [<c06a17a8>] (try_to_bring_up_master+0x238/0x2a4) [ 4.467517] r7:ef6d5d98 r6:ec8009c0 r5:00000118 r4:ec805ac0 [ 4.473195] [<c06a1570>] (try_to_bring_up_master) from [<c06a18d0>] (component_add+0xbc/0x174) [ 4.481820] r10:00000000 r9:c147bee0 r8:00000000 r7:c147cc1c r6:ec830400 r5:00000000 [ 4.489659] r4:ec8009c0 [ 4.492211] [<c06a1814>] (component_add) from [<c067bbbc>] (ipu_drm_probe+0x74/0x9c) [ 4.499966] r7:00000000 r6:c147bee0 r5:ec83fc10 r4:ec83fde0 [ 4.505648] [<c067bb48>] (ipu_drm_probe) from [<c06aa8d8>] (platform_drv_probe+0x50/0xa0) [ 4.513836] r5:00000000 r4:ec83fc10 [ 4.517430] [<c06aa888>] (platform_drv_probe) from [<c06a8204>] (really_probe+0x230/0x408) [ 4.525706] r7:00000000 r6:c1c752d0 r5:c1c752cc r4:ec83fc10 [ 4.531380] [<c06a7fd4>] (really_probe) from [<c06a85c0>] (driver_probe_device+0x74/0x1bc) [ 4.539658] r10:00000000 r9:c1c75288 r8:00000001 r7:ec0d5be4 r6:ec83fc10 r5:c147bee0 [ 4.547496] r4:ec83fc10 [ 4.550047] [<c06a854c>] (driver_probe_device) from [<c06a88ec>] (__device_attach_driver+0xa4/0x13c) [ 4.559195] r9:c1c75288 r8:00000001 r7:ec0d5be4 r6:ec83fc10 r5:00000001 r4:c147bee0 [ 4.566954] [<c06a8848>] (__device_attach_driver) from [<c06a6010>] (bus_for_each_drv+0x5c/0xc0) [ 4.575751] r7:c1408908 r6:c06a8848 r5:ec0d5be4 r4:00000000 [ 4.581425] [<c06a5fb4>] (bus_for_each_drv) from [<c06a7f20>] (__device_attach+0xd4/0x170) [ 4.589702] r7:ec83fc10 r6:c1408908 r5:ec83fc44 r4:ec83fc10 [ 4.595378] [<c06a7e4c>] (__device_attach) from [<c06a89d0>] (device_initial_probe+0x14/0x18) [ 4.603916] r8:c1408908 r7:ec83fc10 r6:ec83fc10 r5:c147d410 r4:ec83fc18 [ 4.610634] [<c06a89bc>] (device_initial_probe) from [<c06a7094>] (bus_probe_device+0x90/0x98) [ 4.619266] [<c06a7004>] (bus_probe_device) from [<c06a389c>] (device_add+0x410/0x654) [ 4.627196] r7:ec83fc10 r6:00000000 r5:ec2e5410 r4:ec83fc18 [ 4.632873] [<c06a348c>] (device_add) from [<c06aa6a4>] (platform_device_add+0x118/0x26c) [ 4.641066] r10:c147c8b8 r9:ec2e5410 r8:ec83fc00 r7:ec83fc10 r6:ec83fc00 r5:00000007 [ 4.648904] r4:00000000 [ 4.651463] [<c06aa58c>] (platform_device_add) from [<c06957fc>] (ipu_probe+0xa6c/0xc94) [ 4.659569] r9:ec2e5410 r8:ec83fc00 r7:ec2e5410 r6:00000003 r5:00000007 r4:ef6f2818 [ 4.667329] [<c0694d90>] (ipu_probe) from [<c06aa8d8>] (platform_drv_probe+0x50/0xa0) [ 4.675174] r10:00000000 r9:c147c8ec r8:00000000 r7:00000000 r6:c147c8ec r5:00000000 [ 4.683012] r4:ec2e5410 [ 4.685563] [<c06aa888>] (platform_drv_probe) from [<c06a8204>] (really_probe+0x230/0x408) [ 4.693840] r7:00000000 r6:c1c752d0 r5:c1c752cc r4:ec2e5410 [ 4.699514] [<c06a7fd4>] (really_probe) from [<c06a85c0>] (driver_probe_device+0x74/0x1bc) [ 4.707793] r10:c147d410 r9:c06aa888 r8:00000000 r7:c1408908 r6:c147c8ec r5:c147c8ec [ 4.715631] r4:ec2e5410 [ 4.718181] [<c06a854c>] (driver_probe_device) from [<c06a8820>] (__driver_attach+0x118/0x140) [ 4.726806] r9:c06aa888 r8:00000000 r7:c1408908 r6:c147c8ec r5:ec2e5444 r4:ec2e5410 [ 4.734564] [<c06a8708>] (__driver_attach) from [<c06a5f4c>] (bus_for_each_dev+0x78/0xbc) [ 4.742753] r7:c1408908 r6:c06a8708 r5:c147c8ec r4:00000000 [ 4.748428] [<c06a5ed4>] (bus_for_each_dev) from [<c06a7a40>] (driver_attach+0x20/0x28) [ 4.756444] r7:c14f5310 r6:c147d410 r5:ec839100 r4:c147c8ec [ 4.762119] [<c06a7a20>] (driver_attach) from [<c06a738c>] (bus_add_driver+0x1ac/0x26c) [ 4.770137] [<c06a71e0>] (bus_add_driver) from [<c06a96fc>] (driver_register+0x7c/0x110) [ 4.778240] r8:00000000 r7:00000003 r6:c14f5610 r5:00000002 r4:c147c8ec [ 4.784958] [<c06a9680>] (driver_register) from [<c06aaa04>] (__platform_register_drivers+0x5c/0x144) [ 4.794186] r5:00000002 r4:c0e6e380 [ 4.797784] [<c06aa9a8>] (__platform_register_drivers) from [<c135e490>] (imx_ipu_init+0x1c/0x24) [ 4.806672] r10:ffffe000 r9:c14e8bfc r8:c14e9f60 r7:c135e474 r6:00000000 r5:c1408908 [ 4.814510] r4:c1408930 [ 4.817064] [<c135e474>] (imx_ipu_init) from [<c0103194>] (do_one_initcall+0x88/0x318) [ 4.825005] [<c010310c>] (do_one_initcall) from [<c1301354>] (kernel_init_freeable+0x3d4/0x4b8) [ 4.833720] r10:ffffe000 r9:c1408930 r8:c1398850 r7:c14e9f60 r6:00000007 r5:c1507200 [ 4.841558] r4:c13b2aa0 [ 4.844115] [<c1300f80>] (kernel_init_freeable) from [<c0d1b4e8>] (kernel_init+0x10/0x11c) [ 4.852394] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0d1b4d8 [ 4.860232] r4:00000000 [ 4.862783] [<c0d1b4d8>] (kernel_init) from [<c01010b4>] (ret_from_fork+0x14/0x20) [ 4.870362] Exception stack(0xec0d5fb0 to 0xec0d5ff8) [ 4.875426] 5fa0: 00000000 00000000 00000000 00000000 [ 4.883618] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.891808] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 [ 4.898432] r5:c0d1b4d8 r4:00000000 [ 4.902025] Code: ebece3a5 e595303c e1a00005 e1a05007 (e5933004) [ 4.908239] ---[ end trace 839be2ff59e9785c ]--- [ 4.913020] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 4.913020] [ 4.922186] CPU1: stopping [ 4.924914] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G D 4.19.0-rc3+ #314 [ 4.932844] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 4.939381] Backtrace: [ 4.941857] [<c010ebc8>] (dump_backtrace) from [<c010ee98>] (show_stack+0x18/0x1c) [ 4.949443] r7:00000000 r6:60000193 r5:00000000 r4:c14e19ac [ 4.955121] [<c010ee80>] (show_stack) from [<c0d05978>] (dump_stack+0xb4/0xec) [ 4.962364] [<c0d058c4>] (dump_stack) from [<c0112eb8>] (handle_IPI+0x358/0x3a0) [ 4.969777] r10:ffffe000 r9:c14e9fc4 r8:00000000 r7:00000001 r6:00000004 r5:c1408d64 [ 4.977619] r4:c13bd3e8 r3:f411825b [ 4.981217] [<c0112b60>] (handle_IPI) from [<c057a56c>] (gic_handle_irq+0xb0/0xc4) [ 4.988803] r10:c14653a8 r9:ec117f20 r8:c1409044 r7:f4000100 r6:000003ff r5:000003eb [ 4.996644] r4:f400010c [ 4.999197] [<c057a4bc>] (gic_handle_irq) from [<c0101a30>] (__irq_svc+0x70/0x98) [ 5.006692] Exception stack(0xec117f20 to 0xec117f68) [ 5.011761] 7f20: c010a850 00000000 60000093 c011fc40 ffffe000 c1408930 00000002 c1408978 [ 5.019954] 7f40: 00000000 00000000 c1408908 ec117f7c ec117f40 ec117f70 c0224380 c010a854 [ 5.028142] 7f60: 60000013 ffffffff [ 5.031646] r10:c1408908 r9:ec116000 r8:00000000 r7:ec117f54 r6:ffffffff r5:60000013 [ 5.039485] r4:c010a854 [ 5.042047] [<c010a82c>] (arch_cpu_idle) from [<c0d22fa8>] (default_idle_call+0x28/0x38) [ 5.050161] [<c0d22f80>] (default_idle_call) from [<c016ac38>] (do_idle+0x1c0/0x2c8) [ 5.057922] [<c016aa78>] (do_idle) from [<c016b0f4>] (cpu_startup_entry+0x20/0x24) [ 5.065507] r10:00000000 r9:412fc09a r8:1000406a r7:c1507560 r6:10c0387d r5:00000001 [ 5.073346] r4:00000086 [ 5.075899] [<c016b0d4>] (cpu_startup_entry) from [<c01128c8>] (secondary_start_kernel+0x15c/0x1a4) [ 5.084961] [<c011276c>] (secondary_start_kernel) from [<1010278c>] (0x1010278c) [ 5.092368] r5:00000051 r4:3c10406a [ 5.095956] CPU3: stopping [ 5.098686] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G D 4.19.0-rc3+ #314 [ 5.106613] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 5.113149] Backtrace: [ 5.115622] [<c010ebc8>] (dump_backtrace) from [<c010ee98>] (show_stack+0x18/0x1c) [ 5.123207] r7:00000000 r6:60000193 r5:00000000 r4:c14e19ac [ 5.128883] [<c010ee80>] (show_stack) from [<c0d05978>] (dump_stack+0xb4/0xec) [ 5.136123] [<c0d058c4>] (dump_stack) from [<c0112eb8>] (handle_IPI+0x358/0x3a0) [ 5.143534] r10:ffffe000 r9:c14e9fc4 r8:00000000 r7:00000003 r6:00000004 r5:c1408d64 [ 5.151374] r4:c13bd3e8 r3:f411825b [ 5.154969] [<c0112b60>] (handle_IPI) from [<c057a56c>] (gic_handle_irq+0xb0/0xc4) [ 5.162554] r10:c14653a8 r9:ec11bf20 r8:c1409044 r7:f4000100 r6:000003ff r5:000003eb [ 5.170393] r4:f400010c [ 5.172944] [<c057a4bc>] (gic_handle_irq) from [<c0101a30>] (__irq_svc+0x70/0x98) [ 5.180437] Exception stack(0xec11bf20 to 0xec11bf68) [ 5.185505] bf20: c010a850 00000000 60000093 c011fc40 ffffe000 c1408930 00000008 c1408978 [ 5.193698] bf40: 00000000 00000000 c1408908 ec11bf7c ec11bf40 ec11bf70 c0224380 c010a854 [ 5.201886] bf60: 60000013 ffffffff [ 5.205390] r10:c1408908 r9:ec11a000 r8:00000000 r7:ec11bf54 r6:ffffffff r5:60000013 [ 5.213229] r4:c010a854 [ 5.215785] [<c010a82c>] (arch_cpu_idle) from [<c0d22fa8>] (default_idle_call+0x28/0x38) [ 5.223893] [<c0d22f80>] (default_idle_call) from [<c016ac38>] (do_idle+0x1c0/0x2c8) [ 5.231651] [<c016aa78>] (do_idle) from [<c016b0f4>] (cpu_startup_entry+0x20/0x24) [ 5.239237] r10:00000000 r9:412fc09a r8:1000406a r7:c1507560 r6:10c0387d r5:00000003 [ 5.247075] r4:00000086 [ 5.249626] [<c016b0d4>] (cpu_startup_entry) from [<c01128c8>] (secondary_start_kernel+0x15c/0x1a4) [ 5.258687] [<c011276c>] (secondary_start_kernel) from [<1010278c>] (0x1010278c) [ 5.266094] r5:00000051 r4:3c10406a [ 5.269682] CPU2: stopping [ 5.272412] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G D 4.19.0-rc3+ #314 [ 5.280342] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 5.286878] Backtrace: [ 5.289350] [<c010ebc8>] (dump_backtrace) from [<c010ee98>] (show_stack+0x18/0x1c) [ 5.296933] r7:00000000 r6:60000193 r5:00000000 r4:c14e19ac [ 5.302609] [<c010ee80>] (show_stack) from [<c0d05978>] (dump_stack+0xb4/0xec) [ 5.309849] [<c0d058c4>] (dump_stack) from [<c0112eb8>] (handle_IPI+0x358/0x3a0) [ 5.317261] r10:ffffe000 r9:c14e9fc4 r8:00000000 r7:00000002 r6:00000004 r5:c1408d64 [ 5.325103] r4:c13bd3e8 r3:f411825b [ 5.328698] [<c0112b60>] (handle_IPI) from [<c057a56c>] (gic_handle_irq+0xb0/0xc4) [ 5.336284] r10:c14653a8 r9:ec119f20 r8:c1409044 r7:f4000100 r6:000003ff r5:000003eb [ 5.344123] r4:f400010c [ 5.346675] [<c057a4bc>] (gic_handle_irq) from [<c0101a30>] (__irq_svc+0x70/0x98) [ 5.354169] Exception stack(0xec119f20 to 0xec119f68) [ 5.359237] 9f20: c010a850 00000000 60000093 c011fc40 ffffe000 c1408930 00000004 c1408978 [ 5.367430] 9f40: 00000000 00000000 c1408908 ec119f7c ec119f40 ec119f70 c0224380 c010a854 [ 5.375618] 9f60: 60000013 ffffffff [ 5.379123] r10:c1408908 r9:ec118000 r8:00000000 r7:ec119f54 r6:ffffffff r5:60000013 [ 5.386962] r4:c010a854 [ 5.389517] [<c010a82c>] (arch_cpu_idle) from [<c0d22fa8>] (default_idle_call+0x28/0x38) [ 5.397626] [<c0d22f80>] (default_idle_call) from [<c016ac38>] (do_idle+0x1c0/0x2c8) [ 5.405385] [<c016aa78>] (do_idle) from [<c016b0f4>] (cpu_startup_entry+0x20/0x24) [ 5.412970] r10:00000000 r9:412fc09a r8:1000406a r7:c1507560 r6:10c0387d r5:00000002 [ 5.420809] r4:00000086 [ 5.423360] [<c016b0d4>] (cpu_startup_entry) from [<c01128c8>] (secondary_start_kernel+0x15c/0x1a4) [ 5.432421] [<c011276c>] (secondary_start_kernel) from [<1010278c>] (0x1010278c) [ 5.439827] r5:00000051 r4:3c10406a [ 5.443435] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 5.443435] ]---
The Apalis iMX6 device tree I work with uses a dumb VGA bridge and a LVDS display directly specified in the ldb node. In the case above I did not compile in the dumb VGA bridge driver, that is the reason why binding parallel-display-controller0 fails.
The LVDS encoder (0xec1a0388 in that case) is somehow already cleaned up when calling drm_mode_config_cleanup(), which leads to a null pointer deference when trying to call destroy.
I was unable to figure out why the DRM encoder in the second drm_mode_config_cleanup() call is already zeroed out. The component framework calls imx_ldb_unbind() first, but that should not free up the encoder afaict. Any idea?
I was also wondering in the deferred probing case, functions like imx_ldb_bind() call devm_kzalloc on every try. Since the underlying device is not removed, doesn't this leads to multiple active allocations?
-- Stefan
On 12.09.2018 15:26, Stefan Agner wrote:
FWIW, I also get a warning when enabling list debugging:
[ 3.938454] drm_mode_config_cleanup, encoder TMDS-44, ec549814 ->funcs c0e63a18 [ 3.946064] drm_mode_config_cleanup, calling encoder->funcs->destroy! [ 3.952764] ------------[ cut here ]------------ [ 3.957433] WARNING: CPU: 0 PID: 1 at lib/list_debug.c:56 __list_del_entry_valid+0xc0/0xdc [ 3.965823] list_del corruption. next->prev should be ec549818, but was 00000000 ...
Not sure, but is this expected when using list_for_each_entry_safe?
-- Stefan
Hi Stefan,
thank you for the report. I think what happens is the following:
On Wed, 2018-09-12 at 15:26 -0700, Stefan Agner wrote:
[...]
component_bind calls devres_open_group right before component->ops->bind
The devmem_kzalloc'ed imx_ldb_channel that contains the encoder is allocated in this devres group.
[ 3.799818] drm_encoder_init, encoder ec0da388 [ 3.804363] drm_encoder_init, ret 0
drm_encoder_init adds the encoder in imx_ldb to the mode_config.encoder_list.
component_unbind calls devres_release_group after component->ops-
unbind, freeing imx_ldb and with it the encoder that is still in the
mode_config.encoder_list
Use after free.
[ 3.939356] drm_mode_config_cleanup, calling encoder->funcs->destroy! [ 3.946050] Unable to handle kernel NULL pointer dereference at virtual address 00000004
[...]
I suppose this means that component drivers must not allocate the encoder in the component devres group during bind. Not only their own failure, but any other component's failure can cause component_unbind to be called in the cleanup path of component_bind_all, freeing the memory before drm_mode_config_cleanup is called.
See above. To me it looks like we have to allocate imx_ldb in probe and deal with possibly partially preinitialzied structure when bind is called a second time.
regards Philipp
Hi Philipp,
On 13.09.2018 01:36, Philipp Zabel wrote:
Hi Stefan,
thank you for the report. I think what happens is the following:
Thanks for looking into it!
Oh I see, I did not realize that component_unbind releases devres...
That all makes sense now...
Indeed, moving allocation into driver bind fixes the crash!
I wonder, how does devres knows that imx_ldb got allocated in probe and does not free on unbind? I guess that is the group mechanism which makes sure of that?
ldb would not the only driver affected, also drivers/gpu/drm/imx/parallel-display.c allocates encoders in component bind, there are probably more.
Actually, when thinking more about it, if we would have a way to call framework cleanup functions (drm_mode_config_cleanup() in this case) between the bind and unbind loops in component_bind_all(), we would not have that problem.
[adding Russel, since he introduced the component infrastructure]
Yeah with the fact that component framework does free devres at unbind time, my concern stated here is null...
-- Stefan
Fix the issue: "drm/imx: Crash in drm_mode_config_cleanup".
Which was documented here:
https://www.spinics.net/lists/dri-devel/msg189388.html
And tried to address with this:
https://patchwork.kernel.org/patch/10633297/ https://patchwork.kernel.org/patch/10633299/
This series fixes the possible case of use after free by adding action functions to the devres cleanup path. So it will ensure the generic cleanup code will not use the already freed memory.
Michael Grzeschik (3): ipuv3-crtc: add remove action for devres data ipuv3-ldb: add init list head on bind ipuv3-ldb: add remove action for devres data
drivers/gpu/drm/imx/imx-ldb.c | 35 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/imx/ipuv3-crtc.c | 12 +++++++++++ 2 files changed, 47 insertions(+)
The destroy function in drm_mode_config_cleanup will remove the objects in ipu-drm-core by calling its destroy functions if the bind function fails. The drm_crtc is also part of the devres allocated ipu_crtc object. The ipu_crtc object will already be cleaned up if the bind for the crtc fails. This leads drm_crtc_cleanup try to clean already freed memory.
We fix this issue by adding the devres action ipu_crtc_remove_head which will remove its head from the objects in ipu-drm-core which then never calls its destroy function anymore.
Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de --- drivers/gpu/drm/imx/ipuv3-crtc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index ec3602ebbc1cd..fa1ee33a43d77 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -429,6 +429,14 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, return ret; }
+static void ipu_crtc_remove_head(void *data) +{ + struct ipu_crtc *ipu_crtc = data; + struct drm_crtc *crtc = &ipu_crtc->base; + + list_del(&crtc->head); +} + static int ipu_drm_bind(struct device *dev, struct device *master, void *data) { struct ipu_client_platformdata *pdata = dev->platform_data; @@ -440,6 +448,10 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data) if (!ipu_crtc) return -ENOMEM;
+ ret = devm_add_action(dev, ipu_crtc_remove_head, ipu_crtc); + if (ret) + return ret; + ipu_crtc->dev = dev;
ret = ipu_crtc_init(ipu_crtc, pdata, drm);
Hi Michael,
On Tue, 2019-04-02 at 15:49 +0200, Michael Grzeschik wrote:
I don't think reaching into drm_crtc internals like this is going to be robust. Currently, this is either missing the rest of drm_crtc_cleanup, or it will crash if drm_crtc_init_with_planes hasn't been called yet.
I think you could call devm_add_action with a function that calls drm_crtc_cleanup after drm_crtc_init_with_planes in ipu_crtc_init.
Alternatively, the ipu_crtc allocation could be changed to kzalloc. It would then have to freed manually in the drm_crtc_funcs->destroy callback.
regards Philipp
On Tue, Apr 02, 2019 at 05:49:23PM +0200, Philipp Zabel wrote:
Dirty secret of devm: You can't use it for any drm_ structure, because the lifetimes of those do not match the lifetimes of the underlying device. We'd need to tie the lifetimes of drm objects to drm_device. Noralf has some patches to move that forward. We'd need something like drm_dev_kzalloc which releases memory when drm_device is freed.
Agreed that digging even deeper into the devm deadend is not a good idea. -Daniel
The list head is not initialised after imx_ldb_bind allocates the imx_ldb object. Ensure it will be valid before anyone uses it.
Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de --- drivers/gpu/drm/imx/imx-ldb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 3837333022804..a11f8758da70e 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -581,6 +581,20 @@ static int imx_ldb_panel_ddc(struct device *dev, return 0; }
+static void ipu_ldb_init_encoder_head(struct imx_ldb *imx_ldb) +{ + struct imx_ldb_channel *imx_ldb_ch; + struct drm_encoder *encoder; + + imx_ldb_ch = &imx_ldb->channel[0]; + encoder = &imx_ldb_ch->encoder; + INIT_LIST_HEAD(&encoder->head); + + imx_ldb_ch = &imx_ldb->channel[1]; + encoder = &imx_ldb_ch->encoder; + INIT_LIST_HEAD(&encoder->head); +} + static int imx_ldb_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; @@ -597,6 +611,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) if (!imx_ldb) return -ENOMEM;
+ ipu_ldb_init_encoder_head(imx_ldb); + imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { dev_err(dev, "failed to get parent regmap\n");
The destroy function in drm_mode_config_cleanup will remove the objects in ipu-drm-core by calling its destroy functions if the bind function fails. The drm_encoder is also part of the devres allocated ipu_ldb object. The ipu_ldb object will already be cleaned up if the bind for the crtc fails. This leads drm_encoder_cleanup try to clean already freed memory.
We fix this issue by adding the devres action ipu_ldb_remove_head which will remove its head from the objects in ipu-drm-core which then never calls its destroy function anymore.
Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de --- drivers/gpu/drm/imx/imx-ldb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index a11f8758da70e..0a224036cc68d 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -581,6 +581,21 @@ static int imx_ldb_panel_ddc(struct device *dev, return 0; }
+static void ipu_ldb_remove_head(void *data) +{ + struct imx_ldb *imx_ldb = data; + struct imx_ldb_channel *imx_ldb_ch; + struct drm_encoder *encoder; + + imx_ldb_ch = &imx_ldb->channel[0]; + encoder = &imx_ldb_ch->encoder; + list_del_init(&encoder->head); + + imx_ldb_ch = &imx_ldb->channel[1]; + encoder = &imx_ldb_ch->encoder; + list_del_init(&encoder->head); +} + static void ipu_ldb_init_encoder_head(struct imx_ldb *imx_ldb) { struct imx_ldb_channel *imx_ldb_ch; @@ -613,6 +628,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
ipu_ldb_init_encoder_head(imx_ldb);
+ ret = devm_add_action(dev, ipu_ldb_remove_head, imx_ldb); + if (ret) + return ret; + imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { dev_err(dev, "failed to get parent regmap\n");
dri-devel@lists.freedesktop.org