Skip to content

Commit 3c2fe27

Browse files
committed
Merge tag 'drm-fixes-2025-07-12' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Simona Vetter: "Cross-subsystem Changes: - agp/amd64 binding dmesg noise regression fix Core Changes: - fix race in gem_handle_create_tail - fixup handle_count fb refcount regression from -rc5, popular with reports ... - call rust dtor for drm_device release Driver Changes: - nouveau: magic 50ms suspend fix, acpi leak fix - tegra: dma api error in nvdec - pvr: fix device reset - habanalbs maintainer update - intel display: fix some dsi mipi sequences - xe fixes: SRIOV fixes, small GuC fixes, disable indirect ring due to issues, compression fix for fragmented BO, doc update * tag 'drm-fixes-2025-07-12' of https://gitlab.freedesktop.org/drm/kernel: (22 commits) drm/xe/guc: Default log level to non-verbose drm/xe/bmg: Don't use WA 16023588340 and 22019338487 on VF drm/xe/guc: Recommend GuC v70.46.2 for BMG, LNL, DG2 drm/xe/pm: Correct comment of xe_pm_set_vram_threshold() drm/xe: Release runtime pm for error path of xe_devcoredump_read() drm/xe/pm: Restore display pm if there is error after display suspend drm/i915/bios: Apply vlv_fixup_mipi_sequences() to v2 mipi-sequences too drm/gem: Fix race in drm_gem_handle_create_tail() drm/framebuffer: Acquire internal references on GEM handles agp/amd64: Check AGP Capability before binding to unsupported devices drm/xe/bmg: fix compressed VRAM handling Revert "drm/xe/xe2: Enable Indirect Ring State support for Xe2" drm/xe: Allocate PF queue size on pow2 boundary drm/xe/pf: Clear all LMTT pages on alloc drm/nouveau/gsp: fix potential leak of memory used during acpi init rust: drm: remove unnecessary imports MAINTAINERS: Change habanalabs maintainer drm/imagination: Fix kernel crash when hard resetting the GPU drm/tegra: nvdec: Fix dma_alloc_coherent error check rust: drm: device: drop_in_place() the drm::Device in release() ...
2 parents 5f02b80 + b7dc79a commit 3c2fe27

27 files changed

+187
-89
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10506,7 +10506,7 @@ S: Maintained
1050610506
F: block/partitions/efi.*
1050710507

1050810508
HABANALABS PCI DRIVER
10509-
M: Ofir Bitton <[email protected]>
10509+
M: Yaron Avizrat <[email protected]>
1051010510
1051110511
S: Supported
1051210512
C: irc://irc.oftc.net/dri-devel

drivers/char/agp/amd64-agp.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,6 @@ static const struct pci_device_id agp_amd64_pci_table[] = {
720720

721721
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
722722

723-
static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
724-
{ PCI_DEVICE_CLASS(0, 0) },
725-
{ }
726-
};
727-
728723
static DEFINE_SIMPLE_DEV_PM_OPS(agp_amd64_pm_ops, NULL, agp_amd64_resume);
729724

730725
static struct pci_driver agp_amd64_pci_driver = {
@@ -739,6 +734,7 @@ static struct pci_driver agp_amd64_pci_driver = {
739734
/* Not static due to IOMMU code calling it early. */
740735
int __init agp_amd64_init(void)
741736
{
737+
struct pci_dev *pdev = NULL;
742738
int err = 0;
743739

744740
if (agp_off)
@@ -767,9 +763,13 @@ int __init agp_amd64_init(void)
767763
}
768764

769765
/* Look for any AGP bridge */
770-
agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
771-
err = driver_attach(&agp_amd64_pci_driver.driver);
772-
if (err == 0 && agp_bridges_found == 0) {
766+
for_each_pci_dev(pdev)
767+
if (pci_find_capability(pdev, PCI_CAP_ID_AGP))
768+
pci_add_dynid(&agp_amd64_pci_driver,
769+
pdev->vendor, pdev->device,
770+
pdev->subsystem_vendor,
771+
pdev->subsystem_device, 0, 0, 0);
772+
if (agp_bridges_found == 0) {
773773
pci_unregister_driver(&agp_amd64_pci_driver);
774774
err = -ENODEV;
775775
}

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,23 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);
862862
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
863863
const struct drm_framebuffer_funcs *funcs)
864864
{
865+
unsigned int i;
865866
int ret;
867+
bool exists;
866868

867869
if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
868870
return -EINVAL;
869871

872+
for (i = 0; i < fb->format->num_planes; i++) {
873+
if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
874+
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
875+
if (fb->obj[i]) {
876+
exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
877+
if (exists)
878+
fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
879+
}
880+
}
881+
870882
INIT_LIST_HEAD(&fb->filp_head);
871883

872884
fb->funcs = funcs;
@@ -875,15 +887,24 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
875887
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
876888
false, drm_framebuffer_free);
877889
if (ret)
878-
goto out;
890+
goto err;
879891

880892
mutex_lock(&dev->mode_config.fb_lock);
881893
dev->mode_config.num_fb++;
882894
list_add(&fb->head, &dev->mode_config.fb_list);
883895
mutex_unlock(&dev->mode_config.fb_lock);
884896

885897
drm_mode_object_register(dev, &fb->base);
886-
out:
898+
899+
return 0;
900+
901+
err:
902+
for (i = 0; i < fb->format->num_planes; i++) {
903+
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
904+
drm_gem_object_handle_put_unlocked(fb->obj[i]);
905+
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
906+
}
907+
}
887908
return ret;
888909
}
889910
EXPORT_SYMBOL(drm_framebuffer_init);
@@ -960,6 +981,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
960981
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
961982
{
962983
struct drm_device *dev = fb->dev;
984+
unsigned int i;
985+
986+
for (i = 0; i < fb->format->num_planes; i++) {
987+
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
988+
drm_gem_object_handle_put_unlocked(fb->obj[i]);
989+
}
963990

964991
mutex_lock(&dev->mode_config.fb_lock);
965992
list_del(&fb->head);

drivers/gpu/drm/drm_gem.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -223,23 +223,34 @@ static void drm_gem_object_handle_get(struct drm_gem_object *obj)
223223
}
224224

