aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>2017-05-11 22:39:31 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-05-31 14:16:37 -0400
commitcc28c4ed7e735fc09043054b22370202583f69c3 (patch)
tree10c0c94fd26b1c04ad5fca2089a013e14bd6a8f0
parent92456b933cd257845587697a0875878849cef973 (diff)
drm/amdgpu: Return EINVAL if no PT BO
This change is also useful for the upcoming changes where page tables can be updated by CPU. Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6af2d3c56f38..b2384b8536b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1187,8 +1187,9 @@ static struct amdgpu_bo *amdgpu_vm_get_pt(struct amdgpu_pte_update_params *p,
1187 * @flags: mapping flags 1187 * @flags: mapping flags
1188 * 1188 *
1189 * Update the page tables in the range @start - @end. 1189 * Update the page tables in the range @start - @end.
1190 * Returns 0 for success, -EINVAL for failure.
1190 */ 1191 */
1191static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, 1192static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1192 uint64_t start, uint64_t end, 1193 uint64_t start, uint64_t end,
1193 uint64_t dst, uint64_t flags) 1194 uint64_t dst, uint64_t flags)
1194{ 1195{
@@ -1206,12 +1207,12 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1206 pt = amdgpu_vm_get_pt(params, addr); 1207 pt = amdgpu_vm_get_pt(params, addr);
1207 if (!pt) { 1208 if (!pt) {
1208 pr_err("PT not found, aborting update_ptes\n"); 1209 pr_err("PT not found, aborting update_ptes\n");
1209 return; 1210 return -EINVAL;
1210 } 1211 }
1211 1212
1212 if (params->shadow) { 1213 if (params->shadow) {
1213 if (!pt->shadow) 1214 if (!pt->shadow)
1214 return; 1215 return 0;
1215 pt = pt->shadow; 1216 pt = pt->shadow;
1216 } 1217 }
1217 if ((addr & ~mask) == (end & ~mask)) 1218 if ((addr & ~mask) == (end & ~mask))
@@ -1233,12 +1234,12 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1233 pt = amdgpu_vm_get_pt(params, addr); 1234 pt = amdgpu_vm_get_pt(params, addr);
1234 if (!pt) { 1235 if (!pt) {
1235 pr_err("PT not found, aborting update_ptes\n"); 1236 pr_err("PT not found, aborting update_ptes\n");
1236 return; 1237 return -EINVAL;
1237 } 1238 }
1238 1239
1239 if (params->shadow) { 1240 if (params->shadow) {
1240 if (!pt->shadow) 1241 if (!pt->shadow)
1241 return; 1242 return 0;
1242 pt = pt->shadow; 1243 pt = pt->shadow;
1243 } 1244 }
1244 1245
@@ -1273,6 +1274,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1273 1274
1274 params->func(params, cur_pe_start, cur_dst, cur_nptes, 1275 params->func(params, cur_pe_start, cur_dst, cur_nptes,
1275 AMDGPU_GPU_PAGE_SIZE, flags); 1276 AMDGPU_GPU_PAGE_SIZE, flags);
1277
1278 return 0;
1276} 1279}
1277 1280
1278/* 1281/*
@@ -1284,11 +1287,14 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1284 * @end: last PTE to handle 1287 * @end: last PTE to handle
1285 * @dst: addr those PTEs should point to 1288 * @dst: addr those PTEs should point to
1286 * @flags: hw mapping flags 1289 * @flags: hw mapping flags
1290 * Returns 0 for success, -EINVAL for failure.
1287 */ 1291 */
1288static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, 1292static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
1289 uint64_t start, uint64_t end, 1293 uint64_t start, uint64_t end,
1290 uint64_t dst, uint64_t flags) 1294 uint64_t dst, uint64_t flags)
1291{ 1295{
1296 int r;
1297
1292 /** 1298 /**
1293 * The MC L1 TLB supports variable sized pages, based on a fragment 1299 * The MC L1 TLB supports variable sized pages, based on a fragment
1294 * field in the PTE. When this field is set to a non-zero value, page 1300 * field in the PTE. When this field is set to a non-zero value, page
@@ -1317,28 +1323,30 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
1317 1323
1318 /* system pages are non continuously */ 1324 /* system pages are non continuously */
1319 if (params->src || !(flags & AMDGPU_PTE_VALID) || 1325 if (params->src || !(flags & AMDGPU_PTE_VALID) ||
1320 (frag_start >= frag_end)) { 1326 (frag_start >= frag_end))
1321 1327 return amdgpu_vm_update_ptes(params, start, end, dst, flags);
1322 amdgpu_vm_update_ptes(params, start, end, dst, flags);
1323 return;
1324 }
1325 1328
1326 /* handle the 4K area at the beginning */ 1329 /* handle the 4K area at the beginning */
1327 if (start != frag_start) { 1330 if (start != frag_start) {
1328 amdgpu_vm_update_ptes(params, start, frag_start, 1331 r = amdgpu_vm_update_ptes(params, start, frag_start,
1329 dst, flags); 1332 dst, flags);
1333 if (r)
1334 return r;
1330 dst += (frag_start - start) * AMDGPU_GPU_PAGE_SIZE; 1335 dst += (frag_start - start) * AMDGPU_GPU_PAGE_SIZE;
1331 } 1336 }
1332 1337
1333 /* handle the area in the middle */ 1338 /* handle the area in the middle */
1334 amdgpu_vm_update_ptes(params, frag_start, frag_end, dst, 1339 r = amdgpu_vm_update_ptes(params, frag_start, frag_end, dst,
1335 flags | frag_flags); 1340 flags | frag_flags);
1341 if (r)
1342 return r;
1336 1343
1337 /* handle the 4K area at the end */ 1344 /* handle the 4K area at the end */
1338 if (frag_end != end) { 1345 if (frag_end != end) {
1339 dst += (frag_end - frag_start) * AMDGPU_GPU_PAGE_SIZE; 1346 dst += (frag_end - frag_start) * AMDGPU_GPU_PAGE_SIZE;
1340 amdgpu_vm_update_ptes(params, frag_end, end, dst, flags); 1347 r = amdgpu_vm_update_ptes(params, frag_end, end, dst, flags);
1341 } 1348 }
1349 return r;
1342} 1350}
1343 1351
1344/** 1352/**
@@ -1459,9 +1467,13 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
1459 goto error_free; 1467 goto error_free;
1460 1468
1461 params.shadow = true; 1469 params.shadow = true;
1462 amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags); 1470 r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
1471 if (r)
1472 goto error_free;
1463 params.shadow = false; 1473 params.shadow = false;
1464 amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags); 1474 r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
1475 if (r)
1476 goto error_free;
1465 1477
1466 amdgpu_ring_pad_ib(ring, params.ib); 1478 amdgpu_ring_pad_ib(ring, params.ib);
1467 WARN_ON(params.ib->length_dw > ndw); 1479 WARN_ON(params.ib->length_dw > ndw);