Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70740d6c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm: Avoid oops in DRM_IOCTL_RM_DRAW if a bad handle is supplied.
  drm: Add 32-bit compatibility for DRM_IOCTL_UPDATE_DRAW.
  drm/i915: use pipes, not planes to label vblank data
  drm/i915: hold dev->struct_mutex and DRM lock during vblank ring operations
  i915: Fix format string warnings on x86-64.
  i915: Don't dereference HWS in /proc debug files when it isn't initialized.
  i915: Enable IMR passthrough of vblank events before enabling it in pipestat.
  drm: Remove two leaks of vblank reference count in error paths.
  drm: fix leak of cliprects in drm_rmdraw()
  i915: Disable MSI on GM965 (errata says it doesn't work)
  drm: Set cliprects to NULL when changing drawable to having 0 cliprects.
  i915: Protect vblank IRQ reg access with spinlock
parents a3415dc3 7e78f725
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -76,11 +76,18 @@ int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	struct drm_draw *draw = data;
	unsigned long irqflags;
	struct drm_drawable_info *info;

	spin_lock_irqsave(&dev->drw_lock, irqflags);

	drm_free(drm_get_drawable_info(dev, draw->handle),
		 sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
	info = drm_get_drawable_info(dev, draw->handle);
	if (info == NULL) {
		spin_unlock_irqrestore(&dev->drw_lock, irqflags);
		return -EINVAL;
	}
	drm_free(info->rects, info->num_rects * sizeof(struct drm_clip_rect),
			DRM_MEM_BUFS);
	drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS);

	idr_remove(&dev->drw_idr, draw->handle);

@@ -111,7 +118,9 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file

	switch (update->type) {
	case DRM_DRAWABLE_CLIPRECTS:
		if (update->num != info->num_rects) {
		if (update->num == 0)
			rects = NULL;
		else if (update->num != info->num_rects) {
			rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
					 DRM_MEM_BUFS);
		} else
+34 −0
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@
#define DRM_IOCTL_SG_ALLOC32		DRM_IOW( 0x38, drm_scatter_gather32_t)
#define DRM_IOCTL_SG_FREE32		DRM_IOW( 0x39, drm_scatter_gather32_t)

#define DRM_IOCTL_UPDATE_DRAW32		DRM_IOW( 0x3f, drm_update_draw32_t)

#define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)

typedef struct drm_version_32 {
@@ -952,6 +954,37 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
			 DRM_IOCTL_SG_FREE, (unsigned long)request);
}

typedef struct drm_update_draw32 {
	drm_drawable_t handle;
	unsigned int type;
	unsigned int num;
	/* 64-bit version has a 32-bit pad here */
	u64 data;	/**< Pointer */
} __attribute__((packed)) drm_update_draw32_t;

static int compat_drm_update_draw(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	drm_update_draw32_t update32;
	struct drm_update_draw __user *request;
	int err;

	if (copy_from_user(&update32, (void __user *)arg, sizeof(update32)))
		return -EFAULT;

	request = compat_alloc_user_space(sizeof(*request));
	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) ||
	    __put_user(update32.handle, &request->handle) ||
	    __put_user(update32.type, &request->type) ||
	    __put_user(update32.num, &request->num) ||
	    __put_user(update32.data, &request->data))
		return -EFAULT;

	err = drm_ioctl(file->f_path.dentry->d_inode, file,
			DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
	return err;
}

struct drm_wait_vblank_request32 {
	enum drm_vblank_seq_type type;
	unsigned int sequence;
@@ -1033,6 +1066,7 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = {
#endif
	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
	[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
};

+4 −1
Original line number Diff line number Diff line
@@ -594,11 +594,14 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
			goto done;
		}

		/* Get a refcount on the vblank, which will be released by
		 * drm_vbl_send_signals().
		 */
		ret = drm_vblank_get(dev, crtc);
		if (ret) {
			drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
				 DRM_MEM_DRIVER);
			return ret;
			goto done;
		}

		atomic_inc(&dev->vbl_signal_pending);
+2 −0
Original line number Diff line number Diff line
@@ -232,6 +232,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
	}
	return 0;
}
EXPORT_SYMBOL(drm_lock_take);

/**
 * This takes a lock forcibly and hands it to context.	Should ONLY be used
@@ -299,6 +300,7 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
	wake_up_interruptible(&lock_data->lock_queue);
	return 0;
}
EXPORT_SYMBOL(drm_lock_free);

/**
 * If we get here, it means that the process has called DRM_IOCTL_LOCK
+4 −1
Original line number Diff line number Diff line
@@ -844,8 +844,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	 * correctly in testing on 945G.
	 * This may be a side effect of MSI having been made available for PEG
	 * and the registers being closely associated.
	 *
	 * According to chipset errata, on the 965GM, MSI interrupts may
	 * be lost or delayed
	 */
	if (!IS_I945G(dev) && !IS_I945GM(dev))
	if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev))
		if (pci_enable_msi(dev->pdev))
			DRM_ERROR("failed to enable MSI\n");

Loading