Skip to content

Commit 973fd94

Browse files
committed
Merge tag 'amd-drm-fixes-7.2-2026-07-17' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-7.2-2026-07-17: amdgpu: - DCN 4.2 fixes - NUTMEG fixes - 8K panel fix - Backlight fixes - UserQ fix - Fix bo->pin leaking in amdgpu_bo_create_reserved() - VFCT fixes - devcoredump fixes - Display fixes - SMU7 DPM fix - AC/DC fixes for SMU7 and SI - Queue reset fix - PCIe DPM fix - XHCI/GPU resume ordering fix - Pageflip timeout fix amdkfd: - Fix potential overflow in CWSR size calculation - DQM error clean up fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260717215008.998399-1-alexander.deucher@amd.com
2 parents 5554e05 + f39283e commit 973fd94

31 files changed

Lines changed: 720 additions & 431 deletions

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

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -372,19 +372,59 @@ static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev)
372372
}
373373

374374
#ifdef CONFIG_ACPI
375+
/**
376+
* amdgpu_acpi_vfct_match() - Check if a VFCT entry matches the device
377+
* @adev: AMDGPU device
378+
* @vhdr: VFCT image header to check
379+
*
380+
* VFCT entries contain the PCI bus number as recorded during BIOS POST.
381+
* On systems where the kernel renumbers PCI buses (e.g. pci=realloc or
382+
* resource conflicts), the runtime bus number may differ from the POST
383+
* value. Match by device identity (vendor + device + function) and use
384+
* the bus number as a preference: exact bus match is preferred, but when
385+
* the bus numbers disagree we accept the entry if the device identity
386+
* matches.
387+
*
388+
* Returns: 0 on match, -ENODEV on no match
389+
*/
390+
static int amdgpu_acpi_vfct_match(struct amdgpu_device *adev,
391+
VFCT_IMAGE_HEADER *vhdr)
392+
{
393+
/* Vendor and device IDs must always match */
394+
if (vhdr->VendorID != adev->pdev->vendor ||
395+
vhdr->DeviceID != adev->pdev->device)
396+
return -ENODEV;
397+
398+
if (vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) ||
399+
vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn))
400+
return -ENODEV;
401+
402+
/* Exact bus number match - preferred */
403+
if (vhdr->PCIBus == adev->pdev->bus->number)
404+
return 0;
405+
406+
/* Bus mismatch but device identity matches (PCI renumbering case) */
407+
dev_notice(adev->dev,
408+
"VFCT bus number mismatch: table %u != runtime %u, matching by device identity (vendor 0x%04x device 0x%04x)\n",
409+
vhdr->PCIBus, adev->pdev->bus->number,
410+
adev->pdev->vendor, adev->pdev->device);
411+
return 0;
412+
}
413+
375414
static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
376415
{
377416
struct acpi_table_header *hdr;
378417
acpi_size tbl_size;
379418
UEFI_ACPI_VFCT *vfct;
380419
unsigned int offset;
420+
bool r = false;
381421

382422
if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
383423
return false;
384424
tbl_size = hdr->length;
385425
if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
386426
dev_info(adev->dev, "ACPI VFCT table present but broken (too short #1),skipping\n");
387-
return false;
427+
goto out;
388428
}
389429

390430
vfct = (UEFI_ACPI_VFCT *)hdr;
@@ -397,36 +437,36 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
397437
offset += sizeof(VFCT_IMAGE_HEADER);
398438
if (offset > tbl_size) {
399439
dev_info(adev->dev, "ACPI VFCT image header truncated,skipping\n");
400-
return false;
440+
goto out;
401441
}
402442

403443
offset += vhdr->ImageLength;
404444
if (offset > tbl_size) {
405445
dev_info(adev->dev, "ACPI VFCT image truncated,skipping\n");
406-
return false;
446+
goto out;
407447
}
408448

409449
if (vhdr->ImageLength &&
410-
vhdr->PCIBus == adev->pdev->bus->number &&
411-
vhdr->PCIDevice == PCI_SLOT(adev->pdev->devfn) &&
412-
vhdr->PCIFunction == PCI_FUNC(adev->pdev->devfn) &&
413-
vhdr->VendorID == adev->pdev->vendor &&
414-
vhdr->DeviceID == adev->pdev->device) {
450+
!amdgpu_acpi_vfct_match(adev, vhdr)) {
415451
adev->bios = kmemdup(&vbios->VbiosContent,
416452
vhdr->ImageLength,
417453
GFP_KERNEL);
418454

419455
if (!check_atom_bios(adev, vhdr->ImageLength)) {
420456
amdgpu_bios_release(adev);
421-
return false;
457+
goto out;
422458
}
423459
adev->bios_size = vhdr->ImageLength;
424-
return true;
460+
r = true;
461+
goto out;
425462
}
426463
}
427464

