From owner-freebsd-stable@FreeBSD.ORG Thu Oct 25 21:43:42 2007 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E385316A46E; Thu, 25 Oct 2007 21:43:41 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from gnome.kiev.sovam.com (gnome.kiev.sovam.com [212.109.32.24]) by mx1.freebsd.org (Postfix) with ESMTP id 2D6E613C4A6; Thu, 25 Oct 2007 21:43:41 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from relay02.kiev.sovam.com ([62.64.120.197]) by gnome.kiev.sovam.com with esmtp (Exim 4.67 (FreeBSD)) (envelope-from ) id 1Il6w7-0008Uo-He; Thu, 25 Oct 2007 20:56:03 +0300 Received: from [212.82.216.226] (helo=deviant.kiev.zoral.com.ua) by relay02.kiev.sovam.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.67) (envelope-from ) id 1Il6vw-0006bo-Dl; Thu, 25 Oct 2007 20:56:02 +0300 Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.1/8.14.1) with ESMTP id l9PHtnQS040522; Thu, 25 Oct 2007 20:55:49 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.1/8.14.1/Submit) id l9PHtnhc040498; Thu, 25 Oct 2007 20:55:49 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 25 Oct 2007 20:55:49 +0300 From: Kostik Belousov To: pluknet Message-ID: <20071025175548.GV2012@deviant.kiev.zoral.com.ua> References: Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="gPQW1Pk7T/0rhUBV" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Scanner-Signature: 78ef101f1599e7371446f950a81864ad X-DrWeb-checked: yes X-SpamTest-Envelope-From: kostikbel@gmail.com X-SpamTest-Group-ID: 00000000 X-SpamTest-Info: Profiles 1674 [Oct 25 2007] X-SpamTest-Info: helo_type=3 X-SpamTest-Info: {TO: seems autogenerated} X-SpamTest-Info: {TO: local part of email appears in body} X-SpamTest-Info: {received from trusted relay: not dialup} X-SpamTest-Method: none X-SpamTest-Method: Local Lists X-SpamTest-Rate: 20 X-SpamTest-Status: Not detected X-SpamTest-Status-Extended: not_detected X-SpamTest-Version: SMTP-Filter Version 3.0.0 [0255], KAS30/Release Cc: anholt@freebsd.org, freebsd-stable@freebsd.org Subject: Re: drm(4) related LOR X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Oct 2007 21:43:42 -0000 --gPQW1Pk7T/0rhUBV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Oct 25, 2007 at 03:37:32PM +0400, pluknet wrote: > Hi all. >=20 > I am getting the following LOR on my 7.0-BETA1: >=20 > lock order reversal: (sleepable after non-sleepable) > 1st 0xc3c904d8 drm device (drm device) @ /media/src/sys/modules/drm/drm/.= ./../.. > /dev/drm/drm_drv.c:907 > 2nd 0xc4135a3c user map (user map) @ vm/vm_glue.c:183 > KDB: stack backtrace: > db_trace_self_wrapper(c076f2df,e6716a74,c055fcd6,c077168b,c4135a3c,...) a= t db_tr > ace_self_wrapper+0x26 > kdb_backtrace(c077168b,c4135a3c,c078accb,c078accb,c078a7e6,...) at kdb_ba= cktrace > +0x29 > witness_checkorder(c4135a3c,9,c078a7dd,b7,c4135a3c,...) at witness_checko= rder+0x > 6d6 > _sx_xlock(c4135a3c,0,c078a7dd,b7,e6716ad8,...) at _sx_xlock+0x7d > _vm_map_lock_read(c41359f8,c078a7dd,b7,c078ac64,8,...) at _vm_map_lock_re= ad+0x50 > useracc(28aab980,8,1,1,c076b1ec,...) at useracc+0x65 > i915_cmdbuffer(c4147100,8018644b,c52e8180,3,c492dc60,...) at i915_cmdbuff= er+0x56 > 3 > drm_ioctl(c4147100,8018644b,c52e8180,3,c492dc60,...) at drm_ioctl+0x384 > giant_ioctl(c4147100,8018644b,c52e8180,3,c492dc60,...) at giant_ioctl+0x56 > devfs_ioctl_f(c5c146c0,8018644b,c52e8180,c5536500,c492dc60,...) at devfs_= ioctl_f > +0xd5 > kern_ioctl(c492dc60,5,8018644b,c52e8180,c52e8180,...) at kern_ioctl+0x253 > ioctl(c492dc60,e6716cfc,c,e6716d38,c07a92d0,...) at ioctl+0x13f > syscall(e6716d38) at syscall+0x2f3 > Xint0x80_syscall() at Xint0x80_syscall+0x20 > --- syscall (54, FreeBSD ELF32, ioctl), eip =3D 0x28698a53, esp =3D 0xbf6= f6c9c, ebp > =3D 0xbf6f6cb8 --- >=20 > It is first observed after update to 7.0-BETA1 (from CURRENT of Oct 11) > $ ident /media/src/sys/dev/drm/drm_drv.c > /media/src/sys/dev/drm/drm_drv.c: > $FreeBSD: src/sys/dev/drm/drm_drv.c,v 1.6 2006/09/07 23:04:47 anholt= Exp $ > $ ident /media/src/sys/vm/vm_glue.c > /media/src/sys/vm/vm_glue.c: > $FreeBSD: src/sys/vm/vm_glue.c,v 1.225 2007/09/21 05:07:07 jeff Exp $ >=20 > Note that drm is kldloadable and is not statically compiled in a kernel. > Thanks. The folowing patch should fix it. I tried to get review by Eric, but failed. diff --git a/sys/dev/drm/i915_dma.c b/sys/dev/drm/i915_dma.c index 16955bd..69854b4 100644 --- a/sys/dev/drm/i915_dma.c +++ b/sys/dev/drm/i915_dma.c @@ -366,20 +366,14 @@ static int i915_emit_cmds(drm_device_t * dev, int __u= ser * buffer, int dwords) for (i =3D 0; i < dwords;) { int cmd, sz; =20 - if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) { - - return DRM_ERR(EINVAL); - } + cmd =3D buffer[i]; if ((sz =3D validate_cmd(cmd)) =3D=3D 0 || i + sz > dwords) return DRM_ERR(EINVAL); =20 OUT_RING(cmd); =20 while (++i, --sz) { - if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], - sizeof(cmd))) { - return DRM_ERR(EINVAL); - } + cmd =3D buffer[i]; OUT_RING(cmd); } } @@ -400,10 +394,7 @@ static int i915_emit_box(drm_device_t * dev, drm_clip_rect_t box; RING_LOCALS; =20 - if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return EFAULT; - } - + box =3D boxes[i]; if (box.y2 <=3D box.y1 || box.x2 <=3D box.x1 || box.y2 <=3D 0 || box.x2 <= =3D 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", box.x1, box.y1, box.x2, box.y2); @@ -603,6 +594,7 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) drm_i915_sarea_t *sarea_priv =3D (drm_i915_sarea_t *) dev_priv->sarea_priv; drm_i915_batchbuffer_t batch; + size_t cliplen; int ret; =20 if (!dev_priv->allow_batchbuffer) { @@ -618,14 +610,25 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) =20 LOCK_TEST_WITH_RETURN(dev, filp); =20 + DRM_UNLOCK(); + cliplen =3D batch.num_cliprects * sizeof(drm_clip_rect_t);=09 if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, - batch.num_cliprects * - sizeof(drm_clip_rect_t))) + cliplen)) { + DRM_LOCK(); return DRM_ERR(EFAULT); - + } + ret =3D vslock(batch.cliprects, cliplen); + if (ret) { + DRM_ERROR("Fault wiring cliprects\n"); + DRM_LOCK(); + return DRM_ERR(EFAULT); + } + DRM_LOCK(); ret =3D i915_dispatch_batchbuffer(dev, &batch); - sarea_priv->last_dispatch =3D (int)hw_status[5]; + DRM_UNLOCK(); + vsunlock(batch.cliprects, cliplen); + DRM_LOCK(); return ret; } =20 @@ -637,6 +640,7 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) drm_i915_sarea_t *sarea_priv =3D (drm_i915_sarea_t *) dev_priv->sarea_priv; drm_i915_cmdbuffer_t cmdbuf; + size_t cliplen; int ret; =20 DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data, @@ -647,22 +651,38 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) =20 LOCK_TEST_WITH_RETURN(dev, filp); =20 + DRM_UNLOCK(); + cliplen =3D cmdbuf.num_cliprects * sizeof(drm_clip_rect_t); if (cmdbuf.num_cliprects && - DRM_VERIFYAREA_READ(cmdbuf.cliprects, - cmdbuf.num_cliprects * - sizeof(drm_clip_rect_t))) { + DRM_VERIFYAREA_READ(cmdbuf.cliprects, cliplen)) { DRM_ERROR("Fault accessing cliprects\n"); + DRM_LOCK(); return DRM_ERR(EFAULT); } - - ret =3D i915_dispatch_cmdbuffer(dev, &cmdbuf); + ret =3D vslock(cmdbuf.cliprects, cliplen); if (ret) { - DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); - return ret; + DRM_ERROR("Fault wiring cliprects\n"); + DRM_LOCK(); + return DRM_ERR(EFAULT); } - - sarea_priv->last_dispatch =3D (int)hw_status[5]; - return 0; + ret =3D vslock(cmdbuf.buf, cmdbuf.sz); + if (ret) { + vsunlock(cmdbuf.cliprects, cliplen); + DRM_ERROR("Fault wiring cmds\n"); + DRM_LOCK(); + return DRM_ERR(EFAULT); + } + DRM_LOCK(); + ret =3D i915_dispatch_cmdbuffer(dev, &cmdbuf); + if (ret =3D=3D 0) + sarea_priv->last_dispatch =3D (int)hw_status[5]; + else + DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); + DRM_UNLOCK(); + vsunlock(cmdbuf.buf, cmdbuf.sz); + vsunlock(cmdbuf.cliprects, cliplen); + DRM_LOCK(); + return (ret); } =20 static int i915_do_cleanup_pageflip(drm_device_t * dev) --gPQW1Pk7T/0rhUBV Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4 (FreeBSD) iD8DBQFHINikC3+MBN1Mb4gRAo8uAKCEJKuxeGRe8DG0IGAZuZ9M3TFCNgCgh3p9 q8Mop3edA0aZnsxjAwJ/kBM= =4sMU -----END PGP SIGNATURE----- --gPQW1Pk7T/0rhUBV--