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
blob: fdb2df3ed83b5202c71bde2bb937bfb852f39a30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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