428465
dev_info(adev->dev, "ACPI VFCT table present but broken (too short #2),skipping\n");
429-
return false;
466+
467+
out:
468+
acpi_put_table(hdr);
469+
return r;
430470
}
431471
#else
432472
static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ amdgpu_devcoredump_print_ibs(struct drm_printer *p,
234234
drm_printf(p, "\nIB #%d 0x%llx %d dw\n", i,
235235
coredump->ibs[i].gpu_addr,
236236
coredump->ibs[i].ib_size_dw);
237+
238+
for (int j = 0; j < coredump->ibs[i].ib_size_dw; j++)
239+
drm_printf(p, "0xffffffff\n");
237240
}
238241
return;
239242
}
@@ -355,10 +358,14 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
355358
drm_printf(&p, "kernel: %s\n", init_utsname()->release);
356359
drm_printf(&p, "module: " KBUILD_MODNAME "\n");
357360
drm_printf(&p, "time: %ptSp\n", &coredump->reset_time);
361+
drm_printf(&p, "pasid: %u\n", coredump->pasid);
362+
drm_printf(&p, "vmid: %u\n", coredump->vmid);
358363

359364
if (coredump->reset_task_info.task.pid)
360-
drm_printf(&p, "process_name: %s PID: %d\n",
365+
drm_printf(&p, "process_name: %s TGID: %d thread: %s PID: %d\n",
361366
coredump->reset_task_info.process_name,
367+
coredump->reset_task_info.tgid,
368+
coredump->reset_task_info.task.comm,
362369
coredump->reset_task_info.task.pid);
363370

364371
/* SOC Information */
@@ -562,6 +569,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
562569
amdgpu_vm_put_task_info(ti);
563570
}
564571
coredump->pasid = job->pasid;
572+
coredump->vmid = job->vmid;
565573
coredump->num_ibs = job->num_ibs;
566574
for (i = 0; i < job->num_ibs; ++i) {
567575
coredump->ibs[i].gpu_addr = job->ibs[i].gpu_addr;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct amdgpu_coredump_info {
6363
char *formatted;
6464

6565
unsigned int pasid;
66+
unsigned int vmid;
6667
int num_ibs;
6768
struct amdgpu_coredump_ib_info ibs[] __counted_by(num_ibs);
6869
};

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,15 @@ static bool amdgpu_device_pcie_dynamic_switching_supported(struct amdgpu_device
13231323

13241324
if (c->x86_vendor == X86_VENDOR_INTEL)
13251325
return false;
1326+
1327+
/*
1328+
* AMD Ryzen Pinnacle Ridge (Zen+, family 0x17 model 0x08) CPUs don't
1329+
* support PCIe dynamic speed switching.
1330+
* https://gitlab.freedesktop.org/drm/amd/-/work_items/5436
1331+
*/
1332+
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 0x17 &&
1333+
c->x86_model == 0x08)
1334+
return false;
13261335
#endif
13271336
return true;
13281337
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3137,9 +3137,11 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
31373137
case IP_VERSION(11, 5, 3):
31383138
case IP_VERSION(11, 5, 4):
31393139
case IP_VERSION(11, 5, 6):
3140+
adev->family = AMDGPU_FAMILY_GC_11_5_0;
3141+
break;
31403142
case IP_VERSION(11, 7, 0):
31413143
case IP_VERSION(11, 7, 1):
3142-
adev->family = AMDGPU_FAMILY_GC_11_5_0;
3144+
adev->family = AMDGPU_FAMILY_GC_11_5_4;
31433145
break;
31443146
case IP_VERSION(12, 0, 0):
31453147
case IP_VERSION(12, 0, 1):

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,12 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
276276
goto error_free;
277277
}
278278

