Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/repaper: Do not access GEM-DMA vaddr directly

Use DRM's shadow-plane helper to map and access the GEM object's buffer
within kernel address space. Encapsulates the vmap logic in the GEM-DMA
helpers.

The repaper driver currently reads the vaddr field from the GME buffer
object directly. This only works because GEM code 'automagically' sets
vaddr.

Shadow-plane helpers perform the same steps, but with correct abstraction
behind drm_gem_vmap(). The shadow-plane state provides the buffer address
in kernel address space and the format-conversion state.

v2:
- fix typo in commit description

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250627152422.8399-1-tzimmermann@suse.de

+7 -9
+7 -9
drivers/gpu/drm/tiny/repaper.c
··· 510 510 epd->factored_stage_time = epd->stage_time * factor10x / 10; 511 511 } 512 512 513 - static int repaper_fb_dirty(struct drm_framebuffer *fb, 513 + static int repaper_fb_dirty(struct drm_framebuffer *fb, const struct iosys_map *vmap, 514 514 struct drm_format_conv_state *fmtcnv_state) 515 515 { 516 - struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0); 517 516 struct repaper_epd *epd = drm_to_epd(fb->dev); 518 517 unsigned int dst_pitch = 0; 519 - struct iosys_map dst, vmap; 518 + struct iosys_map dst; 520 519 struct drm_rect clip; 521 520 int idx, ret = 0; 522 521 u8 *buf = NULL; ··· 545 546 goto out_free; 546 547 547 548 iosys_map_set_vaddr(&dst, buf); 548 - iosys_map_set_vaddr(&vmap, dma_obj->vaddr); 549 - drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, &vmap, fb, &clip, fmtcnv_state); 549 + drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, &clip, fmtcnv_state); 550 550 551 551 drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); 552 552 ··· 830 832 struct drm_plane_state *old_state) 831 833 { 832 834 struct drm_plane_state *state = pipe->plane.state; 833 - struct drm_format_conv_state fmtcnv_state = DRM_FORMAT_CONV_STATE_INIT; 835 + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); 834 836 struct drm_rect rect; 835 837 836 838 if (!pipe->crtc.state->active) 837 839 return; 838 840 839 841 if (drm_atomic_helper_damage_merged(old_state, state, &rect)) 840 - repaper_fb_dirty(state->fb, &fmtcnv_state); 841 - 842 - drm_format_conv_state_release(&fmtcnv_state); 842 + repaper_fb_dirty(state->fb, shadow_plane_state->data, 843 + &shadow_plane_state->fmtcnv_state); 843 844 } 844 845 845 846 static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = { ··· 846 849 .enable = repaper_pipe_enable, 847 850 .disable = repaper_pipe_disable, 848 851 .update = repaper_pipe_update, 852 + DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, 849 853 }; 850 854 851 855 static int repaper_connector_get_modes(struct drm_connector *connector)