Skip to content

Commit 26df51a

Browse files
committed
Merge tag 'drm-fixes-2026-03-28-1' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie: "Weekly fixes, still a bit busy, but the usual suspects amdgpu and i915/xe have a bunch of small fixes, and otherwise it's just a few minor driver fixes. loognsoon: - update MAINTAINERS shmem: - fault handler fix syncobj: - fix GFP flags amdgpu: - DSC fix - Module parameter parsing fix - PASID reuse fix - drm_edid leak fix - SMU 13.x fixes - SMU 14.x fix - Fence fix in amdgpu_amdkfd_submit_ib() - LVDS fixes - GPU page fault fix for non-4K pages amdkfd: - Ordering fix in kfd_ioctl_create_process() i915/display: - DP tunnel error handling fix - Spurious GMBUS timeout fix - Unlink NV12 planes earlier - Order OP vs. timeout correctly in __wait_for() xe: - Fix UAF in SRIOV migration restore - Updates to HW W/a - VMBind remap fix ivpu: - poweroff fix mediatek: - fix register ordering" * tag 'drm-fixes-2026-03-28-1' of https://gitlab.freedesktop.org/drm/kernel: (25 commits) MAINTAINERS: Update GPU driver maintainer information drm/xe: always keep track of remap prev/next drm/syncobj: Fix xa_alloc allocation flags drm/amd/display: Fix DCE LVDS handling drm/amdgpu: Handle GPU page faults correctly on non-4K page systems drm/amd/pm: disable OD_FAN_CURVE if temp or pwm range invalid for smu v14 drm/amdkfd: Fix NULL pointer check order in kfd_ioctl_create_process drm/amd/display: check if ext_caps is valid in BL setup drm/amdgpu: Fix fence put before wait in amdgpu_amdkfd_submit_ib drm/xe: Implement recent spec updates to Wa_16025250150 accel/ivpu: Add disable clock relinquish workaround for NVL-A0 drm/i915/dp_tunnel: Fix error handling when clearing stream BW in atomic state drm/amd/pm: disable OD_FAN_CURVE if temp or pwm range invalid for smu v13 drm/amd/pm: Return -EOPNOTSUPP for unsupported OD_MCLK on smu_v13_0_6 drm/amd/pm: Skip redundant UCLK restore in smu_v13_0_6 drm/amd/display: Fix drm_edid leak in amdgpu_dm drm/amdgpu: prevent immediate PASID reuse case drm/amdgpu: fix strsep() corrupting lockup_timeout on multi-GPU (v3) drm/amd/display: Do not skip unrelated mode changes in DSC validation drm/xe/pf: Fix use-after-free in migration restore ...
2 parents 335c901 + 5ba61d8 commit 26df51a

37 files changed

Lines changed: 313 additions & 117 deletions

MAINTAINERS

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8628,8 +8628,14 @@ F: drivers/gpu/drm/lima/
86288628
F: include/uapi/drm/lima_drm.h
86298629

86308630
DRM DRIVERS FOR LOONGSON
8631+
M: Jianmin Lv <[email protected]>
8632+
M: Qianhai Wu <[email protected]>
8633+
R: Huacai Chen <[email protected]>
8634+
R: Mingcong Bai <[email protected]>
8635+
R: Xi Ruoyao <[email protected]>
8636+
R: Icenowy Zheng <[email protected]>
86318637
8632-
S: Orphan
8638+
S: Maintained
86338639
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
86348640
F: drivers/gpu/drm/loongson/
86358641

drivers/accel/ivpu/ivpu_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define IVPU_HW_IP_60XX 60
3636

3737
#define IVPU_HW_IP_REV_LNL_B0 4
38+
#define IVPU_HW_IP_REV_NVL_A0 0
3839

3940
#define IVPU_HW_BTRS_MTL 1
4041
#define IVPU_HW_BTRS_LNL 2

drivers/accel/ivpu/ivpu_hw.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ static void wa_init(struct ivpu_device *vdev)
7070
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
7171
vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);
7272

73-
if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
74-
ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0)
73+
if ((ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
74+
ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0) ||
75+
(ivpu_device_id(vdev) == PCI_DEVICE_ID_NVL &&
76+
ivpu_revision(vdev) == IVPU_HW_IP_REV_NVL_A0))
7577
vdev->wa.disable_clock_relinquish = true;
7678

