Skip to content

Commit cee9daa

Browse files
mbrost05jfvogel
authored andcommitted
drm/xe: Nuke VM's mapping upon close
[ Upstream commit 074e40d9c2a84939fe28d7121d3469db50f34a3d ] Clear root PT entry and invalidate entire VM's address space when closing the VM. Will prevent the GPU from accessing any of the VM's memory after closing. v2: - s/vma/vm in kernel doc (CI) - Don't nuke migration VM as this occur at driver unload (CI) v3: - Rebase and pull into SVM series (Thomas) - Wait for pending binds (Thomas) v5: - Remove xe_gt_tlb_invalidation_fence_fini in error case (Matt Auld) - Drop local migration bool (Thomas) v7: - Add drm_dev_enter/exit protecting invalidation (CI, Matt Auld) Signed-off-by: Matthew Brost <[email protected]> Reviewed-by: Thomas Hellström <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 623669ae7a8204264098c80cdc13086b7371bacf) Signed-off-by: Jack Vogel <[email protected]>
1 parent 6d5eda6 commit cee9daa

File tree

5 files changed

+73
-0
lines changed

5 files changed

+73
-0
lines changed

drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,28 @@ int xe_gt_tlb_invalidation_range(struct xe_gt *gt,
406406
return send_tlb_invalidation(&gt->uc.guc, fence, action, len);
407407
}
408408

409+
/**
410+
* xe_gt_tlb_invalidation_vm - Issue a TLB invalidation on this GT for a VM
411+
* @gt: graphics tile
412+
* @vm: VM to invalidate
413+
*
414+
* Invalidate entire VM's address space
415+
*/
416+
void xe_gt_tlb_invalidation_vm(struct xe_gt *gt, struct xe_vm *vm)
417+
{
418+
struct xe_gt_tlb_invalidation_fence fence;
419+
u64 range = 1ull << vm->xe->info.va_bits;
420+
int ret;
421+
422+
xe_gt_tlb_invalidation_fence_init(gt, &fence, true);
423+
424+
ret = xe_gt_tlb_invalidation_range(gt, &fence, 0, range, vm->usm.asid);
425+
if (ret < 0)
426+
return;
427+
428+
xe_gt_tlb_invalidation_fence_wait(&fence);
429+
}
430+
409431
/**
410432
* xe_gt_tlb_invalidation_vma - Issue a TLB invalidation on this GT for a VMA
411433
* @gt: graphics tile

drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
struct xe_gt;
1414
struct xe_guc;
15+
struct xe_vm;
1516
struct xe_vma;
1617

1718
int xe_gt_tlb_invalidation_init_early(struct xe_gt *gt);
@@ -21,6 +22,7 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt);
2122
int xe_gt_tlb_invalidation_vma(struct xe_gt *gt,
2223
struct xe_gt_tlb_invalidation_fence *fence,
2324
struct xe_vma *vma);
25+
void xe_gt_tlb_invalidation_vm(struct xe_gt *gt, struct xe_vm *vm);
2426
int xe_gt_tlb_invalidation_range(struct xe_gt *gt,
2527
struct xe_gt_tlb_invalidation_fence *fence,
2628
u64 start, u64 end, u32 asid);

drivers/gpu/drm/xe/xe_pt.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred)
217217
xe_pt_free(pt);
218218
}
219219

220+
/**
221+
* xe_pt_clear() - Clear a page-table.
222+
* @xe: xe device.
223+
* @pt: The page-table.
224+
*
225+
* Clears page-table by setting to zero.
226+
*/
227+
void xe_pt_clear(struct xe_device *xe, struct xe_pt *pt)
228+
{
229+
struct iosys_map *map = &pt->bo->vmap;
230+
231+
xe_map_memset(xe, map, 0, 0, SZ_4K);
232+
}
233+
220234
/**
221235
* DOC: Pagetable building
222236
*

drivers/gpu/drm/xe/xe_pt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct dma_fence;
1313
struct xe_bo;
1414
struct xe_device;
1515
struct xe_exec_queue;
16+
struct xe_svm_range;
1617
struct xe_sync_entry;
1718
struct xe_tile;
1819
struct xe_vm;
@@ -35,6 +36,8 @@ void xe_pt_populate_empty(struct xe_tile *tile, struct xe_vm *vm,
3536

3637
void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred);
3738

39+
void xe_pt_clear(struct xe_device *xe, struct xe_pt *pt);
40+
3841
int xe_pt_update_ops_prepare(struct xe_tile *tile, struct xe_vma_ops *vops);
3942
struct dma_fence *xe_pt_update_ops_run(struct xe_tile *tile,
4043
struct xe_vma_ops *vops);

drivers/gpu/drm/xe/xe_vm.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/dma-fence-array.h>
99
#include <linux/nospec.h>
1010

11+
#include <drm/drm_drv.h>
1112
#include <drm/drm_exec.h>
1213
#include <drm/drm_print.h>
1314
#include <drm/ttm/ttm_execbuf_util.h>
@@ -1581,9 +1582,40 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
15811582

15821583
static void xe_vm_close(struct xe_vm *vm)
15831584
{
1585+
struct xe_device *xe = vm->xe;
1586+
bool bound;
1587+
int idx;
1588+
1589+
bound = drm_dev_enter(&xe->drm, &idx);
1590+
15841591
down_write(&vm->lock);
1592+
15851593
vm->size = 0;
1594+
1595+
if (!((vm->flags & XE_VM_FLAG_MIGRATION))) {
1596+
struct xe_tile *tile;
1597+
struct xe_gt *gt;
1598+
u8 id;
1599+
1600+
/* Wait for pending binds */
1601+
dma_resv_wait_timeout(xe_vm_resv(vm),
1602+
DMA_RESV_USAGE_BOOKKEEP,
1603+
false, MAX_SCHEDULE_TIMEOUT);
1604+
1605+
if (bound) {
1606+
for_each_tile(tile, xe, id)
1607+
if (vm->pt_root[id])
1608+
xe_pt_clear(xe, vm->pt_root[id]);
1609+
1610+
for_each_gt(gt, xe, id)
1611+
xe_gt_tlb_invalidation_vm(gt, vm);
1612+
}
1613+
}
1614+
15861615
up_write(&vm->lock);
1616+
1617+
if (bound)
1618+
drm_dev_exit(idx);
15871619
}
15881620

15891621
void xe_vm_close_and_put(struct xe_vm *vm)

0 commit comments

Comments
 (0)