Skip to content

Commit 927cec6

Browse files
committed
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: Dave 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
2 parents 47271a0 + 1d34597 commit 927cec6

21 files changed

+165
-53
lines changed

drivers/accel/ivpu/ivpu_debugfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si
332332
return -EINVAL;
333333

334334
ret = ivpu_rpm_get(vdev);
335-
if (ret)
335+
if (ret < 0)
336336
return ret;
337337

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

385385
ret = ivpu_rpm_get(vdev);
386-
if (ret)
386+
if (ret < 0)
387387
return ret;
388388

389389
if (active_percent)

drivers/accel/ivpu/ivpu_ipc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req
302302
struct ivpu_ipc_consumer cons;
303303
int ret;
304304

305-
drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
305+
drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev) &&
306+
pm_runtime_enabled(vdev->drm.dev));
306307

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

drivers/accel/ivpu/ivpu_ms.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
#include <drm/drm_file.h>
7+
#include <linux/pm_runtime.h>
78

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

48+
ret = ivpu_rpm_get(vdev);
49+
if (ret < 0)
50+
return ret;
51+
4752
mutex_lock(&file_priv->ms_lock);
4853

4954
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
96101
kfree(ms);
97102
unlock:
98103
mutex_unlock(&file_priv->ms_lock);
104+
105+
ivpu_rpm_put(vdev);
99106
return ret;
100107
}
101108

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

170+
ret = ivpu_rpm_get(vdev);
171+
if (ret < 0)
172+
return ret;
173+
163174
mutex_lock(&file_priv->ms_lock);
164175

165176
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 *
187198
unlock:
188199
mutex_unlock(&file_priv->ms_lock);
189200

201+
ivpu_rpm_put(vdev);
190202
return ret;
191203
}
192204

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

209223
if (!args->metric_group_mask)
210224
return -EINVAL;
211225

226+
ret = ivpu_rpm_get(vdev);
227+
if (ret < 0)
228+
return ret;
229+
212230
mutex_lock(&file_priv->ms_lock);
213231

214232
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
217235

218236
mutex_unlock(&file_priv->ms_lock);
219237

238+
ivpu_rpm_put(vdev);
220239
return ms ? 0 : -EINVAL;
221240
}
222241

@@ -281,6 +300,9 @@ int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *
281300
void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
282301
{
283302
struct ivpu_ms_instance *ms, *tmp;
303+
struct ivpu_device *vdev = file_priv->vdev;
304+
305+
pm_runtime_get_sync(vdev->drm.dev);
284306

285307
mutex_lock(&file_priv->ms_lock);
286308

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

295317
mutex_unlock(&file_priv->ms_lock);
318+
319+
pm_runtime_put_autosuspend(vdev->drm.dev);
296320
}
297321

298322
void ivpu_ms_cleanup_all(struct ivpu_device *vdev)

drivers/dma-buf/udmabuf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ static long udmabuf_create(struct miscdevice *device,
393393
if (!ubuf)
394394
return -ENOMEM;
395395

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

drivers/gpu/drm/imagination/pvr_fw.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ pvr_fw_process(struct pvr_device *pvr_dev)
732732
fw_mem->core_data, fw_mem->core_code_alloc_size);
733733

734734
if (err)
735-
goto err_free_fw_core_data_obj;
735+
goto err_free_kdata;
736736

737737
memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size);
738738
memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size);
@@ -742,18 +742,22 @@ pvr_fw_process(struct pvr_device *pvr_dev)
742742
memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size);
743743

744744
/* We're finished with the firmware section memory on the CPU, unmap. */
745-
if (fw_core_data_ptr)
745+
if (fw_core_data_ptr) {
746746
pvr_fw_object_vunmap(fw_mem->core_data_obj);
747-
if (fw_core_code_ptr)
747+
fw_core_data_ptr = NULL;
748+
}
749+
if (fw_core_code_ptr) {
748750
pvr_fw_object_vunmap(fw_mem->core_code_obj);
751+
fw_core_code_ptr = NULL;
752+
}
749753
pvr_fw_object_vunmap(fw_mem->data_obj);
750754
fw_data_ptr = NULL;
751755
pvr_fw_object_vunmap(fw_mem->code_obj);
752756
fw_code_ptr = NULL;
753757

754758
err = pvr_fw_create_fwif_connection_ctl(pvr_dev);
755759
if (err)
756-
goto err_free_fw_core_data_obj;
760+
goto err_free_kdata;
757761

