diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index afe45cbcd762..9ea024395d49 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -580,10 +580,9 @@ setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) | |||
| 580 | * region, including any PTEs which happen to point to scratch. | 580 | * region, including any PTEs which happen to point to scratch. |
| 581 | * | 581 | * |
| 582 | * This is only relevant for the 48b PPGTT where we support | 582 | * This is only relevant for the 48b PPGTT where we support |
| 583 | * huge-gtt-pages, see also i915_vma_insert(). | 583 | * huge-gtt-pages, see also i915_vma_insert(). However, as we share the |
| 584 | * | 584 | * scratch (read-only) between all vm, we create one 64k scratch page |
| 585 | * TODO: we should really consider write-protecting the scratch-page and | 585 | * for all. |
| 586 | * sharing between ppgtt | ||
| 587 | */ | 586 | */ |
| 588 | size = I915_GTT_PAGE_SIZE_4K; | 587 | size = I915_GTT_PAGE_SIZE_4K; |
| 589 | if (i915_vm_is_48bit(vm) && | 588 | if (i915_vm_is_48bit(vm) && |
| @@ -1209,6 +1208,26 @@ static int gen8_init_scratch(struct i915_address_space *vm) | |||
| 1209 | { | 1208 | { |
| 1210 | int ret; | 1209 | int ret; |
| 1211 | 1210 | ||
| 1211 | /* | ||
| 1212 | * If everybody agrees to not to write into the scratch page, | ||
| 1213 | * we can reuse it for all vm, keeping contexts and processes separate. | ||
| 1214 | */ | ||
| 1215 | if (vm->has_read_only && | ||
| 1216 | vm->i915->kernel_context && | ||
| 1217 | vm->i915->kernel_context->ppgtt) { | ||
| 1218 | struct i915_address_space *clone = | ||
| 1219 | &vm->i915->kernel_context->ppgtt->vm; | ||
| 1220 | |||
| 1221 | GEM_BUG_ON(!clone->has_read_only); | ||
| 1222 | |||
| 1223 | vm->scratch_page.order = clone->scratch_page.order; | ||
| 1224 | vm->scratch_pte = clone->scratch_pte; | ||
| 1225 | vm->scratch_pt = clone->scratch_pt; | ||
| 1226 | vm->scratch_pd = clone->scratch_pd; | ||
| 1227 | vm->scratch_pdp = clone->scratch_pdp; | ||
| 1228 | return 0; | ||
| 1229 | } | ||
| 1230 | |||
| 1212 | ret = setup_scratch_page(vm, __GFP_HIGHMEM); | 1231 | ret = setup_scratch_page(vm, __GFP_HIGHMEM); |
| 1213 | if (ret) | 1232 | if (ret) |
| 1214 | return ret; | 1233 | return ret; |
| @@ -1289,6 +1308,9 @@ static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create) | |||
| 1289 | 1308 | ||
| 1290 | static void gen8_free_scratch(struct i915_address_space *vm) | 1309 | static void gen8_free_scratch(struct i915_address_space *vm) |
| 1291 | { | 1310 | { |
| 1311 | if (!vm->scratch_page.daddr) | ||
| 1312 | return; | ||
| 1313 | |||
| 1292 | if (use_4lvl(vm)) | 1314 | if (use_4lvl(vm)) |
| 1293 | free_pdp(vm, vm->scratch_pdp); | 1315 | free_pdp(vm, vm->scratch_pdp); |
| 1294 | free_pd(vm, vm->scratch_pd); | 1316 | free_pd(vm, vm->scratch_pd); |