225225
/**
226-
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
226+
* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any
227227
* @obj: GEM object
228228
*
229-
* Acquires a reference on the GEM buffer object's handle. Required
230-
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
231-
* to release the reference.
229+
* Acquires a reference on the GEM buffer object's handle. Required to keep
230+
* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked()
231+
* to release the reference. Does nothing if the buffer object has no handle.
232+
*
233+
* Returns:
234+
* True if a handle exists, or false otherwise
232235
*/
233-
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
236+
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj)
234237
{
235238
struct drm_device *dev = obj->dev;
236239

237240
guard(mutex)(&dev->object_name_lock);
238241

239-
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
242+
/*
243+
* First ref taken during GEM object creation, if any. Some
244+
* drivers set up internal framebuffers with GEM objects that
245+
* do not have a GEM handle. Hence, this counter can be zero.
246+
*/
247+
if (!obj->handle_count)
248+
return false;
249+
240250
drm_gem_object_handle_get(obj);
251+
252+
return true;
241253
}
242-
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
243254

244255
/**
245256
* drm_gem_object_handle_free - release resources bound to userspace handles
@@ -272,7 +283,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
272283
}
273284

274285
/**
275-
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
286+
* drm_gem_object_handle_put_unlocked - releases reference on user-space handle
276287
* @obj: GEM object
277288
*
278289
* Releases a reference on the GEM buffer object's handle. Possibly releases
@@ -283,14 +294,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
283294
struct drm_device *dev = obj->dev;
284295
bool final = false;
285296

286-
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
297+
if (drm_WARN_ON(dev, READ_ONCE(obj->handle_count) == 0))
287298
return;
288299

289300
/*
290-
* Must bump handle count first as this may be the last
291-
* ref, in which case the object would disappear before we
292-
* checked for a name
293-
*/
301+
* Must bump handle count first as this may be the last
302+
* ref, in which case the object would disappear before
303+
* we checked for a name.
304+
*/
294305

295306
mutex_lock(&dev->object_name_lock);
296307
if (--obj->handle_count == 0) {
@@ -303,7 +314,6 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
303314
if (final)
304315
drm_gem_object_put(obj);
305316
}
306-
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
307317

308318
/*
309319
* Called at device or object close to release the file's
@@ -315,6 +325,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
315325
struct drm_file *file_priv = data;
316326
struct drm_gem_object *obj = ptr;
317327

328+
if (drm_WARN_ON(obj->dev, !data))
329+
return 0;
330+
318331
if (obj->funcs->close)
319332
obj->funcs->close(obj, file_priv);
320333

@@ -435,7 +448,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
435448
idr_preload(GFP_KERNEL);
436449
spin_lock(&file_priv->table_lock);
437450

438-
ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
451+
ret = idr_alloc(&file_priv->object_idr, NULL, 1, 0, GFP_NOWAIT);
439452

440453
spin_unlock(&file_priv->table_lock);
441454
idr_preload_end();
@@ -456,6 +469,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
456469
goto err_revoke;
457470
}
458471

472+
/* mirrors drm_gem_handle_delete to avoid races */
473+
spin_lock(&file_priv->table_lock);
474+
obj = idr_replace(&file_priv->object_idr, obj, handle);
475+
WARN_ON(obj != NULL);
476+
spin_unlock(&file_priv->table_lock);
459477
*handlep = handle;
460478
return 0;
461479

drivers/gpu/drm/drm_gem_framebuffer_helper.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
9999
unsigned int i;
100100

