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