summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-06-08 12:56:59 +0300
committerDave Airlie <airlied@redhat.com>2026-06-08 12:57:35 +0300
commit5ea194bc25518376dee1209e64d32f940dd0cc4c (patch)
tree975b13af0636f851b77fbd7057a7b0d20651f6fa /drivers/gpu
parent8205c61deb6e5c1cabaf02415337070f3ca1ea19 (diff)
parent56ae73c92e200e630c2bdf1e98c88b86c8483b37 (diff)
downloadlinux-5ea194bc25518376dee1209e64d32f940dd0cc4c.tar.xz
Merge tag 'amd-drm-next-7.2-2026-06-04' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-7.2-2026-06-04: amdgpu: - UserQ fix - Userptr fix - MCCS freesync fix - Remove some triggerable BUG() calls - DCN 4.2.1 fixes - Lockdep annotations - Guilty handling fix - VCN 5.3 fix - FRL fixes - Bounds checking fixes - HMM fix - IRQ accounting fix amdkfd: - Fix an event information leak - Events bounds check fix - Trap cleanup fix - Bounds checking fixes - MES fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260604231801.19979-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c195
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.h39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c43
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c162
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c162
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c114
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c35
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v11_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v12_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v12_1.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c39
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_debug.c6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c20
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c14
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hpo/dcn401/dcn401_hpo_frl_stream_encoder.c4
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_asic_id.h4
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c20
39 files changed, 716 insertions, 309 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index ee3574797bc2..ba80542ead9d 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -69,7 +69,7 @@ amdgpu-y += amdgpu_device.o amdgpu_reg_access.o amdgpu_doorbell_mgr.o amdgpu_kms
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
- amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
+ amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o amdgpu_lockdep.o \
amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o amdgpu_dev_coredump.o \
amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 5d7bfa59424a..7b09410d6d8f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -105,6 +105,7 @@
#include "amdgpu_mca.h"
#include "amdgpu_aca.h"
#include "amdgpu_ras.h"
+#include "amdgpu_lockdep.h"
#include "amdgpu_cper.h"
#include "amdgpu_xcp.h"
#include "amdgpu_seq64.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 6ada57abce9d..115b134b4cd1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -60,11 +60,6 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
if (!p->ctx)
return -EINVAL;
- if (atomic_read(&p->ctx->guilty)) {
- amdgpu_ctx_put(p->ctx);
- return -ECANCELED;
- }
-
amdgpu_sync_create(&p->sync);
drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
DRM_EXEC_IGNORE_DUPLICATES, 0);
@@ -1277,6 +1272,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_job *leader = p->gang_leader;
+ struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_bo_list_entry *e;
struct drm_gem_object *gobj;
unsigned int i;
@@ -1321,7 +1317,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_hmm_range_free(e->range);
e->range = NULL;
}
- if (r) {
+
+ if (r || !list_empty(&vm->individual.moved)) {
r = -EAGAIN;
mutex_unlock(&p->adev->notifier_lock);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 7af86a32c0c5..0d7f6cd74f79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -255,7 +255,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
}
r = drm_sched_entity_init(&entity->entity, drm_prio, scheds, num_scheds,
- &ctx->guilty);
+ NULL);
if (r)
goto error_free_entity;
@@ -579,6 +579,27 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
#define AMDGPU_RAS_COUNTE_DELAY_MS 3000
+static bool amdgpu_ctx_guilty(struct amdgpu_ctx *ctx)
+{
+ int i, j, r;
+
+ for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+ for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+ struct amdgpu_ctx_entity *ctx_entity;
+
+ ctx_entity = ctx->entities[i][j];
+ if (!ctx_entity)
+ continue;
+
+ r = drm_sched_entity_error(&ctx_entity->entity);
+ if (r == -ETIME)
+ return true;
+ }
+ }
+
+ return false;
+}
+
static int amdgpu_ctx_query2(struct amdgpu_device *adev,
struct amdgpu_fpriv *fpriv, uint32_t id,
union drm_amdgpu_ctx_out *out)
@@ -607,7 +628,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
if (ctx->generation != amdgpu_vm_generation(adev, &fpriv->vm))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
- if (atomic_read(&ctx->guilty))
+ if (amdgpu_ctx_guilty(ctx))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
if (amdgpu_in_reset(adev))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
index cf8d700a22fe..e444b2088d40 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
@@ -50,7 +50,6 @@ struct amdgpu_ctx {
int32_t init_priority;
int32_t override_priority;
uint32_t stable_pstate;
- atomic_t guilty;
bool preamble_presented;
uint64_t generation;
unsigned long ras_counter_ce;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d2d70c4b2ac5..942f0251c748 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -717,7 +717,12 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return;
- BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
+ if (!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4)) {
+ dev_err(adev->dev, "unaligned pos/size (pos=0x%llx, size=0x%zx)\n",
+ pos, size);
+ drm_dev_exit(idx);
+ return;
+ }
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
for (last = pos + size; pos < last; pos += 4) {
@@ -3752,6 +3757,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->pm.stable_pstate_ctx_lock);
mutex_init(&adev->benchmark_mutex);
mutex_init(&adev->gfx.reset_sem_mutex);
+
+ /* Associate locks with lockdep classes for ordering validation */
+ amdgpu_lockdep_set_class(adev);
/* Initialize the mutex for cleaner shader isolation between GFX and compute processes */
mutex_init(&adev->enforce_isolation_mutex);
for (i = 0; i < MAX_XCP; ++i) {
@@ -5104,12 +5112,12 @@ link_reset_failed:
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
struct amdgpu_reset_context *reset_context)
{
- int i, r = 0;
struct amdgpu_job *job = NULL;
struct dma_fence *fence = NULL;
struct amdgpu_device *tmp_adev = reset_context->reset_req_dev;
bool need_full_reset =
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
+ int i, r;
if (reset_context->reset_req_dev == adev)
job = reset_context->job;
@@ -5135,9 +5143,6 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
amdgpu_fence_driver_isr_toggle(adev, false);
- if (job && job->vm)
- drm_sched_increase_karma(&job->base);
-
r = amdgpu_reset_prepare_hwcontext(adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -EOPNOTSUPP)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 1781c0c3d010..bf4260269681 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -3158,6 +3158,9 @@ static int __init amdgpu_init(void)
{
int r;
+ /* Train lockdep on correct lock ordering */
+ amdgpu_lockdep_init();
+
r = amdgpu_sync_init();
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
index e452444b33b0..99bc9ad67d5b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
@@ -174,7 +174,6 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
const u64 max_bytes = SZ_2G;
struct hmm_range *hmm_range = &range->hmm_range;
- unsigned long timeout;
unsigned long *pfns;
unsigned long end;
int r;
@@ -201,15 +200,9 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
pr_debug("hmm range: start = 0x%lx, end = 0x%lx",
hmm_range->start, hmm_range->end);
- timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
-
-retry:
r = hmm_range_fault(hmm_range);
- if (unlikely(r)) {
- if (r == -EBUSY && !time_after(jiffies, timeout))
- goto retry;
+ if (unlikely(r))
goto out_free_pfns;
- }
if (hmm_range->end == end)
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c
new file mode 100644
index 000000000000..d5d71fd7c70d
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2024 Advanced Micro Devices, Inc.
+ *
+ * Lockdep annotation for AMDGPU lock ordering
+ *
+ * This module teaches lockdep the correct lock ordering to catch
+ * potential deadlocks at development time rather than runtime.
+ *
+ * Based on dma-resv lockdep approach from:
+ * drivers/dma-buf/dma-resv.c:dma_resv_lockdep()
+ */
+
+#include "amdgpu.h"
+#include "amdgpu_reset.h"
+
+#ifdef CONFIG_LOCKDEP
+
+/* Lock class keys for associating with real driver locks */
+static struct lock_class_key amdgpu_userq_sch_mutex_key;
+static struct lock_class_key amdgpu_userq_mutex_key;
+static struct lock_class_key amdgpu_notifier_lock_key;
+static struct lock_class_key amdgpu_vram_lock_key;
+static struct lock_class_key amdgpu_reset_sem_key;
+static struct lock_class_key amdgpu_reset_lock_key;
+static struct lock_class_key amdgpu_srbm_lock_key;
+static struct lock_class_key amdgpu_grbm_lock_key;
+static struct lock_class_key amdgpu_mmio_lock_key;
+
+/**
+ * amdgpu_lockdep_set_class - Associate lock class keys with real locks
+ * @adev: AMDGPU device
+ *
+ * Call during device init to associate lock classes with actual locks
+ * so lockdep can track them properly.
+ */
+void amdgpu_lockdep_set_class(struct amdgpu_device *adev)
+{
+ lockdep_set_class(&adev->gfx.userq_sch_mutex,
+ &amdgpu_userq_sch_mutex_key);
+ lockdep_set_class(&adev->notifier_lock, &amdgpu_notifier_lock_key);
+ lockdep_set_class(&adev->srbm_mutex, &amdgpu_srbm_lock_key);
+ lockdep_set_class(&adev->grbm_idx_mutex, &amdgpu_grbm_lock_key);
+ lockdep_set_class(&adev->mmio_idx_lock, &amdgpu_mmio_lock_key);
+
+ if (adev->reset_domain)
+ lockdep_set_class(&adev->reset_domain->sem,
+ &amdgpu_reset_sem_key);
+}
+
+/**
+ * amdgpu_lockdep_init - Teach lockdep the correct lock ordering
+ *
+ * Instantiates dummy objects and takes locks in the correct order to
+ * train lockdep. This helps catch lock ordering violations during
+ * development.
+ *
+ * Lock ordering hierarchy (outermost to innermost):
+ *
+ * 1. userq_sch_mutex - Global userq scheduler (enforce_isolation)
+ * 2. userq_mutex - Per-context userq (held across queue create/destroy)
+ * 3. notifier_lock - MMU notifier lock
+ * 4. vram_lock - VRAM allocator lock
+ * 5. reset_domain->sem - GPU reset synchronization
+ * 6. reset_lock - Reset control lock
+ * 7. srbm_mutex - SRBM register access
+ * 8. grbm_idx_mutex - GRBM index access
+ * 9. mmio_idx_lock - MMIO index access (spinlock)
+ *
+ * Evidence:
+ * - userq_sch_mutex -> userq_mutex: amdgpu_gfx_kfd_sch_ctrl() calls
+ * amdgpu_userq_stop_sched_for_enforce_isolation() which takes userq_mutex
+ * - userq_mutex -> notifier_lock: userq paths may trigger MMU notifier
+ * invalidation which acquires notifier_lock
+ * - notifier_lock -> reset_domain->sem: HMM invalidation callback holds
+ * notifier_lock and can wait for GPU reset completion, so notifier_lock
+ * must be outer to reset_domain->sem
+ * - vram_lock -> reset_domain->sem: VRAM management paths may need to
+ * wait for ongoing reset to complete
+ *
+ * Note: mmap_lock ordering relative to GPU locks is already taught
+ * by dma-resv (drivers/dma-buf/dma-resv.c).
+ */
+int amdgpu_lockdep_init(void)
+{
+ struct amdgpu_reset_domain *reset_domain = NULL;
+ struct amdgpu_reset_control reset_ctl;
+ struct mutex userq_sch_mutex;
+ struct mutex userq_mutex;
+ struct mutex notifier_lock;
+ struct mutex vram_lock;
+ struct mutex srbm_mutex;
+ struct mutex grbm_idx_mutex;
+ spinlock_t mmio_idx_lock;
+ unsigned long flags;
+
+ /*
+ * Initialize dummy reset domain
+ */
+ reset_domain = amdgpu_reset_create_reset_domain(SINGLE_DEVICE,
+ "lockdep_test");
+ if (!reset_domain)
+ return -ENOMEM;
+
+ /* Initialize dummy locks */
+ mutex_init(&userq_sch_mutex);
+ mutex_init(&userq_mutex);
+ mutex_init(&notifier_lock);
+ mutex_init(&vram_lock);
+ mutex_init(&reset_ctl.reset_lock);
+ mutex_init(&srbm_mutex);
+ mutex_init(&grbm_idx_mutex);
+ spin_lock_init(&mmio_idx_lock);
+
+ /*
+ * Associate dummy locks with the same class keys used for real
+ * driver locks. This ensures lockdep connects the ordering learned
+ * here with the actual locks used at runtime.
+ */
+ lockdep_set_class(&userq_sch_mutex, &amdgpu_userq_sch_mutex_key);
+ lockdep_set_class(&userq_mutex, &amdgpu_userq_mutex_key);
+ lockdep_set_class(&notifier_lock, &amdgpu_notifier_lock_key);
+ lockdep_set_class(&vram_lock, &amdgpu_vram_lock_key);
+ lockdep_set_class(&reset_domain->sem, &amdgpu_reset_sem_key);
+ lockdep_set_class(&reset_ctl.reset_lock, &amdgpu_reset_lock_key);
+ lockdep_set_class(&srbm_mutex, &amdgpu_srbm_lock_key);
+ lockdep_set_class(&grbm_idx_mutex, &amdgpu_grbm_lock_key);
+ lockdep_set_class(&mmio_idx_lock, &amdgpu_mmio_lock_key);
+
+ /*
+ * Take locks in the correct order to train lockdep.
+ * This establishes the dependency chain.
+ */
+
+ /* Level 1: Global userq scheduler mutex (outermost) */
+ mutex_lock(&userq_sch_mutex);
+
+ /* Level 2: Per-context userq mutex */
+ mutex_lock(&userq_mutex);
+
+ /* Level 3: MMU notifier lock */
+ mutex_lock(&notifier_lock);
+
+ /* Level 4: VRAM allocator lock */
+ mutex_lock(&vram_lock);
+
+ /* Level 5: Reset domain semaphore */
+ down_read(&reset_domain->sem);
+
+ /* Level 6: Reset control lock */
+ mutex_lock(&reset_ctl.reset_lock);
+
+ /*
+ * Mark potential memory reclaim boundary.
+ * GPU operations might trigger memory allocation/reclaim.
+ */
+ fs_reclaim_acquire(GFP_KERNEL);
+
+ /* Level 7: SRBM register access */
+ mutex_lock(&srbm_mutex);
+
+ /* Level 8: GRBM index access */
+ mutex_lock(&grbm_idx_mutex);
+
+ /* Level 9: MMIO index access (innermost lock, spinlock) */
+ spin_lock_irqsave(&mmio_idx_lock, flags);
+
+ /*
+ * All locks acquired in order.
+ * Lockdep has now learned the valid dependency chain.
+ */
+
+ /* Release in reverse order */
+ spin_unlock_irqrestore(&mmio_idx_lock, flags);
+ mutex_unlock(&grbm_idx_mutex);
+ mutex_unlock(&srbm_mutex);
+
+ fs_reclaim_release(GFP_KERNEL);
+
+ mutex_unlock(&reset_ctl.reset_lock);
+ up_read(&reset_domain->sem);
+ mutex_unlock(&vram_lock);
+ mutex_unlock(&notifier_lock);
+ mutex_unlock(&userq_mutex);
+ mutex_unlock(&userq_sch_mutex);
+
+ /* Cleanup */
+ amdgpu_reset_put_reset_domain(reset_domain);
+
+ pr_info("AMDGPU: Lockdep annotations initialized (9 lock levels)\n");
+
+ return 0;
+}
+
+#endif /* CONFIG_LOCKDEP */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.h
new file mode 100644
index 000000000000..04adb58665bf
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2024 Advanced Micro Devices, Inc.
+ *
+ * Lockdep annotation interface for AMDGPU
+ */
+
+#ifndef __AMDGPU_LOCKDEP_H__
+#define __AMDGPU_LOCKDEP_H__
+
+#include <linux/lockdep.h>
+
+struct amdgpu_device;
+
+#ifdef CONFIG_LOCKDEP
+
+/**
+ * amdgpu_lockdep_init - Train lockdep on correct lock ordering
+ *
+ * Call once during module init to establish the lock dependency chain.
+ */
+int amdgpu_lockdep_init(void);
+
+/**
+ * amdgpu_lockdep_set_class - Associate lock class keys with real locks
+ * @adev: AMDGPU device
+ *
+ * Call during device init to associate lock classes with actual locks.
+ */
+void amdgpu_lockdep_set_class(struct amdgpu_device *adev);
+
+#else /* !CONFIG_LOCKDEP */
+
+static inline int amdgpu_lockdep_init(void) { return 0; }
+static inline void amdgpu_lockdep_set_class(struct amdgpu_device *adev) {}
+
+#endif /* CONFIG_LOCKDEP */
+
+#endif /* __AMDGPU_LOCKDEP_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index c9467b26e42c..e3972673fd64 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -781,6 +781,18 @@ out:
return r;
}
+void amdgpu_mes_validate_fw_version(struct amdgpu_device *adev)
+{
+ u32 fw_from_ucode = adev->mes.fw_version[AMDGPU_MES_SCHED_PIPE];
+ u32 fw_from_reg = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
+
+ if (fw_from_ucode != fw_from_reg)
+ dev_info(adev->dev,
+ "MES firmware reports incorrect version in ucode binary (0x%x vs 0x%x)\n",
+ fw_from_ucode, fw_from_reg);
+}
+
+
bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev)
{
uint32_t mes_rev = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index 93990d4990f2..fdd06a17520a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -441,6 +441,7 @@ struct amdgpu_mes_funcs {
(adev)->mes.kiq_hw_fini((adev), (xcc_id))
int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe);
+void amdgpu_mes_validate_fw_version(struct amdgpu_device *adev);
int amdgpu_mes_init(struct amdgpu_device *adev);
void amdgpu_mes_fini(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c
index daefbeeee4d2..7468855c16a2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c
@@ -406,7 +406,10 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
if (offset < adev->rmmio_size)
return (readb(adev->rmmio + offset));
- BUG();
+
+ dev_err(adev->dev, "invalid MMIO read offset 0x%x (rmmio size 0x%x)\n",
+ offset, (unsigned int)adev->rmmio_size);
+ return 0;
}
/**
@@ -469,10 +472,13 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
if (amdgpu_device_skip_hw_access(adev))
return;
- if (offset < adev->rmmio_size)
+ if (offset < adev->rmmio_size) {
writeb(value, adev->rmmio + offset);
- else
- BUG();
+ } else {
+ dev_err(adev->dev, "invalid MMIO write offset 0x%x (rmmio size 0x%x)\n",
+ offset, (unsigned int)adev->rmmio_size);
+ return;
+ }
}
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index a41fb72dba94..f74ad378e407 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -593,7 +593,7 @@ free_syncobj_handles:
static int
amdgpu_userq_wait_count_fences(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
- u32 *syncobj_handles, u32 *timeline_points,
+ u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@@ -703,7 +703,7 @@ amdgpu_userq_wait_add_fence(struct drm_amdgpu_userq_wait *wait_info,
static int
amdgpu_userq_wait_return_fence_info(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
- u32 *syncobj_handles, u32 *timeline_points,
+ u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@@ -906,7 +906,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
int num_points, num_syncobj, num_read_bo_handles, num_write_bo_handles;
- u32 *syncobj_handles, *timeline_points, *timeline_handles;
+ u32 *syncobj_handles, *timeline_handles;
+ u64 *timeline_points;
struct drm_amdgpu_userq_wait *wait_info = data;
struct drm_gem_object **gobj_write;
struct drm_gem_object **gobj_read;
@@ -935,7 +936,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
}
ptr = u64_to_user_ptr(wait_info->syncobj_timeline_points);
- timeline_points = memdup_array_user(ptr, num_points, sizeof(u32));
+ timeline_points = memdup_array_user(ptr, num_points, sizeof(u64));
if (IS_ERR(timeline_points)) {
r = PTR_ERR(timeline_points);
goto free_timeline_handles;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 58c69dcb527f..0780c5e5de4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -7530,6 +7530,24 @@ static int gfx_v10_0_hw_init(struct amdgpu_ip_block *ip_block)
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 3, 0) && !amdgpu_sriov_vf(adev))
gfx_v10_3_set_power_brake_sequence(adev);
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
+ if (r)
+ goto err_bad_op;
+
+ return 0;
+
+err_bad_op:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@@ -7539,9 +7557,9 @@ static int gfx_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
/* WA added for Vangogh asic fixing the SMU suspend failure
* It needs to set power gating again during gfxoff control
@@ -7837,26 +7855,6 @@ static int gfx_v10_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v10_0_init_microcode(adev);
}
-static int gfx_v10_0_late_init(struct amdgpu_ip_block *ip_block)
-{
- struct amdgpu_device *adev = ip_block->adev;
- int r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
- if (r)
- return r;
-
- return 0;
-}
-
static bool gfx_v10_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@@ -9805,7 +9803,6 @@ static void gfx_v10_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
.name = "gfx_v10_0",
.early_init = gfx_v10_0_early_init,
- .late_init = gfx_v10_0_late_init,
.sw_init = gfx_v10_0_sw_init,
.sw_fini = gfx_v10_0_sw_fini,
.hw_init = gfx_v10_0_hw_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 1941bfbcbfbf..f856b0cf5bec 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -4814,6 +4814,78 @@ static void gfx_v11_0_disable_gpa_mode(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCPG_PSP_DEBUG, data);
}
+static int gfx_v11_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
+ bool enable)
+{
+ unsigned int irq_type;
+ int m, p, r;
+
+ if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
+ for (m = 0; m < adev->gfx.me.num_me; m++) {
+ for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ if (enable)
+ r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
+ else
+ r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ if (r) {
+ if (!enable)
+ return r;
+ goto err_gfx;
+ }
+ }
+ }
+ }
+
+ if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
+ for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
+ for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec)
+ + p;
+ if (enable)
+ r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
+ else
+ r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ if (r) {
+ if (!enable)
+ return r;
+ goto err_compute;
+ }
+ }
+ }
+ }
+
+ return 0;
+
+err_compute:
+ for (p--; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ for (m--; m >= 0; m--) {
+ for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ }
+ m = adev->gfx.me.num_me;
+err_gfx:
+ for (p--; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ for (m--; m >= 0; m--) {
+ for (p = adev->gfx.me.num_pipe_per_me - 1; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ }
+ return r;
+}
+
static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
@@ -4911,50 +4983,31 @@ static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
if (!adev->gfx.imu_fw_version)
adev->gfx.imu_fw_version = RREG32_SOC15(GC, 0, regGFX_IMU_SCRATCH_0);
- return r;
-}
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
-static int gfx_v11_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
- bool enable)
-{
- unsigned int irq_type;
- int m, p, r;
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
- if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
- for (m = 0; m < adev->gfx.me.num_me; m++) {
- for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
- irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
- if (enable)
- r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
- irq_type);
- else
- r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
- irq_type);
- if (r)
- return r;
- }
- }
- }
+ r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
+ if (r)
+ goto err_bad_op;
- if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
- for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
- for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
- irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
- + (m * adev->gfx.mec.num_pipe_per_mec)
- + p;
- if (enable)
- r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
- irq_type);
- else
- r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
- irq_type);
- if (r)
- return r;
- }
- }
- }
+ r = gfx_v11_0_set_userq_eop_interrupts(adev, true);
+ if (r)
+ goto err_userq_eop;
return 0;
+
+err_userq_eop:
+ amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+err_bad_op:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
+ return r;
}
static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
@@ -4963,10 +5016,10 @@ static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
gfx_v11_0_set_userq_eop_interrupts(adev, false);
+ amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring &&
@@ -5356,30 +5409,6 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v11_0_init_microcode(adev);
}
-static int gfx_v11_0_late_init(struct amdgpu_ip_block *ip_block)
-{
- struct amdgpu_device *adev = ip_block->adev;
- int r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
- if (r)
- return r;
-
- r = gfx_v11_0_set_userq_eop_interrupts(adev, true);
- if (r)
- return r;
-
- return 0;
-}
-
static bool gfx_v11_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@@ -7211,7 +7240,6 @@ static void gfx_v11_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
.name = "gfx_v11_0",
.early_init = gfx_v11_0_early_init,
- .late_init = gfx_v11_0_late_init,
.sw_init = gfx_v11_0_sw_init,
.sw_fini = gfx_v11_0_sw_fini,
.hw_init = gfx_v11_0_hw_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index f47928dcd848..f66293fc675e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3655,6 +3655,78 @@ static void gfx_v12_0_init_golden_registers(struct amdgpu_device *adev)
}
}
+static int gfx_v12_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
+ bool enable)
+{
+ unsigned int irq_type;
+ int m, p, r;
+
+ if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
+ for (m = 0; m < adev->gfx.me.num_me; m++) {
+ for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ if (enable)
+ r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
+ else
+ r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ if (r) {
+ if (!enable)
+ return r;
+ goto err_gfx;
+ }
+ }
+ }
+ }
+
+ if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
+ for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
+ for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec)
+ + p;
+ if (enable)
+ r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
+ else
+ r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ if (r) {
+ if (!enable)
+ return r;
+ goto err_compute;
+ }
+ }
+ }
+ }
+
+ return 0;
+
+err_compute:
+ for (p--; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ for (m--; m >= 0; m--) {
+ for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ }
+ m = adev->gfx.me.num_me;
+err_gfx:
+ for (p--; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ for (m--; m >= 0; m--) {
+ for (p = adev->gfx.me.num_pipe_per_me - 1; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ }
+ return r;
+}
+
static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
@@ -3742,50 +3814,31 @@ static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- return r;
-}
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
-static int gfx_v12_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
- bool enable)
-{
- unsigned int irq_type;
- int m, p, r;
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
- if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
- for (m = 0; m < adev->gfx.me.num_me; m++) {
- for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
- irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
- if (enable)
- r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
- irq_type);
- else
- r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
- irq_type);
- if (r)
- return r;
- }
- }
- }
+ r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
+ if (r)
+ goto err_bad_op;
- if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
- for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
- for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
- irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
- + (m * adev->gfx.mec.num_pipe_per_mec)
- + p;
- if (enable)
- r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
- irq_type);
- else
- r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
- irq_type);
- if (r)
- return r;
- }
- }
- }
+ r = gfx_v12_0_set_userq_eop_interrupts(adev, true);
+ if (r)
+ goto err_userq_eop;
return 0;
+
+err_userq_eop:
+ amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+err_bad_op:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
+ return r;
}
static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
@@ -3795,10 +3848,10 @@ static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
gfx_v12_0_set_userq_eop_interrupts(adev, false);
+ amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring) {
@@ -3927,30 +3980,6 @@ static int gfx_v12_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v12_0_init_microcode(adev);
}
-static int gfx_v12_0_late_init(struct amdgpu_ip_block *ip_block)
-{
- struct amdgpu_device *adev = ip_block->adev;
- int r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
- if (r)
- return r;
-
- r = gfx_v12_0_set_userq_eop_interrupts(adev, true);
- if (r)
- return r;
-
- return 0;
-}
-
static bool gfx_v12_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@@ -5440,7 +5469,6 @@ static void gfx_v12_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v12_0_ip_funcs = {
.name = "gfx_v12_0",
.early_init = gfx_v12_0_early_init,
- .late_init = gfx_v12_0_late_init,
.sw_init = gfx_v12_0_sw_init,
.sw_fini = gfx_v12_0_sw_fini,
.hw_init = gfx_v12_0_hw_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
index 033f15e21ad3..61c3577f829f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
@@ -2735,6 +2735,50 @@ static void gfx_v12_1_init_golden_registers(struct amdgpu_device *adev)
}
}
+static int gfx_v12_1_set_userq_eop_interrupts(struct amdgpu_device *adev,
+ bool enable)
+{
+ unsigned int irq_type;
+ int m, p, r;
+
+ if (!adev->gfx.disable_kq)
+ return 0;
+
+ for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
+ for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec)
+ + p;
+ if (enable)
+ r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
+ else
+ r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ if (r) {
+ if (!enable)
+ return r;
+ goto err_unwind;
+ }
+ }
+ }
+
+ return 0;
+
+err_unwind:
+ for (p--; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ for (m--; m >= 0; m--) {
+ for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
+ irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ + (m * adev->gfx.mec.num_pipe_per_mec) + p;
+ amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
+ }
+ }
+ return r;
+}
+
static int gfx_v12_1_hw_init(struct amdgpu_ip_block *ip_block)
{
int r, i, num_xcc;
@@ -2803,6 +2847,24 @@ static int gfx_v12_1_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
+
+ r = gfx_v12_1_set_userq_eop_interrupts(adev, true);
+ if (r)
+ goto err_userq_eop;
+
+ return 0;
+
+err_userq_eop:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@@ -2828,41 +2890,14 @@ static void gfx_v12_1_xcc_fini(struct amdgpu_device *adev,
gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);
}
-static int gfx_v12_1_set_userq_eop_interrupts(struct amdgpu_device *adev,
- bool enable)
-{
- unsigned int irq_type;
- int m, p, r;
-
- if (adev->gfx.disable_kq) {
- for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
- for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
- irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
- + (m * adev->gfx.mec.num_pipe_per_mec)
- + p;
- if (enable)
- r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
- irq_type);
- else
- r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
- irq_type);
- if (r)
- return r;
- }
- }
- }
-
- return 0;
-}
-
static int gfx_v12_1_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int i, num_xcc;
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
gfx_v12_1_set_userq_eop_interrupts(adev, false);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
for (i = 0; i < num_xcc; i++) {
@@ -2963,26 +2998,6 @@ static int gfx_v12_1_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v12_1_init_microcode(adev);
}
-static int gfx_v12_1_late_init(struct amdgpu_ip_block *ip_block)
-{
- struct amdgpu_device *adev = ip_block->adev;
- int r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = gfx_v12_1_set_userq_eop_interrupts(adev, true);
- if (r)
- return r;
-
- return 0;
-}
-
static bool gfx_v12_1_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@@ -3876,7 +3891,6 @@ static void gfx_v12_1_emit_mem_sync(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v12_1_ip_funcs = {
.name = "gfx_v12_1",
.early_init = gfx_v12_1_early_init,
- .late_init = gfx_v12_1_late_init,
.sw_init = gfx_v12_1_sw_init,
.sw_fini = gfx_v12_1_sw_fini,
.hw_init = gfx_v12_1_hw_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 60376d43e81d..47721d0c3781 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -4050,6 +4050,24 @@ static int gfx_v9_0_hw_init(struct amdgpu_ip_block *ip_block)
!amdgpu_sriov_vf(adev))
gfx_v9_4_2_set_power_brake_sequence(adev);
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
+ if (r)
+ goto err_bad_op;
+
+ return 0;
+
+err_bad_op:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@@ -4057,9 +4075,9 @@ static int gfx_v9_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
/* DF freeze and kcq disable will fail */
if (!amdgpu_ras_intr_triggered())
@@ -4860,18 +4878,6 @@ static int gfx_v9_0_late_init(struct amdgpu_ip_block *ip_block)
struct amdgpu_device *adev = ip_block->adev;
int r;
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
- if (r)
- return r;
-
r = gfx_v9_0_ecc_late_init(ip_block);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 9f76e1af8a55..510266ba0c38 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -2371,6 +2371,24 @@ static int gfx_v9_4_3_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
+ if (r)
+ return r;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
+ if (r)
+ goto err_priv_inst;
+
+ r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
+ if (r)
+ goto err_bad_op;
+
+ return 0;
+
+err_bad_op:
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+err_priv_inst:
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@@ -2446,9 +2464,9 @@ static int gfx_v9_4_3_hw_fini(struct amdgpu_ip_block *ip_block)
if (adev->psp.ptl.hw_supported && !amdgpu_in_reset(adev))
gfx_v9_4_3_perf_monitor_ptl_init(adev, false);
- amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
- amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
for (i = 0; i < num_xcc; i++) {
@@ -2611,19 +2629,6 @@ static int gfx_v9_4_3_early_init(struct amdgpu_ip_block *ip_block)
static int gfx_v9_4_3_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
- int r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
- if (r)
- return r;
-
- r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
- if (r)
- return r;
if (adev->gfx.ras &&
adev->gfx.ras->enable_watchdog_timer)
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index 147ba2942690..ac6d4f277336 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -1688,6 +1688,7 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
goto failure;
+ amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 023c7345ea54..7453fb11289e 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -1871,6 +1871,7 @@ static int mes_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
goto failure;
+ amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
index b169e577e583..8a90ad5a51b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
@@ -1917,6 +1917,7 @@ static int mes_v12_1_xcc_hw_init(struct amdgpu_ip_block *ip_block, int xcc_id)
goto failure;
}
+ amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
index e1d63bed84bf..c3293e5a658c 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
@@ -308,7 +308,7 @@ void xgpu_vi_init_golden_registers(struct amdgpu_device *adev)
xgpu_tonga_golden_common_all));
break;
default:
- BUG_ON("Doesn't support chip type.\n");
+ dev_err(adev->dev, "Doesn't support chip type %d\n", adev->asic_type);
break;
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
index d5f49fa33bee..45580e9c4e0c 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
@@ -1234,6 +1234,38 @@ static const struct amdgpu_ring_funcs vcn_v5_0_0_unified_ring_vm_funcs = {
.reset = vcn_v5_0_0_ring_reset,
};
+static const struct amdgpu_ring_funcs vcn_v5_0_0_unified_ring_vm_funcs_secure = {
+ .type = AMDGPU_RING_TYPE_VCN_ENC,
+ .align_mask = 0x3f,
+ .nop = VCN_ENC_CMD_NO_OP,
+ .secure_submission_supported = true,
+ .no_user_fence = true,
+ .get_rptr = vcn_v5_0_0_unified_ring_get_rptr,
+ .get_wptr = vcn_v5_0_0_unified_ring_get_wptr,
+ .set_wptr = vcn_v5_0_0_unified_ring_set_wptr,
+ .emit_frame_size =
+ SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
+ SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
+ 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
+ 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
+ 1, /* vcn_v2_0_enc_ring_insert_end */
+ .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
+ .emit_ib = vcn_v2_0_enc_ring_emit_ib,
+ .emit_fence = vcn_v2_0_enc_ring_emit_fence,
+ .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
+ .test_ring = amdgpu_vcn_enc_ring_test_ring,
+ .test_ib = amdgpu_vcn_unified_ring_test_ib,
+ .insert_nop = amdgpu_ring_insert_nop,
+ .insert_end = vcn_v2_0_enc_ring_insert_end,
+ .pad_ib = amdgpu_ring_generic_pad_ib,
+ .begin_use = amdgpu_vcn_ring_begin_use,
+ .end_use = amdgpu_vcn_ring_end_use,
+ .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
+ .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
+ .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = vcn_v5_0_0_ring_reset,
+};
+
/**
* vcn_v5_0_0_set_unified_ring_funcs - set unified ring functions
*
@@ -1249,7 +1281,12 @@ static void vcn_v5_0_0_set_unified_ring_funcs(struct amdgpu_device *adev)
if (adev->vcn.harvest_config & (1 << i))
continue;
- adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_0_unified_ring_vm_funcs;
+ if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(5, 3, 0))
+ adev->vcn.inst[i].ring_enc[0].funcs =
+ &vcn_v5_0_0_unified_ring_vm_funcs_secure;
+ else
+ adev->vcn.inst[i].ring_enc[0].funcs =
+ &vcn_v5_0_0_unified_ring_vm_funcs;
adev->vcn.inst[i].ring_enc[0].me = i;
}
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index af2ae144f508..f28259d13818 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -1404,6 +1404,14 @@ int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
sub_type_hdr = (struct crat_subtype_generic *)(crat_table+1);
while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) <
((char *)crat_image) + image_len) {
+ if (!sub_type_hdr->length ||
+ sub_type_hdr->length < sizeof(struct crat_subtype_generic)) {
+ pr_warn("Invalid CRAT subtype length %u\n",
+ sub_type_hdr->length);
+ ret = -EINVAL;
+ break;
+ }
+
if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
ret = kfd_parse_subtype(sub_type_hdr, device_list);
if (ret)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
index 0f7aa51b629e..0dd1fd448059 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
@@ -832,6 +832,12 @@ int kfd_dbg_trap_enable(struct kfd_process *target, uint32_t fd,
if (copy_to_user(runtime_info, (void *)&target->runtime_info, copy_size)) {
kfd_dbg_trap_deactivate(target, false, 0);
+ fput(target->dbg_ev_file);
+ target->dbg_ev_file = NULL;
+ if (target->debugger_process)
+ atomic_dec(&target->debugger_process->debugged_process_count);
+ target->debug_trap_enabled = false;
+ kfd_unref_process(target);
r = -EFAULT;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 5150511cefc5..2e010c1f8828 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -3264,32 +3264,24 @@ int kfd_dqm_suspend_bad_queue_mes(struct kfd_node *knode, u32 pasid, u32 doorbel
list_for_each_entry(q, &qpd->queues_list, list) {
if (q->doorbell_id == doorbell_id && q->properties.is_active) {
- ret = suspend_all_queues_mes(dqm);
- if (ret) {
- dev_err(dev, "Suspending all queues failed");
- goto out;
- }
+ /* suspend all queues will save any good queues and mark the rest as bad */
+ suspend_all_queues_mes(dqm);
q->properties.is_evicted = true;
q->properties.is_active = false;
decrement_queue_count(dqm, qpd, q);
+ /* this will remove the bad queue and sched a GPU reset if needed */
ret = remove_queue_mes(dqm, q, qpd);
- if (ret) {
- dev_err(dev, "Removing bad queue failed");
- goto out;
- }
-
- ret = resume_all_queues_mes(dqm);
if (ret)
- dev_err(dev, "Resuming all queues failed");
-
+ dev_err(dev, "Removing bad queue failed");
+ /* resume the good queues */
+ resume_all_queues_mes(dqm);
break;
}
}
}
-out:
dqm_unlock(dqm);
kfd_unref_process(p);
return ret;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index a11c4ab3aafd..81900b49d9d5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -800,6 +800,8 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
struct kfd_event_waiter *event_waiters;
uint32_t i;
+ if (num_events > KFD_SIGNAL_EVENT_LIMIT)
+ return NULL;
event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events);
if (!event_waiters)
return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
index 15975c23a88e..dfbde5a571f6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
@@ -254,8 +254,10 @@ void kfd_smi_event_update_vmfault(struct kfd_node *dev, uint16_t pasid)
if (task_info) {
/* Report VM faults from user applications, not retry from kernel */
if (task_info->task.pid)
- kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, KFD_EVENT_FMT_VMFAULT(
- task_info->task.pid, task_info->task.comm));
+ kfd_smi_event_add(task_info->tgid, dev,
+ KFD_SMI_EVENT_VMFAULT,
+ KFD_EVENT_FMT_VMFAULT(task_info->task.pid,
+ task_info->task.comm));
amdgpu_vm_put_task_info(task_info);
}
}
@@ -356,7 +358,7 @@ void kfd_smi_event_process(struct kfd_process_device *pdd, bool start)
task_info = amdgpu_vm_get_task_info_vm(avm);
if (task_info) {
- kfd_smi_event_add(0, pdd->dev,
+ kfd_smi_event_add(task_info->tgid, pdd->dev,
start ? KFD_SMI_EVENT_PROCESS_START :
KFD_SMI_EVENT_PROCESS_END,
KFD_EVENT_FMT_PROCESS(task_info->task.pid,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index dc1c6bd1252f..00517c3d0e6a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -198,8 +198,7 @@ struct kfd_topology_device *kfd_create_topology_device(
#define sysfs_show_gen_prop(buffer, offs, fmt, ...) \
- (offs += snprintf(buffer+offs, PAGE_SIZE-offs, \
- fmt, __VA_ARGS__))
+ (offs += sysfs_emit_at(buffer, offs, fmt, __VA_ARGS__))
#define sysfs_show_32bit_prop(buffer, offs, name, value) \
sysfs_show_gen_prop(buffer, offs, "%s %u\n", name, value)
#define sysfs_show_64bit_prop(buffer, offs, name, value) \
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 04e440521f67..1ed697a3a453 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -13837,17 +13837,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
}
/* Handle MCCS */
- if (do_mccs)
+ if (do_mccs) {
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
- if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
- as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
- (!sink->edid_caps.freesync_vcp_code ||
- (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
- freesync_capable = false;
+ if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
+ freesync_capable = false;
- if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
- dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+ if (sink->mccs_caps.freesync_supported && freesync_capable)
+ dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+ }
update:
if (dm_con_state)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index b9a3e842626e..f257ea91a34d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -968,7 +968,7 @@ bool dm_helpers_is_dp_sink_present(struct dc_link *link)
struct amdgpu_dm_connector *aconnector = link->priv;
if (!aconnector) {
- BUG_ON("Failed to find connector for link!");
+ DRM_ERROR("Failed to find connector for link!");
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
index 0da03eb794aa..eb6e7f4043fd 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
@@ -266,7 +266,7 @@ struct dc_hdmi_frl_link_settings {
};
struct dc_hdmi_frl_flags {
- int force_frl_rate;
+ unsigned int force_frl_rate;
bool ignore_ffe;
int select_ffe;
int limit_ffe;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index 5f088d113b9f..38c79239004c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -1060,7 +1060,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)
{
int plane_count;
- int i;
+ unsigned int i;
plane_count = 0;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
index c6ff7a290c7f..c1a3e2496983 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
@@ -48,6 +48,7 @@ static enum dml2_project_id dml21_dcn_revision_to_dml2_project_id(enum dce_versi
project_id = dml2_project_dcn4x_stage2_auto_drr_svp;
break;
case DCN_VERSION_4_2:
+ case DCN_VERSION_4_2B:
project_id = dml2_project_dcn42;
break;
default:
diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn401/dcn401_hpo_frl_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn401/dcn401_hpo_frl_stream_encoder.c
index 28cb14dc87b0..85b7a44c0a11 100644
--- a/drivers/gpu/drm/amd/display/dc/hpo/dcn401/dcn401_hpo_frl_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn401/dcn401_hpo_frl_stream_encoder.c
@@ -143,8 +143,8 @@ void hpo_enc401_read_state(
struct hpo_frl_stream_encoder *enc,
struct hpo_frl_stream_encoder_state *state)
{
- int pixel_encoding;
- int color_depth;
+ uint32_t pixel_encoding;
+ uint32_t color_depth;
// int odm_combine;
struct dcn401_hpo_frl_stream_encoder *enc401 = DCN401_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(enc);
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
index 7d8944d27d92..ca77d29ebacc 100644
--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
@@ -261,8 +261,8 @@ enum {
#define ASICREV_IS_GC_11_0_0(eChipRev) (eChipRev < GC_11_0_2_A0)
#define ASICREV_IS_GC_11_0_2(eChipRev) (eChipRev >= GC_11_0_2_A0 && eChipRev < GC_11_0_3_A0)
-#define ASICREV_IS_GC_11_0_3(eChipRev) (eChipRev >= GC_11_0_3_A0 && eChipRev < GC_11_UNKNOWN)
-#define ASICREV_IS_GC_11_0_4(eChipRev) (eChipRev >= GC_11_0_4_A0 && eChipRev < GC_11_UNKNOWN)
+#define ASICREV_IS_GC_11_0_3(eChipRev) (eChipRev >= GC_11_0_3_A0 && eChipRev < GC_11_0_4_A0)
+#define ASICREV_IS_GC_11_0_4(eChipRev) (eChipRev >= GC_11_0_4_A0 && eChipRev < DCN4A_SOC_VAR_B_A0)
#define ASICREV_IS_DCN36(eChipRev) ((eChipRev) >= 0x50 && (eChipRev) < 0xC0)
#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 52e5cbcac352..f43d09769320 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -806,6 +806,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
if (strlen(sub_str) == 0)
continue;
+ if (parameter_size >= ARRAY_SIZE(parameter))
+ return -EINVAL;
ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
if (ret)
return -EINVAL;
@@ -874,6 +876,8 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
for (clk_index = 0 ; clk_index < ARRAY_SIZE(od_clocks) ; clk_index++) {
amdgpu_dpm_emit_clock_levels(adev, od_clocks[clk_index], buf, &size);
+ if (unlikely(size >= (PAGE_SIZE - 1)))
+ break;
}
if (size == 0)
@@ -1389,7 +1393,6 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
long parameter[64];
char *sub_str, buf_cpy[128];
char *tmp_str;
- uint32_t i = 0;
char tmp[2];
long int profile_mode = 0;
const char delimiter[3] = {' ', '\n', '\0'};
@@ -1398,18 +1401,18 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
if (count == 0 || sysfs_streq(buf, ""))
return -EINVAL;
- tmp[0] = *(buf);
+ tmp[0] = *(buf++);
tmp[1] = '\0';
ret = kstrtol(tmp, 0, &profile_mode);
if (ret)
return -EINVAL;
if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
- if (count < 2 || count > 127)
+ if (count < 2 || count > sizeof(buf_cpy))
return -EINVAL;
- while (isspace(*++buf))
- i++;
- memcpy(buf_cpy, buf, count-i);
+ while (isspace(*buf))
+ buf++;
+ strscpy(buf_cpy, buf, sizeof(buf_cpy));
tmp_str = buf_cpy;
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
if (strlen(sub_str) == 0)
@@ -3955,6 +3958,7 @@ static int parse_input_od_command_lines(const char *buf,
size_t count,
u32 *type,
long *params,
+ size_t params_max,
uint32_t *num_of_params)
{
const char delimiter[3] = {' ', '\n', '\0'};
@@ -3990,6 +3994,9 @@ static int parse_input_od_command_lines(const char *buf,
if (strlen(sub_str) == 0)
continue;
+ if (parameter_size >= params_max)
+ return -EINVAL;
+
ret = kstrtol(sub_str, 0, &params[parameter_size]);
if (ret)
return -EINVAL;
@@ -4021,6 +4028,7 @@ amdgpu_distribute_custom_od_settings(struct amdgpu_device *adev,
count,
&cmd_type,
parameter,
+ ARRAY_SIZE(parameter),
&parameter_size);
if (ret)
return ret;