summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_pt.c
diff options
context:
space:
mode:
authorThomas Hellström <thomas.hellstrom@linux.intel.com>2023-12-09 18:18:42 +0300
committerRodrigo Vivi <rodrigo.vivi@intel.com>2023-12-21 19:45:28 +0300
commit06951c2ee72df2f53b71e7cf2b504d4fa6bba453 (patch)
tree49c9376542d6e5381c0446776e74bf051b0518dd /drivers/gpu/drm/xe/xe_pt.c
parente84d716dd461928b3db344748cd7f87395a2ce74 (diff)
downloadlinux-06951c2ee72df2f53b71e7cf2b504d4fa6bba453.tar.xz
drm/xe: Use NULL PTEs as scratch PTEs
Currently scratch PTEs are write-enabled and points to a single scratch page. This has the side effect that buggy applications with out-of-bounds memory accesses may not notice the bad access since what's written may be read back. Instead use NULL PTEs as scratch PTEs. These always return 0 when reading, and writing has no effect. As a slight benefit, we can also use huge NULL PTEs. One drawback pointed out is that debugging may be hampered since previously when inspecting the content of the scratch page, it might be possible to detect writes to out-of-bound addresses and possibly also from where the out-of-bounds address originated. However since the scratch page-table structure is kept, it will be easy to add back the single RW-enabled scratch page under a debug define if needed. Also update the kerneldoc accordingly and move the function to create the scratch page-tables from xe_pt.c to xe_pt.h since it is accessing vm structure internals and this also makes it possible to make it static. v2: - Don't try to encode scratch PTEs larger than 1GiB. - Move xe_pt_create_scratch(), Update kerneldoc. v3: - Rebase. Cc: Brian Welty <brian.welty@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Acked-by: Lucas De Marchi <lucas.demarchi@intel.com> #for general direction. Reviewed-by: Brian Welty <brian.welty@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231209151843.7903-3-thomas.hellstrom@linux.intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/drm/xe/xe_pt.c')
-rw-r--r--drivers/gpu/drm/xe/xe_pt.c65
1 files changed, 8 insertions, 57 deletions
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 46ef9df34a2e..de1030a47588 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -50,17 +50,19 @@ static struct xe_pt *xe_pt_entry(struct xe_pt_dir *pt_dir, unsigned int index)
static u64 __xe_pt_empty_pte(struct xe_tile *tile, struct xe_vm *vm,
unsigned int level)
{
- u16 pat_index = tile_to_xe(tile)->pat.idx[XE_CACHE_WB];
+ struct xe_device *xe = tile_to_xe(tile);
+ u16 pat_index = xe->pat.idx[XE_CACHE_WB];
u8 id = tile->id;
- if (!vm->scratch_bo[id])
+ if (!xe_vm_has_scratch(vm))
return 0;
- if (level > 0)
+ if (level > MAX_HUGEPTE_LEVEL)
return vm->pt_ops->pde_encode_bo(vm->scratch_pt[id][level - 1]->bo,
0, pat_index);
- return vm->pt_ops->pte_encode_bo(vm->scratch_bo[id], 0, pat_index, 0);
+ return vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level, IS_DGFX(xe), 0) |
+ XE_PTE_NULL;
}
/**
@@ -135,7 +137,7 @@ void xe_pt_populate_empty(struct xe_tile *tile, struct xe_vm *vm,
u64 empty;
int i;
- if (!vm->scratch_bo[tile->id]) {
+ if (!xe_vm_has_scratch(vm)) {
/*
* FIXME: Some memory is allocated already allocated to zero?
* Find out which memory that is and avoid this memset...
@@ -195,57 +197,6 @@ void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred)
}
/**
- * xe_pt_create_scratch() - Setup a scratch memory pagetable tree for the
- * given tile and vm.
- * @xe: xe device.
- * @tile: tile to set up for.
- * @vm: vm to set up for.
- *
- * Sets up a pagetable tree with one page-table per level and a single
- * leaf bo. All pagetable entries point to the single page-table or,
- * for L0, the single bo one level below.
- *
- * Return: 0 on success, negative error code on error.
- */
-int xe_pt_create_scratch(struct xe_device *xe, struct xe_tile *tile,
- struct xe_vm *vm)
-{
- u8 id = tile->id;
- unsigned int flags;
- int i;
-
- /*
- * So we don't need to worry about 64K TLB hints when dealing with
- * scratch entires, rather keep the scratch page in system memory on
- * platforms where 64K pages are needed for VRAM.
- */
- flags = XE_BO_CREATE_PINNED_BIT;
- if (vm->flags & XE_VM_FLAG_64K)
- flags |= XE_BO_CREATE_SYSTEM_BIT;
- else
- flags |= XE_BO_CREATE_VRAM_IF_DGFX(tile);
-
- vm->scratch_bo[id] = xe_bo_create_pin_map(xe, tile, vm, SZ_4K,
- ttm_bo_type_kernel,
- flags);
- if (IS_ERR(vm->scratch_bo[id]))
- return PTR_ERR(vm->scratch_bo[id]);
-
- xe_map_memset(vm->xe, &vm->scratch_bo[id]->vmap, 0, 0,
- vm->scratch_bo[id]->size);
-
- for (i = 0; i < vm->pt_root[id]->level; i++) {
- vm->scratch_pt[id][i] = xe_pt_create(vm, tile, i);
- if (IS_ERR(vm->scratch_pt[id][i]))
- return PTR_ERR(vm->scratch_pt[id][i]);
-
- xe_pt_populate_empty(tile, vm, vm->scratch_pt[id][i]);
- }
-
- return 0;
-}
-
-/**
* DOC: Pagetable building
*
* Below we use the term "page-table" for both page-directories, containing
@@ -1289,7 +1240,7 @@ __xe_pt_bind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queue
* it needs to be done here.
*/
if ((rebind && !xe_vm_in_lr_mode(vm) && !vm->batch_invalidate_tlb) ||
- (!rebind && vm->scratch_bo[tile->id] && xe_vm_in_preempt_fence_mode(vm))) {
+ (!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) {
ifence = kzalloc(sizeof(*ifence), GFP_KERNEL);
if (!ifence)
return ERR_PTR(-ENOMEM);