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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
From dd3cebfd6c74af0f8b50b3c09c24c625dca84528 Mon Sep 17 00:00:00 2001
From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Date: Wed, 20 Dec 2017 12:38:45 -0500
Subject: [PATCH 3142/4131] drm/amdkfd: cma: check invalid BO range
Also modify error message to indicate CMA operation
BUG: SWDEV-138468
Change-Id: Ie6ee0189f515e00c15832ba5f0fa15812763f9a9
Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 33 ++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index afc4ce2..7fd26ec 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1759,7 +1759,8 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
struct dma_fence *fence = NULL, *lfence = NULL;
uint64_t dst_va_addr;
uint64_t copied, total_copied = 0;
- uint64_t src_offset, dst_offset;
+ uint64_t src_offset, dst_offset, dst_va_addr_end;
+ const char *cma_op;
int i, j = 0, err = 0;
/* Check parameters */
@@ -1830,10 +1831,12 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
if (KFD_IS_CROSS_MEMORY_WRITE(args->flags)) {
src_p = local_p;
dst_p = remote_p;
+ cma_op = "WRITE";
pr_debug("CMA WRITE: local -> remote\n");
} else {
src_p = remote_p;
dst_p = local_p;
+ cma_op = "READ";
pr_debug("CMA READ: remote -> local\n");
}
@@ -1848,12 +1851,14 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
* data will be sourced or copied
*/
dst_va_addr = dst_array[0].va_addr;
+ dst_va_addr_end = dst_va_addr + dst_array[0].size - 1;
mutex_lock(&dst_p->mutex);
dst_bo = kfd_process_find_bo_from_interval(dst_p,
dst_va_addr,
- dst_va_addr + dst_array[0].size - 1);
+ dst_va_addr_end);
mutex_unlock(&dst_p->mutex);
- if (!dst_bo) {
+ if (!dst_bo || dst_va_addr_end > dst_bo->it.last) {
+ pr_err("CMA %s failed. Invalid dst range\n", cma_op);
err = -EFAULT;
goto kfd_process_fail;
}
@@ -1870,7 +1875,7 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
src_va_addr_end);
mutex_unlock(&src_p->mutex);
if (!src_bo || src_va_addr_end > src_bo->it.last) {
- pr_err("Cross mem copy failed. Invalid range\n");
+ pr_err("CMA %s failed. Invalid src range\n", cma_op);
err = -EFAULT;
break;
}
@@ -1896,7 +1901,7 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
/* Check both BOs belong to same device */
if (src_bo->dev->kgd != dst_bo->dev->kgd) {
- pr_err("Cross Memory failed. Not same device\n");
+ pr_err("CMA %s fail. Not same dev\n", cma_op);
err = -EINVAL;
break;
}
@@ -1915,7 +1920,7 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
&fence, &copied);
if (err) {
- pr_err("GPU Cross mem copy failed\n");
+ pr_err("GPU CMA %s failed\n", cma_op);
err = -EFAULT;
break;
}
@@ -1933,7 +1938,7 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
dst_offset += copied;
src_offset += copied;
if (dst_va_addr > dst_bo->it.last + 1) {
- pr_err("Cross mem copy failed. Memory overflow\n");
+ pr_err("CMA %s fail. Mem overflow\n", cma_op);
err = -EFAULT;
break;
}
@@ -1944,11 +1949,19 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
break;
dst_va_addr = dst_array[j].va_addr;
+ dst_va_addr_end = dst_va_addr +
+ dst_array[j].size - 1;
dst_bo = kfd_process_find_bo_from_interval(
dst_p,
dst_va_addr,
- dst_va_addr +
- dst_array[j].size - 1);
+ dst_va_addr_end);
+ if (!dst_bo ||
+ dst_va_addr_end > dst_bo->it.last) {
+ pr_err("CMA %s failed. Invalid dst range\n",
+ cma_op);
+ err = -EFAULT;
+ break;
+ }
dst_offset = dst_va_addr - dst_bo->it.start;
}
@@ -1964,7 +1977,7 @@ static int kfd_ioctl_cross_memory_copy(struct file *filep,
if (fence) {
if (dma_fence_wait_timeout(fence, false, msecs_to_jiffies(1000))
< 0)
- pr_err("Cross mem copy failed. BO timed out\n");
+ pr_err("CMA %s failed. BO timed out\n", cma_op);
dma_fence_put(fence);
} else if (lfence) {
pr_debug("GPU copy fail. But wait for prev DMA to finish\n");
--
2.7.4
|