From nobody@FreeBSD.org Sun Jul 20 16:28:55 2008 Return-Path: Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EC85B106567B for ; Sun, 20 Jul 2008 16:28:55 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id DBBD18FC14 for ; Sun, 20 Jul 2008 16:28:55 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m6KGStGl045412 for ; Sun, 20 Jul 2008 16:28:55 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id m6KGStgM045411; Sun, 20 Jul 2008 16:28:55 GMT (envelope-from nobody) Message-Id: <200807201628.m6KGStgM045411@www.freebsd.org> Date: Sun, 20 Jul 2008 16:28:55 GMT From: Andreas Schwarz To: freebsd-gnats-submit@FreeBSD.org Subject: Radeon X800 GTO - *ERROR* Offset failed range check - DRM problem X-Send-Pr-Version: www-3.1 X-GNATS-Notify: >Number: 125808 >Category: kern >Synopsis: [drm] [patch] Radeon X800 GTO - *ERROR* Offset failed range check - DRM problem >Confidential: no >Severity: non-critical >Priority: medium >Responsible: rnoland >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jul 20 16:30:02 UTC 2008 >Closed-Date: Sun Nov 01 17:30:59 UTC 2009 >Last-Modified: Sun Nov 01 17:30:59 UTC 2009 >Originator: Andreas Schwarz >Release: FreeBSD 7.0-STABLE, CURRENT >Organization: >Environment: FreeBSD tapir.schwarzes.net 7.0-STABLE FreeBSD 7.0-STABLE #0: Sun Jul 20 15:36:44 CEST 2008 root@tapir.schwarzes.net:/usr/obj/usr/src/sys/tapir.schwarzes.net i386 >Description: DRI is not working with an ATI Radeon X800 GTO, when starting a application like glxgears "drmRadeonCmdBuffer: -22" is returned. Output of glxinfo looks quite normal and says that direct rendering is enabled. asc@tapir:~ $ glxgears drmRadeonCmdBuffer: -22 In the dmesg output we find : drm0: [ITHREAD] error: [drm:pid881:r300_emit_carefully_checked_packet0] *ERROR* Offset failed range check (reg=4e28 sz=1) error: [drm:pid881:r300_do_cp_cmdbuf] *ERROR* r300_emit_packet0 failed root@tapir:~ # pciconf -lv [...] vgapci0@pci0:2:0:0: class=0x030000 card=0x1600174b chip=0x5d4f1002 rev=0x00 hdr=0x00 vendor = 'ATI Technologies Inc' device = 'r480 x800gto 256 pci-e' class = display subclass = VGA vgapci1@pci0:2:0:1: class=0x038000 card=0x1601174b chip=0x5d6f1002 rev=0x00 hdr=0x00 vendor = 'ATI Technologies Inc' device = 'Radeon X850 Series - Secondary' class = display asc@tapir:~ $ glxinfo name of display: :0.0 display: :0 screen: 0 direct rendering: Yes server glx vendor string: SGI server glx version string: 1.2 server glx extensions: GLX_ARB_multisample, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_OML_swap_method, GLX_SGI_make_current_read, GLX_SGIS_multisample, GLX_SGIX_hyperpipe, GLX_SGIX_swap_barrier, GLX_SGIX_fbconfig, GLX_MESA_copy_sub_buffer client glx vendor string: SGI client glx version string: 1.4 client glx extensions: GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_allocate_memory, GLX_MESA_copy_sub_buffer, GLX_MESA_swap_control, GLX_MESA_swap_frame_usage, GLX_OML_swap_method, GLX_OML_sync_control, GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync, GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group, GLX_EXT_texture_from_pixmap GLX version: 1.2 GLX extensions: GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_copy_sub_buffer, GLX_MESA_swap_control, GLX_MESA_swap_frame_usage, GLX_OML_swap_method, GLX_SGI_make_current_read, GLX_SGI_video_sync, GLX_SGIS_multisample, GLX_SGIX_fbconfig OpenGL vendor string: DRI R300 Project OpenGL renderer string: Mesa DRI R300 20060815 x86/MMX+/3DNow!+/SSE2 TCL OpenGL version string: 1.3 Mesa 7.0.3 OpenGL extensions: GL_ARB_fragment_program, GL_ARB_imaging, GL_ARB_multisample, GL_ARB_multitexture, GL_ARB_texture_border_clamp, GL_ARB_texture_compression, GL_ARB_texture_cube_map, GL_ARB_texture_env_add, GL_ARB_texture_env_combine, GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3, GL_MESAX_texture_float, GL_ARB_texture_mirrored_repeat, GL_ARB_texture_rectangle, GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object, GL_ARB_vertex_program, GL_ARB_window_pos, GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color, GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate, GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_clip_volume_hint, GL_EXT_compiled_vertex_array, GL_EXT_convolution, GL_EXT_copy_texture, GL_EXT_draw_range_elements, GL_EXT_gpu_program_parameters, GL_EXT_histogram, GL_EXT_packed_pixels, GL_EXT_polygon_offset, GL_EXT_rescale_normal, GL_EXT_secondary_color, GL_EXT_separate_specular_color, GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, GL_EXT_subtexture, GL_EXT_texture, GL_EXT_texture3D, GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add, GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3, GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod_bias, GL_EXT_texture_mirror_clamp, GL_EXT_texture_object, GL_EXT_texture_rectangle, GL_EXT_vertex_array, GL_APPLE_packed_pixels, GL_ATI_blend_equation_separate, GL_ATI_texture_env_combine3, GL_ATI_texture_mirror_once, GL_IBM_rasterpos_clip, GL_IBM_texture_mirrored_repeat, GL_INGR_blend_func_separate, GL_MESA_pack_invert, GL_MESA_ycbcr_texture, GL_MESA_window_pos, GL_NV_blend_square, GL_NV_light_max_exponent, GL_NV_texture_rectangle, GL_NV_texgen_reflection, GL_NV_vertex_program, GL_OES_read_format, GL_SGI_color_matrix, GL_SGI_color_table, GL_SGIS_generate_mipmap, GL_SGIS_texture_border_clamp, GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod visual x bf lv rg d st colorbuffer ax dp st accumbuffer ms cav id dep cl sp sz l ci b ro r g b a bf th cl r g b a ns b eat ---------------------------------------------------------------------- 0x23 24 tc 0 32 0 r y . 8 8 8 8 0 24 8 0 0 0 0 0 0 None 0x24 24 tc 0 32 0 r y . 8 8 8 8 0 24 0 0 0 0 0 0 0 None 0x25 24 tc 0 32 0 r y . 8 8 8 8 0 24 8 16 16 16 16 0 0 Slow 0x26 24 tc 0 32 0 r y . 8 8 8 8 0 24 0 16 16 16 16 0 0 Slow 0x27 24 tc 0 32 0 r . . 8 8 8 8 0 24 8 0 0 0 0 0 0 None 0x28 24 tc 0 32 0 r . . 8 8 8 8 0 24 0 0 0 0 0 0 0 None 0x29 24 tc 0 32 0 r . . 8 8 8 8 0 24 8 16 16 16 16 0 0 Slow 0x2a 24 tc 0 32 0 r . . 8 8 8 8 0 24 0 16 16 16 16 0 0 Slow 0x2b 24 dc 0 32 0 r y . 8 8 8 8 0 24 8 0 0 0 0 0 0 None 0x2c 24 dc 0 32 0 r y . 8 8 8 8 0 24 0 0 0 0 0 0 0 None 0x2d 24 dc 0 32 0 r y . 8 8 8 8 0 24 8 16 16 16 16 0 0 Slow 0x2e 24 dc 0 32 0 r y . 8 8 8 8 0 24 0 16 16 16 16 0 0 Slow 0x2f 24 dc 0 32 0 r . . 8 8 8 8 0 24 8 0 0 0 0 0 0 None 0x30 24 dc 0 32 0 r . . 8 8 8 8 0 24 0 0 0 0 0 0 0 None 0x31 24 dc 0 32 0 r . . 8 8 8 8 0 24 8 16 16 16 16 0 0 Slow 0x32 24 dc 0 32 0 r . . 8 8 8 8 0 24 0 16 16 16 16 0 0 Slow 0x74 32 tc 0 32 0 r . . 8 8 8 8 0 0 0 0 0 0 0 0 0 Ncon >How-To-Repeat: Use an ATI RADEON X800 GTO and start an application which is using DRI. >Fix: This is a known bug with the r300_check_offset() function, which was discussed on the linux kernel ml some time ago. Please look at : http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg02975.html Based on this artice I've made a patchfile (attached) for freebsd drm. Usage: cd /usr/src/ patch -p0 < patch-drm_radeon_offset_checking.txt Patch attached with submission follows: diff -Naur sys/dev/drm.old/r300_cmdbuf.c sys/dev/drm/r300_cmdbuf.c --- sys/dev/drm.old/r300_cmdbuf.c 2006-05-17 08:36:28.000000000 +0200 +++ sys/dev/drm/r300_cmdbuf.c 2008-07-20 03:35:35.000000000 +0200 @@ -245,26 +245,6 @@ return 0; } -/* - * we expect offsets passed to the framebuffer to be either within video - * memory or within AGP space - */ -static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, - u32 offset) -{ - /* we realy want to check against end of video aperture - but this value is not being kept. - This code is correct for now (does the same thing as the - code that sets MC_FB_LOCATION) in radeon_cp.c */ - if (offset >= dev_priv->fb_location && - offset < (dev_priv->fb_location + dev_priv->fb_size)) - return 0; - if (offset >= dev_priv->gart_vm_start && - offset < (dev_priv->gart_vm_start + dev_priv->gart_size)) - return 0; - return 1; -} - static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * dev_priv, drm_radeon_kcmd_buffer_t @@ -293,7 +273,7 @@ case MARK_SAFE: break; case MARK_CHECK_OFFSET: - if (r300_check_offset(dev_priv, (u32) values[i])) { + if (!radeon_check_offset(dev_priv, (u32) values[i])) { DRM_ERROR ("Offset failed range check (reg=%04x sz=%d)\n", reg, sz); @@ -455,7 +435,7 @@ i = 1; while ((k < narrays) && (i < (count + 1))) { i++; /* skip attribute field */ - if (r300_check_offset(dev_priv, payload[i])) { + if (!radeon_check_offset(dev_priv, payload[i])) { DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); @@ -466,7 +446,7 @@ if (k == narrays) break; /* have one more to process, they come in pairs */ - if (r300_check_offset(dev_priv, payload[i])) { + if (!radeon_check_offset(dev_priv, payload[i])) { DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); @@ -511,7 +491,7 @@ if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; - ret = r300_check_offset(dev_priv, offset); + ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); return DRM_ERR(EINVAL); @@ -521,7 +501,7 @@ if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[3] << 10; - ret = r300_check_offset(dev_priv, offset); + ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); return DRM_ERR(EINVAL); diff -Naur sys/dev/drm.old/radeon_drv.h sys/dev/drm/radeon_drv.h --- sys/dev/drm.old/radeon_drv.h 2006-09-08 01:04:47.000000000 +0200 +++ sys/dev/drm/radeon_drv.h 2008-07-20 03:38:47.000000000 +0200 @@ -309,6 +309,21 @@ extern drm_ioctl_desc_t radeon_ioctls[]; extern int radeon_max_ioctl; +/* Check whether the given hardware address is inside the framebuffer or the + * GART area. + */ +static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, + u64 off) +{ + u32 fb_start = dev_priv->fb_location; + u32 fb_end = fb_start + dev_priv->fb_size - 1; + u32 gart_start = dev_priv->gart_vm_start; + u32 gart_end = gart_start + dev_priv->gart_size - 1; + + return ((off >= fb_start && off <= fb_end) || + (off >= gart_start && off <= gart_end)); +} + /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); diff -Naur sys/dev/drm.old/radeon_state.c sys/dev/drm/radeon_state.c --- sys/dev/drm.old/radeon_state.c 2006-09-08 01:04:47.000000000 +0200 +++ sys/dev/drm/radeon_state.c 2008-07-20 03:43:11.000000000 +0200 @@ -46,10 +46,7 @@ u32 * offset) { u64 off = *offset; - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; + u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; struct drm_radeon_driver_file_fields *radeon_priv; /* Hrm ... the story of the offset ... So this function converts @@ -69,8 +66,7 @@ /* First, the best case, the offset already lands in either the * framebuffer or the GART mapped space */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) + if (radeon_check_offset(dev_priv, off)) return 0; /* Ok, that didn't happen... now check if we have a zero based @@ -84,11 +80,10 @@ /* Finally, assume we aimed at a GART offset if beyond the fb */ if (off > fb_end) - off = off - fb_end - 1 + gart_start; + off = off - fb_end - 1 + dev_priv->gart_vm_start; /* Now recheck and fail if out of bounds */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) { + if (radeon_check_offset(dev_priv, off)) { DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); *offset = off; return 0; >Release-Note: >Audit-Trail: Responsible-Changed-From-To: freebsd-bugs->rnoland Responsible-Changed-By: joel Responsible-Changed-When: Mon Sep 15 16:20:19 UTC 2008 Responsible-Changed-Why: Over to maintainer. http://www.freebsd.org/cgi/query-pr.cgi?pr=125808 From: Robert Noland To: bug-followup@FreeBSD.org, freebsd.asc@schwarzes.net Cc: Subject: Re: kern/125808: [drm] [patch] Radeon X800 GTO - *ERROR* Offset failed range check - DRM problem Date: Wed, 22 Oct 2008 12:32:31 -0400 --=-QbEn+dfWyq5H2AZEtyou Content-Type: text/plain Content-Transfer-Encoding: quoted-printable This is already addressed in -CURRENT. I'll leave this PR open until we MFC after 7.1. robert. --=-QbEn+dfWyq5H2AZEtyou Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (FreeBSD) iEYEABECAAYFAkj/VZ8ACgkQM4TrQ4qfRONHuwCdFCxR6EfO14Swf7uG2JS29Iqa 6HYAn3Csj/wfmSYipv/xfFJDMqt7p0Ew =A3JY -----END PGP SIGNATURE----- --=-QbEn+dfWyq5H2AZEtyou-- State-Changed-From-To: open->closed State-Changed-By: rnoland State-Changed-When: Sun Nov 1 17:30:57 UTC 2009 State-Changed-Why: Corrected in 7, 8 and 9 http://www.freebsd.org/cgi/query-pr.cgi?pr=125808 >Unformatted: