Re: [PATCH] drm/xe: Bound pgtable update loops by current_op
Matthew Brost <[email protected]>
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Aug 21, 2026 at 06:36:42PM +0000, Jagmeet Randhawa wrote: > xe_vma_ops_alloc() sizes the pt_update_ops->ops array with num_ops, the > number of operations reserved, and allocates it with kmalloc_objs(), so > the entries come back uninitialized. Only the first current_op entries > are ever populated. xe_pt.c reflects this and bounds its loops by > current_op, and xe_pt_update_ops_prepare() states the invariant > explicitly: > > xe_tile_assert(tile, pt_update_ops->current_op <= > pt_update_ops->num_ops); > > xe_migrate.c instead iterates num_ops. When fewer operations are > populated than were reserved, both the CPU and GPU page table update > paths walk past the populated entries into memory that was never > initialized, read a garbage pointer out of it and dereference it. > > A syzkaller reproducer triggers this with a VM_BIND / MADVISE / VM_BIND > sequence that reserves five operations and populates two: > > UBSAN: invalid-load in drivers/gpu/drm/xe/xe_migrate.c:1836:13 > load of value 107 is not a valid value for type '_Bool' > Oops: general protection fault, probably for non-canonical address > 0xed6d696d6d6d6d6e > KASAN: maybe wild-memory-access in range > [0x6b6b6b6b6b6b6b70-0x6b6b6b6b6b6b6b77] > RIP: 0010:xe_vm_populate_pgtable+0xd0/0x380 [xe] > Call Trace: > xe_migrate_update_pgtables+0x32b/0x2c90 [xe] > xe_pt_update_ops_run+0x835/0x25e0 [xe] > ops_execute+0x691/0x2630 [xe] > vm_bind_ioctl_ops_execute+0x46d/0x1820 [xe] > xe_vm_bind_ioctl+0x3d5f/0x45f0 [xe] > > The value 107 is 0x6b, POISON_FREE, left behind in the unpopulated > entries by the slab allocator. > > Bound all five loops in xe_migrate.c by current_op so that only > populated entries are consumed. > Can we find a fixes tag + cc stable? Patch is correct, with that: Reviewed-by: Matthew Brost <[email protected]> > Signed-off-by: Jagmeet Randhawa <[email protected]> > --- > drivers/gpu/drm/xe/xe_migrate.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c > index 75b83687f1b5..b1be1cb2fbfc 100644 > --- a/drivers/gpu/drm/xe/xe_migrate.c > +++ b/drivers/gpu/drm/xe/xe_migrate.c > @@ -1825,7 +1825,7 @@ xe_migrate_update_pgtables_cpu(struct xe_migrate *m, > return ERR_PTR(err); > } > > - for (i = 0; i < pt_update_ops->num_ops; ++i) { > + for (i = 0; i < pt_update_ops->current_op; ++i) { > const struct xe_vm_pgtable_update_op *pt_op = > &pt_update_ops->ops[i]; > > @@ -1871,7 +1871,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, > bool is_migrate = pt_update_ops->q == m->q; > bool usm = is_migrate && xe->info.has_usm; > > - for (i = 0; i < pt_update_ops->num_ops; ++i) { > + for (i = 0; i < pt_update_ops->current_op; ++i) { > struct xe_vm_pgtable_update_op *pt_op = &pt_update_ops->ops[i]; > struct xe_vm_pgtable_update *updates = pt_op->entries; > > @@ -1939,7 +1939,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, > bb->cs[bb->len++] = ofs; > bb->cs[bb->len++] = 0; /* upper_32_bits */ > > - for (; i < pt_update_ops->num_ops; ++i) { > + for (; i < pt_update_ops->current_op; ++i) { > struct xe_vm_pgtable_update_op *pt_op = > &pt_update_ops->ops[i]; > struct xe_vm_pgtable_update *updates = pt_op->entries; > @@ -1976,7 +1976,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, > > addr = xe_migrate_vm_addr(ppgtt_ofs, 0) + > (page_ofs / sizeof(u64)) * XE_PAGE_SIZE; > - for (i = 0; i < pt_update_ops->num_ops; ++i) { > + for (i = 0; i < pt_update_ops->current_op; ++i) { > struct xe_vm_pgtable_update_op *pt_op = > &pt_update_ops->ops[i]; > struct xe_vm_pgtable_update *updates = pt_op->entries; > @@ -1994,7 +1994,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, > bb->cs[bb->len++] = MI_BATCH_BUFFER_END; > update_idx = bb->len; > > - for (i = 0; i < pt_update_ops->num_ops; ++i) { > + for (i = 0; i < pt_update_ops->current_op; ++i) { > struct xe_vm_pgtable_update_op *pt_op = > &pt_update_ops->ops[i]; > struct xe_vm_pgtable_update *updates = pt_op->entries; > -- > 2.43.0 >