Commit 927cec6c authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2025-04-10' of...

Merge tag 'drm-misc-fixes-2025-04-10' of https://gitlab.freedesktop.org/drm/misc/kernel

 into drm-fixes

Short summary of fixes pull:

imagination:
- Fix overflow
- Fix use-after-free

ivpu:
- Fix suspend/resume

nouveau:
- Do not deref dangling pointer

rockchip:
- Set DP/HDMI registers correctly

tests:
- Clean up struct drm_display_mode in various places

udmabuf:
- Fix overflow

virtgpu:
- Set reservation lock on dma-buf import
- Fix error handling in prepare_fb

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20250410122414.GA32202@2a02-2454-fd5e-fd00-d686-8907-6053-f8d8.dyn6.pyur.net
parents 47271a0c 1d34597a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -332,7 +332,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret)
	if (ret < 0)
		return ret;

	ivpu_pm_trigger_recovery(vdev, "debugfs");
@@ -383,7 +383,7 @@ static int dct_active_set(void *data, u64 active_percent)
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret)
	if (ret < 0)
		return ret;

	if (active_percent)
+2 −1
Original line number Diff line number Diff line
@@ -302,7 +302,8 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req
	struct ivpu_ipc_consumer cons;
	int ret;

	drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
	drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev) &&
		    pm_runtime_enabled(vdev->drm.dev));

	ivpu_ipc_consumer_add(vdev, &cons, channel, NULL);

+24 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 */

#include <drm/drm_file.h>
#include <linux/pm_runtime.h>

#include "ivpu_drv.h"
#include "ivpu_gem.h"
@@ -44,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
	    args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS)
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret < 0)
		return ret;

	mutex_lock(&file_priv->ms_lock);

	if (get_instance_by_mask(file_priv, args->metric_group_mask)) {
@@ -96,6 +101,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
	kfree(ms);
unlock:
	mutex_unlock(&file_priv->ms_lock);

	ivpu_rpm_put(vdev);
	return ret;
}

@@ -160,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
	if (!args->metric_group_mask)
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret < 0)
		return ret;

	mutex_lock(&file_priv->ms_lock);

	ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -187,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
unlock:
	mutex_unlock(&file_priv->ms_lock);

	ivpu_rpm_put(vdev);
	return ret;
}

@@ -204,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
{
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct drm_ivpu_metric_streamer_stop *args = data;
	struct ivpu_device *vdev = file_priv->vdev;
	struct ivpu_ms_instance *ms;
	int ret;

	if (!args->metric_group_mask)
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret < 0)
		return ret;

	mutex_lock(&file_priv->ms_lock);

	ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -217,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file

	mutex_unlock(&file_priv->ms_lock);

	ivpu_rpm_put(vdev);
	return ms ? 0 : -EINVAL;
}

@@ -281,6 +300,9 @@ int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *
void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
{
	struct ivpu_ms_instance *ms, *tmp;
	struct ivpu_device *vdev = file_priv->vdev;

	pm_runtime_get_sync(vdev->drm.dev);

	mutex_lock(&file_priv->ms_lock);

@@ -293,6 +315,8 @@ void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
		free_instance(file_priv, ms);

	mutex_unlock(&file_priv->ms_lock);

	pm_runtime_put_autosuspend(vdev->drm.dev);
}

void ivpu_ms_cleanup_all(struct ivpu_device *vdev)
+1 −1
Original line number Diff line number Diff line
@@ -393,7 +393,7 @@ static long udmabuf_create(struct miscdevice *device,
	if (!ubuf)
		return -ENOMEM;

	pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
	pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
	for (i = 0; i < head->count; i++) {
		pgoff_t subpgcnt;

+20 −7
Original line number Diff line number Diff line
@@ -732,7 +732,7 @@ pvr_fw_process(struct pvr_device *pvr_dev)
					       fw_mem->core_data, fw_mem->core_code_alloc_size);

	if (err)
		goto err_free_fw_core_data_obj;
		goto err_free_kdata;

	memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size);
	memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size);
@@ -742,10 +742,14 @@ pvr_fw_process(struct pvr_device *pvr_dev)
		memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size);

	/* We're finished with the firmware section memory on the CPU, unmap. */
	if (fw_core_data_ptr)
	if (fw_core_data_ptr) {
		pvr_fw_object_vunmap(fw_mem->core_data_obj);
	if (fw_core_code_ptr)
		fw_core_data_ptr = NULL;
	}
	if (fw_core_code_ptr) {
		pvr_fw_object_vunmap(fw_mem->core_code_obj);
		fw_core_code_ptr = NULL;
	}
	pvr_fw_object_vunmap(fw_mem->data_obj);
	fw_data_ptr = NULL;
	pvr_fw_object_vunmap(fw_mem->code_obj);
@@ -753,7 +757,7 @@ pvr_fw_process(struct pvr_device *pvr_dev)

	err = pvr_fw_create_fwif_connection_ctl(pvr_dev);
	if (err)
		goto err_free_fw_core_data_obj;
		goto err_free_kdata;

	return 0;

@@ -763,13 +767,16 @@ pvr_fw_process(struct pvr_device *pvr_dev)
	kfree(fw_mem->data);
	kfree(fw_mem->code);

err_free_fw_core_data_obj:
	if (fw_core_data_ptr)
		pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj);
		pvr_fw_object_vunmap(fw_mem->core_data_obj);
	if (fw_mem->core_data_obj)
		pvr_fw_object_destroy(fw_mem->core_data_obj);

err_free_fw_core_code_obj:
	if (fw_core_code_ptr)
		pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj);
		pvr_fw_object_vunmap(fw_mem->core_code_obj);
	if (fw_mem->core_code_obj)
		pvr_fw_object_destroy(fw_mem->core_code_obj);

err_free_fw_data_obj:
	if (fw_data_ptr)
@@ -836,6 +843,12 @@ pvr_fw_cleanup(struct pvr_device *pvr_dev)
	struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem;

	pvr_fw_fini_fwif_connection_ctl(pvr_dev);

	kfree(fw_mem->core_data);
	kfree(fw_mem->core_code);
	kfree(fw_mem->data);
	kfree(fw_mem->code);

	if (fw_mem->core_code_obj)
		pvr_fw_object_destroy(fw_mem->core_code_obj);
	if (fw_mem->core_data_obj)
Loading