Commit b83ac44e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2023-05-26' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "This week's collection is pretty spread out, accel/qaic has a bunch of
  fixes, amdgpu, then lots of single fixes across a bunch of places.

  core:
   - fix drmm_mutex_init lock class

  mgag200:
   - fix gamma lut initialisation

  pl111:
   - fix FB depth on IMPD-1 framebuffer

  amdgpu:
   - Fix missing BO unlocking in KIQ error path
   - Avoid spurious secure display error messages
   - SMU13 fix
   - Fix an OD regression
   - GPU reset display IRQ warning fix
   - MST fix

  radeon:
   - Fix a DP regression

  i915:
   - PIPEDMC disabling fix for bigjoiner config

  panel:
   - fix aya neo air plus quirk

  sched:
   - remove redundant NULL check

  qaic:
   - fix NNC message corruption
   - Grab ch_lock during QAIC_ATTACH_SLICE_BO
   - Flush the transfer list again
   - Validate if BO is sliced before slicing
   - Validate user data before grabbing any lock
   - initialize ret variable to 0
   - silence some uninitialized variable warnings"

* tag 'drm-fixes-2023-05-26' of git://anongit.freedesktop.org/drm/drm:
  drm/amd/display: Have Payload Properly Created After Resume
  drm/amd/display: Fix warning in disabling vblank irq
  drm/amd/pm: Fix output of pp_od_clk_voltage
  drm/amd/pm: add missing NotifyPowerSource message mapping for SMU13.0.7
  drm/radeon: reintroduce radeon_dp_work_func content
  drm/amdgpu: don't enable secure display on incompatible platforms
  drm:amd:amdgpu: Fix missing buffer object unlock in failure path
  accel/qaic: Fix NNC message corruption
  accel/qaic: Grab ch_lock during QAIC_ATTACH_SLICE_BO
  accel/qaic: Flush the transfer list again
  accel/qaic: Validate if BO is sliced before slicing
  accel/qaic: Validate user data before grabbing any lock
  accel/qaic: initialize ret variable to 0
  drm/i915: Fix PIPEDMC disabling for a bigjoiner configuration
  drm: fix drmm_mutex_init()
  drm/sched: Remove redundant check
  drm: panel-orientation-quirks: Change Air's quirk to support Air Plus
  accel/qaic: silence some uninitialized variable warnings
  drm/pl111: Fix FB depth on IMPD-1 framebuffer
  drm/mgag200: Fix gamma lut not initialized.
parents 47ee3f1d 5502d1fa
Loading
Loading
Loading
Loading
+25 −16
Original line number Diff line number Diff line
@@ -997,14 +997,34 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u
	struct xfer_queue_elem elem;
	struct wire_msg *out_buf;
	struct wrapper_msg *w;
	long ret = -EAGAIN;
	int xfer_count = 0;
	int retry_count;
	long ret;

	if (qdev->in_reset) {
		mutex_unlock(&qdev->cntl_mutex);
		return ERR_PTR(-ENODEV);
	}

	/* Attempt to avoid a partial commit of a message */
	list_for_each_entry(w, &wrappers->list, list)
		xfer_count++;

	for (retry_count = 0; retry_count < QAIC_MHI_RETRY_MAX; retry_count++) {
		if (xfer_count <= mhi_get_free_desc_count(qdev->cntl_ch, DMA_TO_DEVICE)) {
			ret = 0;
			break;
		}
		msleep_interruptible(QAIC_MHI_RETRY_WAIT_MS);
		if (signal_pending(current))
			break;
	}

	if (ret) {
		mutex_unlock(&qdev->cntl_mutex);
		return ERR_PTR(ret);
	}

	elem.seq_num = seq_num;
	elem.buf = NULL;
	init_completion(&elem.xfer_done);
@@ -1038,16 +1058,9 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u
	list_for_each_entry(w, &wrappers->list, list) {
		kref_get(&w->ref_count);
		retry_count = 0;
retry:
		ret = mhi_queue_buf(qdev->cntl_ch, DMA_TO_DEVICE, &w->msg, w->len,
				    list_is_last(&w->list, &wrappers->list) ? MHI_EOT : MHI_CHAIN);
		if (ret) {
			if (ret == -EAGAIN && retry_count++ < QAIC_MHI_RETRY_MAX) {
				msleep_interruptible(QAIC_MHI_RETRY_WAIT_MS);
				if (!signal_pending(current))
					goto retry;
			}

			qdev->cntl_lost_buf = true;
			kref_put(&w->ref_count, free_wrapper);
			mutex_unlock(&qdev->cntl_mutex);
@@ -1249,7 +1262,7 @@ static int qaic_manage(struct qaic_device *qdev, struct qaic_user *usr, struct m

int qaic_manage_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	struct qaic_manage_msg *user_msg;
	struct qaic_manage_msg *user_msg = data;
	struct qaic_device *qdev;
	struct manage_msg *msg;
	struct qaic_user *usr;
@@ -1258,6 +1271,9 @@ int qaic_manage_ioctl(struct drm_device *dev, void *data, struct drm_file *file_
	int usr_rcu_id;
	int ret;

	if (user_msg->len > QAIC_MANAGE_MAX_MSG_LENGTH)
		return -EINVAL;

	usr = file_priv->driver_priv;

	usr_rcu_id = srcu_read_lock(&usr->qddev_lock);
@@ -1275,13 +1291,6 @@ int qaic_manage_ioctl(struct drm_device *dev, void *data, struct drm_file *file_
		return -ENODEV;
	}

	user_msg = data;

	if (user_msg->len > QAIC_MANAGE_MAX_MSG_LENGTH) {
		ret = -EINVAL;
		goto out;
	}

	msg = kzalloc(QAIC_MANAGE_MAX_MSG_LENGTH + sizeof(*msg), GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
+46 −47
Original line number Diff line number Diff line
@@ -591,7 +591,7 @@ static int qaic_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc
	struct qaic_bo *bo = to_qaic_bo(obj);
	unsigned long offset = 0;
	struct scatterlist *sg;
	int ret;
	int ret = 0;

	if (obj->import_attach)
		return -EINVAL;
@@ -663,6 +663,10 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi
	if (args->pad)
		return -EINVAL;

	size = PAGE_ALIGN(args->size);
	if (size == 0)
		return -EINVAL;

	usr = file_priv->driver_priv;
	usr_rcu_id = srcu_read_lock(&usr->qddev_lock);
	if (!usr->qddev) {
@@ -677,12 +681,6 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi
		goto unlock_dev_srcu;
	}

	size = PAGE_ALIGN(args->size);
	if (size == 0) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	bo = qaic_alloc_init_bo();
	if (IS_ERR(bo)) {
		ret = PTR_ERR(bo);
@@ -926,8 +924,8 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
{
	struct qaic_attach_slice_entry *slice_ent;
	struct qaic_attach_slice *args = data;
	int rcu_id, usr_rcu_id, qdev_rcu_id;
	struct dma_bridge_chan	*dbc;
	int usr_rcu_id, qdev_rcu_id;
	struct drm_gem_object *obj;
	struct qaic_device *qdev;
	unsigned long arg_size;
@@ -936,6 +934,22 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
	struct qaic_bo *bo;
	int ret;

	if (args->hdr.count == 0)
		return -EINVAL;

	arg_size = args->hdr.count * sizeof(*slice_ent);
	if (arg_size / args->hdr.count != sizeof(*slice_ent))
		return -EINVAL;

	if (args->hdr.size == 0)
		return -EINVAL;

	if (!(args->hdr.dir == DMA_TO_DEVICE || args->hdr.dir == DMA_FROM_DEVICE))
		return -EINVAL;

	if (args->data == 0)
		return -EINVAL;

	usr = file_priv->driver_priv;
	usr_rcu_id = srcu_read_lock(&usr->qddev_lock);
	if (!usr->qddev) {
@@ -950,43 +964,11 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
		goto unlock_dev_srcu;
	}

	if (args->hdr.count == 0) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	arg_size = args->hdr.count * sizeof(*slice_ent);
	if (arg_size / args->hdr.count != sizeof(*slice_ent)) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	if (args->hdr.dbc_id >= qdev->num_dbc) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	if (args->hdr.size == 0) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	if (!(args->hdr.dir == DMA_TO_DEVICE  || args->hdr.dir == DMA_FROM_DEVICE)) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	dbc = &qdev->dbc[args->hdr.dbc_id];
	if (dbc->usr != usr) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	if (args->data == 0) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	user_data = u64_to_user_ptr(args->data);

	slice_ent = kzalloc(arg_size, GFP_KERNEL);
@@ -1013,9 +995,21 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi

	bo = to_qaic_bo(obj);

	if (bo->sliced) {
		ret = -EINVAL;
		goto put_bo;
	}

	dbc = &qdev->dbc[args->hdr.dbc_id];
	rcu_id = srcu_read_lock(&dbc->ch_lock);
	if (dbc->usr != usr) {
		ret = -EINVAL;
		goto unlock_ch_srcu;
	}

	ret = qaic_prepare_bo(qdev, bo, &args->hdr);
	if (ret)
		goto put_bo;
		goto unlock_ch_srcu;

	ret = qaic_attach_slicing_bo(qdev, bo, &args->hdr, slice_ent);
	if (ret)
@@ -1025,6 +1019,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
		dma_sync_sgtable_for_cpu(&qdev->pdev->dev, bo->sgt, args->hdr.dir);

	bo->dbc = dbc;
	srcu_read_unlock(&dbc->ch_lock, rcu_id);
	drm_gem_object_put(obj);
	srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
	srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);
@@ -1033,6 +1028,8 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi

unprepare_bo:
	qaic_unprepare_bo(qdev, bo);
unlock_ch_srcu:
	srcu_read_unlock(&dbc->ch_lock, rcu_id);
put_bo:
	drm_gem_object_put(obj);
free_slice_ent:
@@ -1316,7 +1313,6 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr
	received_ts = ktime_get_ns();

	size = is_partial ? sizeof(*pexec) : sizeof(*exec);

	n = (unsigned long)size * args->hdr.count;
	if (args->hdr.count == 0 || n / args->hdr.count != size)
		return -EINVAL;
@@ -1665,6 +1661,9 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file
	int rcu_id;
	int ret;

	if (args->pad != 0)
		return -EINVAL;

	usr = file_priv->driver_priv;
	usr_rcu_id = srcu_read_lock(&usr->qddev_lock);
	if (!usr->qddev) {
@@ -1679,11 +1678,6 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file
		goto unlock_dev_srcu;
	}

	if (args->pad != 0) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
	}

	if (args->dbc_id >= qdev->num_dbc) {
		ret = -EINVAL;
		goto unlock_dev_srcu;
@@ -1855,6 +1849,11 @@ void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id)
	dbc->usr = NULL;
	empty_xfer_list(qdev, dbc);
	synchronize_srcu(&dbc->ch_lock);
	/*
	 * Threads holding channel lock, may add more elements in the xfer_list.
	 * Flush out these elements from xfer_list.
	 */
	empty_xfer_list(qdev, dbc);
}

void release_dbc(struct qaic_device *qdev, u32 dbc_id)
+1 −1
Original line number Diff line number Diff line
@@ -262,8 +262,8 @@ static void qaic_destroy_drm_device(struct qaic_device *qdev, s32 partition_id)

static int qaic_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
{
	u16 major = -1, minor = -1;
	struct qaic_device *qdev;
	u16 major, minor;
	int ret;

	/*
+3 −1
Original line number Diff line number Diff line
@@ -6892,8 +6892,10 @@ static int gfx_v10_0_kiq_resume(struct amdgpu_device *adev)
		return r;

	r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
	if (unlikely(r != 0))
	if (unlikely(r != 0)) {
		amdgpu_bo_unreserve(ring->mqd_obj);
		return r;
	}

	gfx_v10_0_kiq_init_queue(ring);
	amdgpu_bo_kunmap(ring->mqd_obj);
+3 −1
Original line number Diff line number Diff line
@@ -3617,8 +3617,10 @@ static int gfx_v9_0_kiq_resume(struct amdgpu_device *adev)
		return r;

	r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
	if (unlikely(r != 0))
	if (unlikely(r != 0)) {
		amdgpu_bo_unreserve(ring->mqd_obj);
		return r;
	}

	gfx_v9_0_kiq_init_queue(ring);
	amdgpu_bo_kunmap(ring->mqd_obj);
Loading