101101
for (i = 0; i < fb->format->num_planes; i++)
102-
drm_gem_object_handle_put_unlocked(fb->obj[i]);
102+
drm_gem_object_put(fb->obj[i]);
103103

104104
drm_framebuffer_cleanup(fb);
105105
kfree(fb);
@@ -182,10 +182,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
182182
if (!objs[i]) {
183183
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
184184
ret = -ENOENT;
185-
goto err_gem_object_handle_put_unlocked;
185+
goto err_gem_object_put;
186186
}
187-
drm_gem_object_handle_get_unlocked(objs[i]);
188-
drm_gem_object_put(objs[i]);
189187

190188
min_size = (height - 1) * mode_cmd->pitches[i]
191189
+ drm_format_info_min_pitch(info, i, width)
@@ -195,22 +193,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
195193
drm_dbg_kms(dev,
196194
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
197195
objs[i]->size, min_size, i);
198-
drm_gem_object_handle_put_unlocked(objs[i]);
196+
drm_gem_object_put(objs[i]);
199197
ret = -EINVAL;
200-
goto err_gem_object_handle_put_unlocked;
198+
goto err_gem_object_put;
201199
}
202200
}
203201

204202
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
205203
if (ret)
206-
goto err_gem_object_handle_put_unlocked;
204+
goto err_gem_object_put;
207205

208206
return 0;
209207

210-
err_gem_object_handle_put_unlocked:
208+
err_gem_object_put:
211209
while (i > 0) {
212210
--i;
213-
drm_gem_object_handle_put_unlocked(objs[i]);
211+
drm_gem_object_put(objs[i]);
214212
}
215213
return ret;
216214
}

drivers/gpu/drm/drm_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void drm_sysfs_lease_event(struct drm_device *dev);
161161

162162
/* drm_gem.c */
163163
int drm_gem_init(struct drm_device *dev);
164-
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
164+
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj);
165165
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
166166
int drm_gem_handle_create_tail(struct drm_file *file_priv,
167167
struct drm_gem_object *obj,

drivers/gpu/drm/drm_panic_qr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
//! * <https://github.com/erwanvivien/fast_qr>
2828
//! * <https://github.com/bjguillot/qr>
2929
30-
use kernel::{prelude::*, str::CStr};
30+
use kernel::prelude::*;
3131

3232
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
3333
struct Version(usize);

drivers/gpu/drm/i915/display/intel_bios.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
19381938
int index, len;
19391939

19401940
if (drm_WARN_ON(display->drm,
1941-
!data || panel->vbt.dsi.seq_version != 1))
1941+
!data || panel->vbt.dsi.seq_version >= 3))
19421942
return 0;
19431943

19441944
/* index = 1 to skip sequence byte */
@@ -1961,7 +1961,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
19611961
}
19621962

19631963
/*
1964-
* Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
1964+
* Some v1/v2 VBT MIPI sequences do the deassert in the init OTP sequence.
19651965
* The deassert must be done before calling intel_dsi_device_ready, so for
19661966
* these devices we split the init OTP sequence into a deassert sequence and
19671967
* the actual init OTP part.
@@ -1972,9 +1972,9 @@ static void vlv_fixup_mipi_sequences(struct intel_display *display,
19721972
u8 *init_otp;
19731973
int len;
19741974

1975-
/* Limit this to v1 vid-mode sequences */
1975+
/* Limit this to v1/v2 vid-mode sequences */
19761976
if (panel->vbt.dsi.config->is_cmd_mode ||
1977-
panel->vbt.dsi.seq_version != 1)
1977+
panel->vbt.dsi.seq_version >= 3)
19781978
return;
19791979

19801980
/* Only do this if there are otp and assert seqs and no deassert seq */

drivers/gpu/drm/imagination/pvr_power.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,13 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
386386
if (!err) {
387387
if (hard_reset) {
388388
pvr_dev->fw_dev.booted = false;
389-
WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev));
389+
WARN_ON(pvr_power_device_suspend(from_pvr_device(pvr_dev)->dev));
390390

391391
err = pvr_fw_hard_reset(pvr_dev);
392392
if (err)
393393
goto err_device_lost;
394394

395-
err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev);
395+
err = pvr_power_device_resume(from_pvr_device(pvr_dev)->dev);
396396
pvr_dev->fw_dev.booted = true;
397397
if (err)
398398
goto err_device_lost;

drivers/gpu/drm/nouveau/nouveau_debugfs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,10 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
314314
drm->debugfs = NULL;
315315
}
316316

317-
int
317+
void
318318
nouveau_module_debugfs_init(void)
319319
{
320320
nouveau_debugfs_root = debugfs_create_dir("nouveau", NULL);
321-
if (IS_ERR(nouveau_debugfs_root))
322-
return PTR_ERR(nouveau_debugfs_root);
323-
324-
return 0;
325321
}
326322

327323
void

0 commit comments

Comments
 (0)