mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
rusticl/mem: don't create svm_pointers slice from null raw pointer
std::slice::from_raw_parts requires that the slice pointer be non-null, even when the slice contains zero elements. Failing this invariant is undefined behavior. v2: reordered commits to allow cherry-picking bugfixes Reviewed-by: Karol Herbst <kherbst@redhat.com> Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33989>
This commit is contained in:
parent
faad7a8aad
commit
5e365f1674
2 changed files with 23 additions and 12 deletions
|
|
@ -2419,10 +2419,16 @@ fn enqueue_svm_free_impl(
|
|||
}
|
||||
|
||||
// The application is allowed to reuse or free the memory referenced by `svm_pointers` after this
|
||||
// function returns so we have to make a copy.
|
||||
// SAFETY: num_svm_pointers specifies the amount of elements in svm_pointers
|
||||
let mut svm_pointers =
|
||||
unsafe { slice::from_raw_parts(svm_pointers.cast(), num_svm_pointers as usize) }.to_vec();
|
||||
// function returns, so we have to make a copy.
|
||||
let mut svm_pointers = if !svm_pointers.is_null() {
|
||||
// SAFETY: num_svm_pointers specifies the amount of elements in svm_pointers
|
||||
unsafe { slice::from_raw_parts(svm_pointers.cast(), num_svm_pointers as usize) }.to_vec()
|
||||
} else {
|
||||
// A slice must not be created from a raw null pointer, so simply create
|
||||
// an empty vec instead.
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
// SAFETY: The requirements on `SVMFreeCb::new` match the requirements
|
||||
// imposed by the OpenCL specification. It is the caller's duty to uphold them.
|
||||
let cb_opt = unsafe { SVMFreeCb::new(pfn_free_func, user_data) }.ok();
|
||||
|
|
|
|||
|
|
@ -189,17 +189,22 @@ cl_callback!(
|
|||
|
||||
impl SVMFreeCb {
|
||||
pub fn call(self, queue: &Queue, svm_pointers: &mut [usize]) {
|
||||
let (num_svm_pointers, svm_pointers) = if !svm_pointers.is_empty() {
|
||||
(
|
||||
svm_pointers.len() as cl_uint,
|
||||
svm_pointers.as_mut_ptr().cast(),
|
||||
)
|
||||
} else {
|
||||
// The specification requires that an empty `svm_pointers` list be
|
||||
// null when passed to enqueue and callbacks may expect it to be
|
||||
// passed back in the same manner.
|
||||
(0, std::ptr::null_mut())
|
||||
};
|
||||
|
||||
let cl = cl_command_queue::from_ptr(queue);
|
||||
// SAFETY: `cl` must be a valid pointer to an OpenCL queue, which is where we just got it from.
|
||||
// All other requirements are covered by this callback's type invariants.
|
||||
unsafe {
|
||||
(self.func)(
|
||||
cl,
|
||||
svm_pointers.len() as u32,
|
||||
svm_pointers.as_mut_ptr().cast(),
|
||||
self.data,
|
||||
)
|
||||
};
|
||||
unsafe { (self.func)(cl, num_svm_pointers, svm_pointers, self.data) };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue