Skip to content

Commit 2a1658b

Browse files
committed
drm/drm_fb_helper: fix fbdev with sparc64
Recent kernels have been reported to panic using the bochs_drm framebuffer under qemu-system-sparc64 which was bisected to commit 7a0483a ("drm/bochs: switch to generic drm fbdev emulation"). The backtrace indicates that the shadow framebuffer copy in drm_fb_helper_dirty_blit_real() is trying to access the real framebuffer using a virtual address rather than use an IO access typically implemented using a physical (ASI_PHYS) access on SPARC. The fix is to replace the memcpy with memcpy_toio() from io.h. memcpy_toio() uses writeb() where the original fbdev code used sbus_memcpy_toio(). The latter uses sbus_writeb(). The difference between writeb() and sbus_memcpy_toio() is that writeb() writes bytes in little-endian, where sbus_writeb() writes bytes in big-endian. As endian does not matter for byte writes they are the same. So we can safely use memcpy_toio() here. Note that this only fixes bochs, in general fbdev helpers still have issues with mixing up system memory and __iomem space. Fixing that will require a lot more work. v3: - Improved changelog (Daniel) - Added FIXME to fbdev_use_iomem (Daniel) v2: - Added missing __iomem cast (kernel test robot) - Made changelog readable and fix typos (Mark) - Add flag to select iomem - and set it in the bochs driver Signed-off-by: Sam Ravnborg <[email protected]> Reported-by: Mark Cave-Ayland <[email protected]> Reported-by: kernel test robot <[email protected]> Tested-by: Mark Cave-Ayland <[email protected]> Reviewed-by: Daniel Vetter <[email protected]> Cc: Mark Cave-Ayland <[email protected]> Cc: Thomas Zimmermann <[email protected]> Cc: Gerd Hoffmann <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: [email protected] Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent aa7bf89 commit 2a1658b

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

drivers/gpu/drm/bochs/bochs_kms.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ int bochs_kms_init(struct bochs_device *bochs)
146146
bochs->dev->mode_config.preferred_depth = 24;
147147
bochs->dev->mode_config.prefer_shadow = 0;
148148
bochs->dev->mode_config.prefer_shadow_fbdev = 1;
149+
bochs->dev->mode_config.fbdev_use_iomem = true;
149150
bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
150151

151152
bochs->dev->mode_config.funcs = &bochs_mode_funcs;

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,11 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
399399
unsigned int y;
400400

401401
for (y = clip->y1; y < clip->y2; y++) {
402-
memcpy(dst, src, len);
402+
if (!fb_helper->dev->mode_config.fbdev_use_iomem)
403+
memcpy(dst, src, len);
404+
else
405+
memcpy_toio((void __iomem *)dst, src, len);
406+
403407
src += fb->pitches[0];
404408
dst += fb->pitches[0];
405409
}

include/drm/drm_mode_config.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,18 @@ struct drm_mode_config {
865865
*/
866866
bool prefer_shadow_fbdev;
867867

868+
/**
869+
* @fbdev_use_iomem:
870+
*
871+
* Set to true if framebuffer reside in iomem.
872+
* When set to true memcpy_toio() is used when copying the framebuffer in
873+
* drm_fb_helper.drm_fb_helper_dirty_blit_real().
874+
*
875+
* FIXME: This should be replaced with a per-mapping is_iomem
876+
* flag (like ttm does), and then used everywhere in fbdev code.
877+
*/
878+
bool fbdev_use_iomem;
879+
868880
/**
869881
* @quirk_addfb_prefer_xbgr_30bpp:
870882
*

0 commit comments

Comments
 (0)