linux/drivers/gpu/drm
Lyude Paul fe2a196529 drm/amdgpu: Count disabled CRTCs in commit tail earlier
This fixes a regression I accidentally reduced that was picked up by
kasan, where we were checking the CRTC atomic states after DRM's helpers
had already freed them. Example:

==================================================================
BUG: KASAN: use-after-free in amdgpu_dm_atomic_commit_tail.cold.50+0x13d/0x15a [amdgpu]
Read of size 1 at addr ffff8803a697b071 by task kworker/u16:0/7

CPU: 7 PID: 7 Comm: kworker/u16:0 Tainted: G           O      4.18.0-rc1Lyude-Upstream+ #1
Hardware name: HP HP ZBook 15 G4/8275, BIOS P70 Ver. 01.21 05/02/2018
Workqueue: events_unbound commit_work [drm_kms_helper]
Call Trace:
 dump_stack+0xc1/0x169
 ? dump_stack_print_info.cold.1+0x42/0x42
 ? kmsg_dump_rewind_nolock+0xd9/0xd9
 ? printk+0x9f/0xc5
 ? amdgpu_dm_atomic_commit_tail.cold.50+0x13d/0x15a [amdgpu]
 print_address_description+0x6c/0x23c
 ? amdgpu_dm_atomic_commit_tail.cold.50+0x13d/0x15a [amdgpu]
 kasan_report.cold.6+0x241/0x2fd
 amdgpu_dm_atomic_commit_tail.cold.50+0x13d/0x15a [amdgpu]
 ? commit_planes_to_stream.constprop.45+0x13b0/0x13b0 [amdgpu]
 ? cpu_load_update_active+0x290/0x290
 ? finish_task_switch+0x2bd/0x840
 ? __switch_to_asm+0x34/0x70
 ? read_word_at_a_time+0xe/0x20
 ? strscpy+0x14b/0x460
 ? drm_atomic_helper_wait_for_dependencies+0x47d/0x7e0 [drm_kms_helper]
 commit_tail+0x96/0xe0 [drm_kms_helper]
 process_one_work+0x88a/0x1360
 ? create_worker+0x540/0x540
 ? __sched_text_start+0x8/0x8
 ? move_queued_task+0x760/0x760
 ? call_rcu_sched+0x20/0x20
 ? vsnprintf+0xcda/0x1350
 ? wait_woken+0x1c0/0x1c0
 ? mutex_unlock+0x1d/0x40
 ? init_timer_key+0x190/0x230
 ? schedule+0xea/0x390
 ? __schedule+0x1ea0/0x1ea0
 ? need_to_create_worker+0xe4/0x210
 ? init_worker_pool+0x700/0x700
 ? try_to_del_timer_sync+0xbf/0x110
 ? del_timer+0x120/0x120
 ? __mutex_lock_slowpath+0x10/0x10
 worker_thread+0x196/0x11f0
 ? flush_rcu_work+0x50/0x50
 ? __switch_to_asm+0x34/0x70
 ? __switch_to_asm+0x34/0x70
 ? __switch_to_asm+0x40/0x70
 ? __switch_to_asm+0x34/0x70
 ? __switch_to_asm+0x40/0x70
 ? __switch_to_asm+0x34/0x70
 ? __switch_to_asm+0x40/0x70
 ? __schedule+0x7d6/0x1ea0
 ? migrate_swap_stop+0x850/0x880
 ? __sched_text_start+0x8/0x8
 ? save_stack+0x8c/0xb0
 ? kasan_kmalloc+0xbf/0xe0
 ? kmem_cache_alloc_trace+0xe4/0x190
 ? kthread+0x98/0x390
 ? ret_from_fork+0x35/0x40
 ? ret_from_fork+0x35/0x40
 ? deactivate_slab.isra.67+0x3c4/0x5c0
 ? kthread+0x98/0x390
 ? kthread+0x98/0x390
 ? set_track+0x76/0x120
 ? schedule+0xea/0x390
 ? __schedule+0x1ea0/0x1ea0
 ? wait_woken+0x1c0/0x1c0
 ? kasan_unpoison_shadow+0x30/0x40
 ? parse_args.cold.15+0x17a/0x17a
 ? flush_rcu_work+0x50/0x50
 kthread+0x2d4/0x390
 ? kthread_create_worker_on_cpu+0xc0/0xc0
 ret_from_fork+0x35/0x40