7779
if (ivpu_test_mode & IVPU_TEST_MODE_CLK_RELINQ_ENABLE)

drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,9 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
692692
goto err_ib_sched;
693693
}
694694

695-
/* Drop the initial kref_init count (see drm_sched_main as example) */
696-
dma_fence_put(f);
697695
ret = dma_fence_wait(f, false);
696+
/* Drop the returned fence reference after the wait completes */
697+
dma_fence_put(f);
698698

699699
err_ib_sched:
700700
amdgpu_job_free(job);

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4207,7 +4207,8 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work)
42074207

42084208
static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
42094209
{
4210-
char *input = amdgpu_lockup_timeout;
4210+
char buf[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
4211+
char *input = buf;
42114212
char *timeout_setting = NULL;
42124213
int index = 0;
42134214
long timeout;
@@ -4217,9 +4218,17 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
42174218
adev->gfx_timeout = adev->compute_timeout = adev->sdma_timeout =
42184219
adev->video_timeout = msecs_to_jiffies(2000);
42194220

4220-
if (!strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
4221+
if (!strnlen(amdgpu_lockup_timeout, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
42214222
return 0;
42224223

4224+
/*
4225+
* strsep() destructively modifies its input by replacing delimiters
4226+
* with '\0'. Use a stack copy so the global module parameter buffer
4227+
* remains intact for multi-GPU systems where this function is called
4228+
* once per device.
4229+
*/
4230+
strscpy(buf, amdgpu_lockup_timeout, sizeof(buf));
4231+
42234232
while ((timeout_setting = strsep(&input, ",")) &&
42244233
strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
42254234
ret = kstrtol(timeout_setting, 0, &timeout);

drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@
3535
* PASIDs are global address space identifiers that can be shared
3636
* between the GPU, an IOMMU and the driver. VMs on different devices
3737
* may use the same PASID if they share the same address
38-
* space. Therefore PASIDs are allocated using a global IDA. VMs are
39-
* looked up from the PASID per amdgpu_device.
38+
* space. Therefore PASIDs are allocated using IDR cyclic allocator
39+
* (similar to kernel PID allocation) which naturally delays reuse.
40+
* VMs are looked up from the PASID per amdgpu_device.
4041
*/
41-
static DEFINE_IDA(amdgpu_pasid_ida);
42+
43+
static DEFINE_IDR(amdgpu_pasid_idr);
44+
static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock);
4245

4346
/* Helper to free pasid from a fence callback */
4447
struct amdgpu_pasid_cb {
@@ -50,23 +53,24 @@ struct amdgpu_pasid_cb {
5053
* amdgpu_pasid_alloc - Allocate a PASID
5154
* @bits: Maximum width of the PASID in bits, must be at least 1
5255
*
53-
* Allocates a PASID of the given width while keeping smaller PASIDs
54-
* available if possible.
56+
* Uses kernel's IDR cyclic allocator (same as PID allocation).
57+
* Allocates sequentially with automatic wrap-around.
5558
*
5659
* Returns a positive integer on success. Returns %-EINVAL if bits==0.
5760
* Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
5861
* memory allocation failure.
5962
*/
6063
int amdgpu_pasid_alloc(unsigned int bits)
6164
{
62-
int pasid = -EINVAL;
65+
int pasid;
6366

64-
for (bits = min(bits, 31U); bits > 0; bits--) {
65-
pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1),
66-
(1U << bits) - 1, GFP_KERNEL);
67-
if (pasid != -ENOSPC)
68-
break;
69-
}
67+
if (bits == 0)
68+
return -EINVAL;
69+
70+
spin_lock(&amdgpu_pasid_idr_lock);
71+
pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
72+
1U << bits, GFP_KERNEL);
73+
spin_unlock(&amdgpu_pasid_idr_lock);
7074

7175
if (pasid >= 0)
7276
trace_amdgpu_pasid_allocated(pasid);
@@ -81,7 +85,10 @@ int amdgpu_pasid_alloc(unsigned int bits)
8185
void amdgpu_pasid_free(u32 pasid)
8286
{
8387
trace_amdgpu_pasid_freed(pasid);
84-
ida_free(&amdgpu_pasid_ida, pasid);
88+
89+
spin_lock(&amdgpu_pasid_idr_lock);
90+
idr_remove(&amdgpu_pasid_idr, pasid);
91+
spin_unlock(&amdgpu_pasid_idr_lock);
8592
}
8693

8794
static void amdgpu_pasid_free_cb(struct dma_fence *fence,
@@ -616,3 +623,15 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
616623
}
617624
}
618625
}
626+
627+
/**
628+
* amdgpu_pasid_mgr_cleanup - cleanup PASID manager
629+
*
630+
* Cleanup the IDR allocator.
631+
*/
632+
void amdgpu_pasid_mgr_cleanup(void)
633+
{
634+
spin_lock(&amdgpu_pasid_idr_lock);
635+
idr_destroy(&amdgpu_pasid_idr);
636+
spin_unlock(&amdgpu_pasid_idr_lock);
637+
}

drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ int amdgpu_pasid_alloc(unsigned int bits);
7474
void amdgpu_pasid_free(u32 pasid);
7575
void amdgpu_pasid_free_delayed(struct dma_resv *resv,
7676
u32 pasid);
77+
void amdgpu_pasid_mgr_cleanup(void);
7778

7879
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
7980
struct amdgpu_vmid *id);

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2898,6 +2898,7 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
28982898
xa_destroy(&adev->vm_manager.pasids);
28992899

29002900
amdgpu_vmid_mgr_fini(adev);
2901+
amdgpu_pasid_mgr_cleanup();
29012902
}
29022903

29032904
/**
@@ -2973,14 +2974,14 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
29732974
if (!root)
29742975
return false;
29752976

2976-
addr /= AMDGPU_GPU_PAGE_SIZE;
2977-
29782977
if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid,
2979-
node_id, addr, ts, write_fault)) {
2978+
node_id, addr >> PAGE_SHIFT, ts, write_fault)) {
29802979
amdgpu_bo_unref(&root);
29812980
return true;
29822981
}
29832982

2983+
addr /= AMDGPU_GPU_PAGE_SIZE;
2984+
29842985
r = amdgpu_bo_reserve(root, true);
29852986
if (r)
29862987
goto error_unref;

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3170,11 +3170,11 @@ static int kfd_ioctl_create_process(struct file *filep, struct kfd_process *p, v
31703170
struct kfd_process *process;
31713171
int ret;
31723172

3173-
/* Each FD owns only one kfd_process */
3174-
if (p->context_id != KFD_CONTEXT_ID_PRIMARY)
3173+
if (!filep->private_data || !p)
31753174
return -EINVAL;
31763175

3177-
if (!filep->private_data || !p)
3176+
/* Each FD owns only one kfd_process */
3177+
if (p->context_id != KFD_CONTEXT_ID_PRIMARY)
31783178
return -EINVAL;
31793179

31803180
mutex_lock(&kfd_processes_mutex);

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,8 +3909,9 @@ void amdgpu_dm_update_connector_after_detect(
39093909

39103910
aconnector->dc_sink = sink;
39113911
dc_sink_retain(aconnector->dc_sink);
3912+
drm_edid_free(aconnector->drm_edid);
3913+
aconnector->drm_edid = NULL;
39123914
if (sink->dc_edid.length == 0) {
3913-
aconnector->drm_edid = NULL;
39143915
hdmi_cec_unset_edid(aconnector);
39153916
if (aconnector->dc_link->aux_mode) {
39163917
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
@@ -5422,7 +5423,7 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm,
54225423
caps = &dm->backlight_caps[aconnector->bl_idx];
54235424

54245425
/* Only offer ABM property when non-OLED and user didn't turn off by module parameter */
5425-
if (!caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
5426+
if (caps->ext_caps && !caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
54265427
drm_object_attach_property(&aconnector->base.base,
54275428
dm->adev->mode_info.abm_level_property,
54285429
ABM_SYSFS_CONTROL);
@@ -12523,6 +12524,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
1252312524
}
1252412525

1252512526
if (dc_resource_is_dsc_encoding_supported(dc)) {
12527+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
12528+
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
12529+
dm_new_crtc_state->mode_changed_independent_from_dsc = new_crtc_state->mode_changed;
12530+
}
12531+
1252612532
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1252712533
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1252812534
ret = add_affected_mst_dsc_crtcs(state, crtc);

0 commit comments

Comments
 (0)