ast driver doesn't initialize smem_len
Murilo Fossa Vicentini
muvic at linux.vnet.ibm.com
Wed Oct 21 10:39:30 PDT 2015
Hi all,
In a recent test performed with fbterm and an adapter that uses the ast
driver, fbterm is currently segfaulting in the mainline kernel.
The crash happens when the code attempts to do a write to the frame
buffer, which is an mmap'ed region. The size of the mmap is determined
by the smem_len, which is retrieved by an FBIOGET_FSCREENINFO ioctl. It
gets the following in return:
id: astdrmfb
smem_start: 0 (0x0)
smem_len: 0 (0x0)
type: 0 (0x0)
type_aux: 0 (0x0)
visual: 2 (0x2)
xpanstep: 1 (0x1)
ypanstep: 1 (0x1)
line_length: 4096 (0x1000)
mmio_start: 0 0x0
mmio_len: 0 (0x0)
accel: 0 (0x0)
capabilities: 0 (0x0)
So the mmap is performed on a size of smem_len (0). By looking at the
ast driver code smem_len is never set.
When doing some research on the issue I stumbled upon the following
patch in the SLES kernel:
From: Egbert Eich <eich at suse.de>
Date: Wed Jun 11 14:59:55 2014 +0200
Subject: drm/ast: Initialized data needed to map fbdev memory
Patch-mainline: to be upstreamed
References: bnc#880007
Signed-off-by: Egbert Eich <eich at suse.com>
Due to a missing initialization there was no way to map fbdev memory.
Thus for example using the Xserver with the fbdev driver failed.
This fix adds initialization for fix.smem_start and fix.smem_len
in the fb_info structure, which fixes this problem.
Signed-off-by: Egbert Eich <eich at suse.de>
---
drivers/gpu/drm/ast/ast_drv.h | 1 +
drivers/gpu/drm/ast/ast_fb.c | 7 +++++++
drivers/gpu/drm/ast/ast_main.c | 1 +
drivers/gpu/drm/ast/ast_mode.c | 2 ++
4 files changed, 11 insertions(+)
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/ast/ast_fb.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/ast/ast_fb.c
@@ -346,3 +346,10 @@ void ast_fbdev_set_suspend(struct drm_de
fb_set_suspend(ast->fbdev->helper.fbdev, state);
}
+
+void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr)
+{
+ ast->fbdev->helper.fbdev->fix.smem_start =
+ ast->fbdev->helper.fbdev->apertures->ranges[0].base + gpu_addr;
+ ast->fbdev->helper.fbdev->fix.smem_len = ast->vram_size - gpu_addr;
+}
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/ast/ast_drv.h
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/ast/ast_drv.h
@@ -292,6 +292,7 @@ int ast_framebuffer_init(struct drm_devi
int ast_fbdev_init(struct drm_device *dev);
void ast_fbdev_fini(struct drm_device *dev);
void ast_fbdev_set_suspend(struct drm_device *dev, int state);
+void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr);
struct ast_bo {
struct ttm_buffer_object bo;
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/ast/ast_main.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/ast/ast_main.c
@@ -367,6 +367,7 @@ int ast_driver_load(struct drm_device *d
dev->mode_config.min_height = 0;
dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1;
+ dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);
if (ast->chip == AST2100 ||
ast->chip == AST2200 ||
--- linux-3.0-SLE11-SP3.orig/drivers/gpu/drm/ast/ast_mode.c
+++ linux-3.0-SLE11-SP3/drivers/gpu/drm/ast/ast_mode.c
@@ -509,6 +509,8 @@ static int ast_crtc_do_set_base(struct d
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
if (ret)
DRM_ERROR("failed to kmap fbcon\n");
+ else
+ ast_fbdev_set_base(ast, gpu_addr);
}
ast_bo_unreserve(bo);
---
When applied on top of the mainline kernel it solves the issue and
fbterm is properly initialized. Unfortunately, I didn't found any
evidence of it being submitted upstream. Since this patch is over an
year old, I am wondering if it is still a valid patch or if this issue
should be fixed some other way. I would appreciate any input regarding
the best way to be taken towards a fix for this issue.
Best regards,
Murilo Vicentini
More information about the dri-devel
mailing list