Allocated by task 1124:
 kasan_kmalloc+0xbf/0xe0
 kmem_cache_alloc_trace+0xe4/0x190
 dm_crtc_duplicate_state+0x78/0x130 [amdgpu]
 drm_atomic_get_crtc_state+0x147/0x410 [drm]
 page_flip_common+0x57/0x230 [drm_kms_helper]
 drm_atomic_helper_page_flip+0xa6/0x110 [drm_kms_helper]
 drm_mode_page_flip_ioctl+0xc4b/0x10a0 [drm]
 drm_ioctl_kernel+0x1d4/0x260 [drm]
 drm_ioctl+0x433/0x920 [drm]
 amdgpu_drm_ioctl+0x11d/0x290 [amdgpu]
 do_vfs_ioctl+0x1a1/0x13d0
 ksys_ioctl+0x60/0x90
 __x64_sys_ioctl+0x6f/0xb0
 do_syscall_64+0x147/0x440
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

Freed by task 1124:
 __kasan_slab_free+0x12e/0x180
 kfree+0x92/0x1a0
 drm_atomic_state_default_clear+0x315/0xc40 [drm]
 __drm_atomic_state_free+0x35/0xd0 [drm]
 drm_atomic_helper_update_plane+0xac/0x350 [drm_kms_helper]
 __setplane_internal+0x2d6/0x840 [drm]
 drm_mode_cursor_universal+0x41e/0xbe0 [drm]
 drm_mode_cursor_common+0x49f/0x880 [drm]
 drm_mode_cursor_ioctl+0xd8/0x130 [drm]
 drm_ioctl_kernel+0x1d4/0x260 [drm]
 drm_ioctl+0x433/0x920 [drm]
 amdgpu_drm_ioctl+0x11d/0x290 [amdgpu]
 do_vfs_ioctl+0x1a1/0x13d0
 ksys_ioctl+0x60/0x90
 __x64_sys_ioctl+0x6f/0xb0
 do_syscall_64+0x147/0x440
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

The buggy address belongs to the object at ffff8803a697b068
 which belongs to the cache kmalloc-1024 of size 1024
The buggy address is located 9 bytes inside of
 1024-byte region [ffff8803a697b068, ffff8803a697b468)
The buggy address belongs to the page:
page:ffffea000e9a5e00 count:1 mapcount:0 mapping:ffff88041e00efc0 index:0x0 compound_mapcount: 0
flags: 0x8000000000008100(slab|head)
raw: 8000000000008100 ffffea000ecbc208 ffff88041e000c70 ffff88041e00efc0
raw: 0000000000000000 0000000000170017 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff8803a697af00: fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff8803a697af80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff8803a697b000: fc fc fc fc fc fc fc fc fc fc fc fc fc fb fb fb
                                                             ^
 ffff8803a697b080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff8803a697b100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

So, we fix this by counting the number of CRTCs this atomic commit disabled
early on in the function before their atomic states have been freed, then use
that count later to do the appropriate number of RPM puts at the end of the
function.

