aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch92
1 files changed, 92 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch
new file mode 100644
index 00000000..fdb2df3e
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1418-drm-amdgpu-Fix-CP_HQD_PQ_WPTR-initialization-on.patch
@@ -0,0 +1,92 @@
+From aa29688809e41aec4f2fb49bcdd22efd8cc40c61 Mon Sep 17 00:00:00 2001
+From: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com>
+Date: Thu, 18 Oct 2018 19:12:05 +0530
+Subject: [PATCH 1418/4131] drm/amdgpu: Fix CP_HQD_PQ_WPTR initialization on
+ KFD HQD load
+
+The return value from copy_from_user() was interpreted as the opposite
+of its intended meaning. This caused PQ_WPTR to be populated with the
+uninitialized value from shadow_wptr, causing intermittent HIQ hangs.
+
+Always initialize PQ_WPTR to zero if a shadow write pointer is not
+available. Also check for NULL as this may be mapped in userspace
+but has a specific meaning when passed to hqd_load().
+
+Change-Id: I3ced7765659a043a53b8123bace0e6288a23b59d
+Signed-off-by: Jay Cornwall <jay.cornwall@amd.com>
+Reviewed-by: David Ogbeide <davidboyowa.ogbeide@amd.com>
+
+Signed-off-by: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 8 ++++----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 13 ++++++-------
+ 2 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+index 558bf3e..9eca46f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+@@ -406,12 +406,13 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+ uint32_t page_table_base)
+ {
+ struct amdgpu_device *adev = get_amdgpu_device(kgd);
+- uint32_t wptr_shadow, is_wptr_shadow_valid;
+ struct cik_mqd *m;
++ uint32_t wptr_shadow = 0, is_wptr_shadow_valid = 0;
+
+ m = get_mqd(mqd);
+
+- is_wptr_shadow_valid = !get_user(wptr_shadow, wptr);
++ if (wptr != NULL)
++ is_wptr_shadow_valid = !get_user(wptr_shadow, wptr);
+
+ acquire_queue(kgd, pipe_id, queue_id);
+
+@@ -458,8 +459,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+
+ WREG32(mmCP_HQD_IQ_RPTR, m->cp_hqd_iq_rptr);
+
+- if (is_wptr_shadow_valid)
+- WREG32(mmCP_HQD_PQ_WPTR, wptr_shadow);
++ WREG32(mmCP_HQD_PQ_WPTR, (is_wptr_shadow_valid ? wptr_shadow : 0));
+
+ WREG32(mmCP_HQD_ACTIVE, m->cp_hqd_active);
+ release_queue(kgd);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+index 34e4a81..41925d3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+@@ -322,13 +322,15 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t page_table_base)
+ {
+- struct vi_mqd *m;
+- uint32_t shadow_wptr, valid_wptr;
+ struct amdgpu_device *adev = get_amdgpu_device(kgd);
++ struct vi_mqd *m;
++ uint32_t wptr_shadow = 0, is_wptr_shadow_valid = 0;
+
+ m = get_mqd(mqd);
+
+- valid_wptr = copy_from_user(&shadow_wptr, wptr, sizeof(shadow_wptr));
++ if (wptr != NULL)
++ is_wptr_shadow_valid = !get_user(wptr_shadow, wptr);
++
+ acquire_queue(kgd, pipe_id, queue_id);
+
+ WREG32(mmCP_MQD_CONTROL, m->cp_mqd_control);
+@@ -345,10 +347,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+ WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR, m->cp_hqd_pq_rptr_report_addr_lo);
+ WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI,
+ m->cp_hqd_pq_rptr_report_addr_hi);
+-
+- if (valid_wptr > 0)
+- WREG32(mmCP_HQD_PQ_WPTR, shadow_wptr);
+-
++ WREG32(mmCP_HQD_PQ_WPTR, (is_wptr_shadow_valid ? wptr_shadow : 0));
+ WREG32(mmCP_HQD_PQ_CONTROL, m->cp_hqd_pq_control);
+ WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, m->cp_hqd_pq_doorbell_control);
+
+--
+2.7.4
+