diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index 0e3989d2d10..0e562151f9c 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -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(); diff --git a/src/gallium/frontends/rusticl/api/types.rs b/src/gallium/frontends/rusticl/api/types.rs index fb094227138..351f898cd75 100644 --- a/src/gallium/frontends/rusticl/api/types.rs +++ b/src/gallium/frontends/rusticl/api/types.rs @@ -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) }; } }