758762
return 0;
759763

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

766-
err_free_fw_core_data_obj:
767770
if (fw_core_data_ptr)
768-
pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj);
771+
pvr_fw_object_vunmap(fw_mem->core_data_obj);
772+
if (fw_mem->core_data_obj)
773+
pvr_fw_object_destroy(fw_mem->core_data_obj);
769774

770775
err_free_fw_core_code_obj:
771776
if (fw_core_code_ptr)
772-
pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj);
777+
pvr_fw_object_vunmap(fw_mem->core_code_obj);
778+
if (fw_mem->core_code_obj)
779+
pvr_fw_object_destroy(fw_mem->core_code_obj);
773780

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

838845
pvr_fw_fini_fwif_connection_ctl(pvr_dev);
846+
847+
kfree(fw_mem->core_data);
848+
kfree(fw_mem->core_code);
849+
kfree(fw_mem->data);
850+
kfree(fw_mem->code);
851+
839852
if (fw_mem->core_code_obj)
840853
pvr_fw_object_destroy(fw_mem->core_code_obj);
841854
if (fw_mem->core_data_obj)

drivers/gpu/drm/imagination/pvr_job.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,13 @@ pvr_jobs_link_geom_frag(struct pvr_job_data *job_data, u32 *job_count)
671671
geom_job->paired_job = frag_job;
672672
frag_job->paired_job = geom_job;
673673

674+
/* The geometry job pvr_job structure is used when the fragment
675+
* job is being prepared by the GPU scheduler. Have the fragment
676+
* job hold a reference on the geometry job to prevent it being
677+
* freed until the fragment job has finished with it.
678+
*/
679+
pvr_job_get(geom_job);
680+
674681
/* Skip the fragment job we just paired to the geometry job. */
675682
i++;
676683
}

drivers/gpu/drm/imagination/pvr_queue.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,10 @@ static void pvr_queue_free_job(struct drm_sched_job *sched_job)
866866
struct pvr_job *job = container_of(sched_job, struct pvr_job, base);
867867

868868
drm_sched_job_cleanup(sched_job);
869+
870+
if (job->type == DRM_PVR_JOB_TYPE_FRAGMENT && job->paired_job)
871+
pvr_job_put(job->paired_job);
872+
869873
job->paired_job = NULL;
870874
pvr_job_put(job);
871875
}

drivers/gpu/drm/nouveau/nouveau_bo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
144144
nouveau_bo_del_io_reserve_lru(bo);
145145
nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
146146

147+
if (bo->base.import_attach)
148+
drm_prime_gem_destroy(&bo->base, bo->sg);
149+
147150
/*
148151
* If nouveau_bo_new() allocated this buffer, the GEM object was never
149152
* initialized, so don't attempt to release it.

drivers/gpu/drm/nouveau/nouveau_gem.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
8787
return;
8888
}
8989

90-
if (gem->import_attach)
91-
drm_prime_gem_destroy(gem, nvbo->bo.sg);
92-
9390
ttm_bo_put(&nvbo->bo);
9491

9592
pm_runtime_mark_last_busy(dev);

drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct rockchip_hdmi_qp {
9494
struct gpio_desc *enable_gpio;
9595
struct delayed_work hpd_work;
9696
int port_id;
97+
const struct rockchip_hdmi_qp_ctrl_ops *ctrl_ops;
9798
};
9899

99100
struct rockchip_hdmi_qp_ctrl_ops {
@@ -461,6 +462,7 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
461462
return -ENODEV;
462463
}
463464

465+
hdmi->ctrl_ops = cfg->ctrl_ops;
464466
hdmi->dev = &pdev->dev;
465467
hdmi->port_id = -ENODEV;
466468

@@ -600,27 +602,8 @@ static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev)
600602
static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
601603
{
602604
struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
603-
u32 val;
604605

605-
val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
606-
HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
607-
HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
608-
HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
609-
regmap_write(hdmi->vo_regmap,
610-
hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
611-
val);
612-
613-
val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
614-
RK3588_SET_HPD_PATH_MASK);
615-
regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
616-
617-
if (hdmi->port_id)
618-
val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
619-
RK3588_HDMI1_GRANT_SEL);
620-
else
621-
val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
622-
RK3588_HDMI0_GRANT_SEL);
623-
regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
606+
hdmi->ctrl_ops->io_init(hdmi);
624607

625608
dw_hdmi_qp_resume(dev, hdmi->hdmi);
626609

0 commit comments

Comments
 (0)