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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.