279-
r = amdgpu_bo_pin(*bo_ptr, domain);
280-
if (r) {
281-
dev_err(adev->dev, "(%d) kernel bo pin failed\n", r);
282-
goto error_unreserve;
279+
if (free) {
280+
r = amdgpu_bo_pin(*bo_ptr, domain);
281+
if (r) {
282+
dev_err(adev->dev, "(%d) kernel bo pin failed\n", r);
283+
goto error_unreserve;
284+
}
283285
}
284286

285287
r = amdgpu_ttm_alloc_gart(&(*bo_ptr)->tbo);
@@ -302,7 +304,8 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
302304
return 0;
303305

304306
error_unpin:
305-
amdgpu_bo_unpin(*bo_ptr);
307+
if (free)
308+
amdgpu_bo_unpin(*bo_ptr);
306309
error_unreserve:
307310
amdgpu_bo_unreserve(*bo_ptr);
308311

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,12 +2684,22 @@ void amdgpu_sdma_set_buffer_funcs_scheds(struct amdgpu_device *adev,
26842684
return;
26852685
}
26862686

2687-
/* Navi1x's workaround requires us to limit to a single SDMA sched
2688-
* for ttm.
2689-
*/
26902687
hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
2691-
adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
2692-
1 : n;
2688+
2689+
/*
2690+
* Allow using multiple SDMA schedulers only on GPUs where
2691+
* we are allowed to do concurrent VM flushes.
2692+
* This consideration is necessary because all GART windows
2693+
* are mapped in VMID 0 (the kernel VMID) so each buffer
2694+
* entity would flush VMID 0 concurrently.
2695+
*
2696+
* Also consider the SDMA invalidation workaround on
2697+
* Navi 1x GPUs, which also prevents us from using
2698+
* multiple SDMA engines on VMID 0 at the same time.
2699+
*/
2700+
adev->mman.num_buffer_funcs_scheds =
2701+
(adev->vm_manager.concurrent_flush &&
2702+
!hub->sdma_invalidation_workaround) ? n : 1;
26932703
}
26942704

26952705
#if defined(CONFIG_DEBUG_FS)

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,16 +1376,19 @@ void amdgpu_userq_pre_reset(struct amdgpu_device *adev)
13761376

13771377
/* TODO: We probably need a new lock for the queue state */
13781378
xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) {
1379-
if (queue->state != AMDGPU_USERQ_STATE_MAPPED)
1380-
continue;
1381-
1382-
userq_funcs = adev->userq_funcs[queue->queue_type];
1383-
userq_funcs->unmap(queue);
1384-
/* just mark all queues as hung at this point.
1385-
* if unmap succeeds, we could map again
1386-
* in amdgpu_userq_post_reset() if vram is not lost
1379+
if (queue->state == AMDGPU_USERQ_STATE_MAPPED) {
1380+
userq_funcs = adev->userq_funcs[queue->queue_type];
1381+
userq_funcs->unmap(queue);
1382+
/* just mark all queues as hung at this point.
1383+
* if unmap succeeds, we could map again
1384+
* in amdgpu_userq_post_reset() if vram is not lost
1385+
*/
1386+
queue->state = AMDGPU_USERQ_STATE_HUNG;
1387+
}
1388+
/* Force-complete any pending fence regardless of queue state so
1389+
* that eviction/suspend and queue teardown waiters don't block
1390+
* forever on a fence that will never signal after the reset.
13871391
*/
1388-
queue->state = AMDGPU_USERQ_STATE_HUNG;
13891392
amdgpu_userq_fence_driver_force_completion(queue);
13901393
}
13911394
}

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -855,12 +855,10 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
855855
job->oa_size);
856856
}
857857

858-
if (vm_flush_needed || pasid_mapping_needed || cleaner_shader_needed) {
859-
amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
860-
fence = &job->hw_vm_fence->base;
861-
/* get a ref for the job */
862-
dma_fence_get(fence);
863-
}
858+
amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
859+
fence = &job->hw_vm_fence->base;
860+
/* get a ref for the job */
861+
dma_fence_get(fence);
864862

865863
if (vm_flush_needed) {
866864
mutex_lock(&id_mgr->lock);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,6 +3103,7 @@ static void deallocate_hiq_sdma_mqd(struct kfd_node *dev,
31033103
struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
31043104
{
31053105
struct device_queue_manager *dqm;
3106+
int i;
31063107

31073108
pr_debug("Loading device queue manager\n");
31083109

@@ -3231,6 +3232,9 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
32313232
deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd);
32323233

32333234
out_free:
3235+
for (i = 0; i < KFD_MQD_TYPE_MAX; i++)
3236+
kfree(dqm->mqd_mgrs[i]);
3237+
32343238
kfree(dqm);
32353239
return NULL;
32363240
}

0 commit comments

Comments
 (0)