mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
accel/qaic: Protect perf stats BO state with bo->lock
qaic_perf_stats_bo_ioctl() validates each BO by checking bo->sliced and
bo->dbc before returning its perf stats. These fields are changed by the
detach paths while holding bo->lock, but the perf stats ioctl reads them
without that lock.
A concurrent detach can clear bo->dbc and mark the BO unsliced while the
perf stats ioctl is validating the BO. Take bo->lock while checking the
BO state and copying the per-BO stats into the temporary result buffer.
Fixes: 4ddf4ddfce ("accel/qaic: Ensure entry belongs to DBC in qaic_perf_stats_bo_ioctl()")
Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Signed-off-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Link: https://patch.msgid.link/6a115824.a0bed9bd.3c0137.9edf@mx.google.com
This commit is contained in:
parent
c274d6aaa3
commit
1c50c57717
|
|
@ -1840,15 +1840,16 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
goto free_ent;
|
||||
}
|
||||
bo = to_qaic_bo(obj);
|
||||
ret = mutex_lock_interruptible(&bo->lock);
|
||||
if (ret)
|
||||
goto put_obj;
|
||||
if (!bo->sliced) {
|
||||
drm_gem_object_put(obj);
|
||||
ret = -EINVAL;
|
||||
goto free_ent;
|
||||
goto unlock_bo;
|
||||
}
|
||||
if (bo->dbc->id != args->hdr.dbc_id) {
|
||||
drm_gem_object_put(obj);
|
||||
ret = -EINVAL;
|
||||
goto free_ent;
|
||||
goto unlock_bo;
|
||||
}
|
||||
/*
|
||||
* perf stats ioctl is called before wait ioctl is complete then
|
||||
|
|
@ -1864,7 +1865,12 @@ int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
bo->perf_stats.req_received_ts), 1000);
|
||||
ent[i].queue_level_before = bo->perf_stats.queue_level_before;
|
||||
ent[i].num_queue_element = bo->total_slice_nents;
|
||||
unlock_bo:
|
||||
mutex_unlock(&bo->lock);
|
||||
put_obj:
|
||||
drm_gem_object_put(obj);
|
||||
if (ret)
|
||||
goto free_ent;
|
||||
}
|
||||
|
||||
if (copy_to_user(u64_to_user_ptr(args->data), ent, args->hdr.count * sizeof(*ent)))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user