diff options
author | Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> | 2017-05-11 22:39:31 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-05-31 14:16:37 -0400 |
commit | cc28c4ed7e735fc09043054b22370202583f69c3 (patch) | |
tree | 10c0c94fd26b1c04ad5fca2089a013e14bd6a8f0 | |
parent | 92456b933cd257845587697a0875878849cef973 (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.c | 48 |
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 | */ |
1191 | static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, | 1192 | static 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 | */ |
1288 | static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, | 1292 | static 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(¶ms, start, last + 1, addr, flags); | 1470 | r = amdgpu_vm_frag_ptes(¶ms, 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(¶ms, start, last + 1, addr, flags); | 1474 | r = amdgpu_vm_frag_ptes(¶ms, 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); |