Acked-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Cc: stable@vger.kernel.org
Fixes: 97028037a3 ("drm/amdgpu: Grab/put runtime PM references in atomic_commit_tail()")
Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Michel Dänzer <michel@daenzer.net>
Reported-by: Michel Dänzer <michel@daenzer.net>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2018-06-22 14:55:25 -05:00
..
amd drm/amdgpu: Count disabled CRTCs in commit tail earlier 2018-06-22 14:55:25 -05:00
arc drm/arcpgu: remove drm_encoder_slave 2018-01-30 18:05:25 +01:00
arm drm: mali-dp: Add YUV->RGB conversion support for video layers 2018-03-14 11:41:01 +00:00
armada drm: Don't pass clip to drm_atomic_helper_check_plane_state() 2018-03-05 20:48:25 +02:00
ast drm/ast: fix mode_valid's return type 2018-04-25 09:09:22 +02:00
atmel-hlcdc Fixes for v4.18-rc2: 2018-06-22 11:03:43 +10:00
bochs drm/bochs: fix mode_valid's return type 2018-04-25 09:34:00 +02:00
bridge Fixes for v4.18-rc2: 2018-06-22 11:03:43 +10:00
cirrus Linux 4.16-rc7 2018-03-28 14:30:41 +10:00
etnaviv Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next 2018-05-22 10:43:27 +10:00
exynos treewide: devm_kzalloc() -> devm_kcalloc() 2018-06-12 16:19:22 -07:00
fsl-dcu
gma500 treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
hisilicon drm/hisilicon: fix mode_valid's return type 2018-04-25 09:09:22 +02:00
i2c Merge branch 'drm-tda998x-devel' of git://git.armlinux.org.uk/~rmk/linux-arm into drm-next 2018-05-22 10:20:45 +10:00
i810
i915 drm/i915: Enable provoking vertex fix on Gen9 systems. 2018-06-19 15:48:24 +03:00
imx Linux 4.16-rc7 2018-03-28 14:30:41 +10:00
lib
mediatek drm/mediatek: Using the function drm_display_mode_to_videomode 2018-05-02 14:20:47 +08:00
meson drm/bridge/synopsys: dw-hdmi: fix dw_hdmi_setup_rx_sense 2018-05-30 13:42:39 -04:00
mga
mgag200 drm/mgag200: fix mode_valid's return type 2018-04-25 09:09:22 +02:00
msm treewide: devm_kzalloc() -> devm_kcalloc() 2018-06-12 16:19:22 -07:00
mxsfb drm/mxsfb: Use simple_display_pipe prepare_fb helper 2018-04-24 13:58:43 +02:00
nouveau Merge branch 'linux-4.18' of git://github.com/skeggsb/linux into drm-fixes 2018-06-20 16:57:09 +10:00
omapdrm treewide: kzalloc() -> kcalloc() 2018-06-12 16:19:22 -07:00
panel drm/panel: Enable DSI transactions on the RPi panel. 2018-04-30 13:57:13 -07:00
pl111 drm/pl111: Fix module probe bug 2018-05-04 00:13:41 +02:00
qxl Only a small qxl fix that was queued for v4.17. 2018-06-20 16:58:49 +10:00
r128 r128: don't open-code memdup_user() 2017-12-27 19:00:09 -05:00
radeon treewide: Use array_size() in vzalloc() 2018-06-12 16:19:22 -07:00
rcar-du DeviceTree updates for v4.18: 2018-06-07 14:06:31 -07:00
rockchip drm/rockchip: Disable blending for win0 2018-05-01 15:56:21 -04:00
savage treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
scheduler drm/scheduler: fix a corner case in dependency optimization 2018-05-25 11:02:14 -05:00
selftests treewide: Use array_size() in vzalloc() 2018-06-12 16:19:22 -07:00
shmobile drm: shmobile: remove unused MERAM support 2018-05-14 15:47:30 +02:00
sis
sti gpu: drm: sti: fix spelling mistake: "initialze" -> "initialize" 2018-05-02 13:09:49 +02:00
stm drm/stm: ltdc: fix warnings in ltdc_plane_create() 2018-04-27 11:02:58 +02:00
sun4i Fixes for v4.18-rc2: 2018-06-22 11:03:43 +10:00
tdfx
tegra drm/tegra: Changes for v4.18-rc1 2018-05-22 10:45:43 +10:00
tilcdc drm/tilcdc: Fix setting clock divider for omap-l138 2018-05-09 19:55:18 +03:00
tinydrm treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
ttm treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
tve200 drm/tve200: Use simple_display_pipe prepare_fb helper 2018-04-24 13:58:06 +02:00
udl drm/udl: fix mode_valid's return type 2018-04-25 09:09:22 +02:00
v3d drm-misc-next-fixes for v4.18: 2018-06-08 15:52:54 +10:00
vc4 treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
vgem
via treewide: Use array_size() in vzalloc() 2018-06-12 16:19:22 -07:00
virtio drm-misc-next for v4.18: 2018-04-30 09:32:43 +10:00
vmwgfx drm for v4.18-rc1 2018-06-06 08:16:33 -07:00
xen drm for v4.18-rc1 2018-06-06 08:16:33 -07:00
zte drm/zte: Stop consulting plane->crtc 2018-03-29 19:14:21 +03:00
ati_pcigart.c
drm_agpsupport.c
drm_atomic_helper.c drm/rect: Handle rounding errors in drm_rect_clip_scaled, v3. 2018-05-04 11:09:54 +02:00
drm_atomic.c urgent i686 mmap fix for drm drivers 2018-05-18 14:08:53 +10:00
drm_auth.c drm: Check for lessee in DROP_MASTER ioctl 2018-01-31 09:27:51 +01:00
drm_blend.c drm/blend: Add a generic alpha property 2018-04-16 21:17:29 +02:00
drm_bridge.c
drm_bufs.c drm: dma_bufs: Fixed checkpatch issues 2018-03-19 09:31:20 -04:00
drm_cache.c
drm_color_mgmt.c kernel.h: Retain constant expression output for max()/min() 2018-04-05 14:17:16 -07:00
drm_connector.c drm: Expose modes with aspect ratio, only if requested 2018-05-11 09:06:39 +02:00
drm_context.c
drm_crtc_helper_internal.h
drm_crtc_helper.c
drm_crtc_internal.h drm: Don't EXPORT drm_add/reset_display_info 2018-04-24 21:34:53 +02:00
drm_crtc.c drm: Handle aspect ratio info in legacy modeset path 2018-05-11 09:05:18 +02:00
drm_debugfs_crc.c drm/crc: Add support for polling on the data fd. 2018-02-05 13:22:44 +01:00
drm_debugfs.c
drm_dma.c
drm_dp_aux_dev.c sched/wait, drivers/drm: Convert wait_on_atomic_t() usage to the new wait_var_event() API 2018-03-20 08:23:18 +01:00
drm_dp_dual_mode_helper.c drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state 2018-04-18 16:33:14 +03:00
drm_dp_helper.c drm for v4.18-rc1 2018-06-06 08:16:33 -07:00
drm_dp_mst_topology.c drm/dp/mst: Fix off-by-one typo when dump payload table 2018-03-28 09:12:16 +03:00
drm_drv.c Single fix for v4.18: 2018-06-20 16:58:31 +10:00
drm_dumb_buffers.c drm/dumb-buffers: Integer overflow in drm_mode_create_ioctl() 2018-05-16 17:56:06 +02:00
drm_edid_load.c
drm_edid.c treewide: kmalloc() -> kmalloc_array() 2018-06-12 16:19:22 -07:00
drm_encoder_slave.c
drm_encoder.c drm: Warn if plane/crtc/encoder/connector index exceeds our 32bit bitmasks 2018-01-29 18:46:53 +02:00
drm_fb_cma_helper.c
drm_fb_helper.c drm: Add aspect ratio parsing in DRM layer 2018-05-11 09:23:41 +02:00
drm_file.c drm: set FMODE_UNSIGNED_OFFSET for drm files 2018-05-15 14:46:04 +10:00
drm_flip_work.c
drm_fourcc.c drm/fourcc: Add a alpha field to drm_format_info 2018-01-29 12:07:47 +01:00
drm_framebuffer.c drm: remove all control node code 2018-05-03 21:26:32 +02:00
drm_gem_cma_helper.c
drm_gem_framebuffer_helper.c drm: Move simple_display_pipe prepare_fb helper into gem fb helpers 2018-04-24 13:57:22 +02:00
drm_gem.c drm/gem: Document that handle_create must be the last step 2018-03-26 17:42:06 +02:00
drm_global.c
drm_hashtab.c treewide: Use array_size() in vzalloc() 2018-06-12 16:19:22 -07:00
drm_info.c
drm_internal.h
drm_ioc32.c drm: Drop DRM_CONTROL_ALLOW from ioctls 2018-05-03 11:28:02 +02:00
drm_ioctl.c drm: Add DRM client cap for aspect-ratio 2018-05-11 09:05:03 +02:00
drm_irq.c
drm_kms_helper_common.c
drm_lease.c gpu: drm/lease:: Use list_{next/prev}_entry instead of list_entry 2018-03-26 10:38:06 +02:00
drm_legacy.h
drm_lock.c
drm_memory.c treewide: Use array_size() in vmalloc() 2018-06-12 16:19:22 -07:00
drm_mipi_dsi.c drm/dsi: Fix improper use of mipi_dsi_device_transfer() return value 2018-01-16 17:10:14 -05:00
drm_mm.c Linux 4.16-rc7 2018-03-28 14:30:41 +10:00
drm_mode_config.c Linux 4.15-rc4 2017-12-19 21:37:24 +10:00
drm_mode_object.c
drm_modes.c drm: Add and handle new aspect ratios in DRM layer 2018-05-11 09:23:55 +02:00
drm_modeset_helper.c
drm_modeset_lock.c drm/atomic: Call ww_acquire_done after drm_modeset_lock_all 2018-03-05 10:35:32 +01:00
drm_of.c drm: of: simplify component probe code 2018-03-06 14:05:00 +05:30
drm_panel_orientation_quirks.c drm: panel-orientation-quirks: Convert to use match_string() helper 2018-05-10 11:36:25 -04:00
drm_panel.c
drm_pci.c
drm_plane_helper.c drm: Don't pass clip to drm_atomic_helper_check_plane_state() 2018-03-05 20:48:25 +02:00
drm_plane.c drm: Use plane->state->fb over plane->fb 2018-03-29 19:14:21 +03:00
drm_prime.c drm: Make the prime vmap/vunmap hooks optional. 2018-04-30 10:42:03 -07:00
drm_print.c drm: Reduce object size of DRM_DEV_<LEVEL> uses 2018-03-19 15:15:42 +01:00
drm_probe_helper.c Linux 4.16-rc7 2018-03-28 14:30:41 +10:00
drm_property.c drm: Don't pass the index to drm_property_add_enum() 2018-04-27 16:46:50 +03:00
drm_rect.c drm/rect: Handle rounding errors in drm_rect_clip_scaled, v3. 2018-05-04 11:09:54 +02:00
drm_scatter.c
drm_scdc_helper.c drm/scdc-helper: Convert errors into debug messages 2018-03-26 21:37:24 +03:00
drm_simple_kms_helper.c drm/simple-kms-helper: Plumb plane state to the enable hook 2018-03-28 19:19:32 +03:00
drm_syncobj.c Revert 190c462d5be19ba622a82f5fd0625087c870a1e6..bf3012ada1b2222e770de5c35c1bb16f73b3a01d" 2018-05-03 12:38:39 +02:00
drm_sysfs.c drm: remove all control node code 2018-05-03 21:26:32 +02:00
drm_trace_points.c
drm_trace.h
drm_vblank.c Merge tag 'drm-intel-next-2018-03-08' of git://anongit.freedesktop.org/drm/drm-intel into drm-next 2018-03-14 14:53:01 +10:00
drm_vm.c
drm_vma_manager.c
Kconfig drm/selftests: Add drm helper selftest 2018-05-04 11:36:45 +02:00
Makefile drm/selftests: Rename the Kconfig option to CONFIG_DRM_DEBUG_SELFTEST 2018-05-04 11:36:34 +02:00