diff --git a/sys/dev/drm/r600_cp.c b/sys/dev/drm/r600_cp.c index acf8b93..71a3eaa 100644 --- a/sys/dev/drm/r600_cp.c +++ b/sys/dev/drm/r600_cp.c @@ -2333,8 +2333,13 @@ int r600_cp_dispatch_texture(struct drm_device * dev, buf = radeon_freelist_get(dev); if (!buf) { DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) + DRM_UNLOCK(); + if (DRM_COPY_TO_USER(tex->image, image, + sizeof(*image))) { + DRM_LOCK(); return -EFAULT; + } + DRM_LOCK(); return -EAGAIN; } @@ -2346,10 +2351,13 @@ int r600_cp_dispatch_texture(struct drm_device * dev, buffer = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); + DRM_UNLOCK(); if (DRM_COPY_FROM_USER(buffer, data, pass_size)) { DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size); + DRM_LOCK(); return -EFAULT; } + DRM_LOCK(); buf->file_priv = file_priv; buf->used = pass_size; diff --git a/sys/dev/drm/radeon_state.c b/sys/dev/drm/radeon_state.c index fd8388f..e1b802f 100644 --- a/sys/dev/drm/radeon_state.c +++ b/sys/dev/drm/radeon_state.c @@ -1773,8 +1773,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, } if (!buf) { DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) + DRM_UNLOCK(); + if (DRM_COPY_TO_USER(tex->image, image, + sizeof(*image))) { + DRM_LOCK(); return -EFAULT; + } + DRM_LOCK(); return -EAGAIN; } @@ -1786,10 +1791,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, #define RADEON_COPY_MT(_buf, _data, _width) \ do { \ + DRM_UNLOCK(); \ if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ + DRM_LOCK(); \ return -EFAULT; \ } \ + DRM_LOCK(); \ } while(0) if (microtile) { @@ -2394,10 +2402,14 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file return -EINVAL; } + DRM_UNLOCK(); if (DRM_COPY_FROM_USER(&image, (drm_radeon_tex_image_t __user *) tex->image, - sizeof(image))) + sizeof(image))) { + DRM_LOCK(); return -EFAULT; + } + DRM_LOCK(); RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv);