Skip to content

Commit 72097f9

Browse files
Danilo Krummrichgregkh
authored andcommitted
rust: drm: don't pass the address of drm::Device to drm_dev_put()
[ Upstream commit 3600772 ] In drm_dev_put() call in AlwaysRefCounted::dec_ref() we rely on struct drm_device to be the first field in drm::Device, whereas everywhere else we correctly obtain the address of the actual struct drm_device. Analogous to the from_drm_device() helper, provide the into_drm_device() helper in order to address this. Fixes: 1e4b889 ("rust: drm: add device abstraction") Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250731154919.4132-5-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f46b0e3 commit 72097f9

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

rust/kernel/drm/device.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,13 @@ impl<T: drm::Driver> Device<T> {
120120
// - `raw_data` is a valid pointer to uninitialized memory.
121121
// - `raw_data` will not move until it is dropped.
122122
unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| {
123-
// SAFETY: `__drm_dev_alloc()` was successful, hence `raw_drm` must be valid and the
123+
// SAFETY: `raw_drm` is a valid pointer to `Self`, given that `__drm_dev_alloc` was
124+
// successful.
125+
let drm_dev = unsafe { Self::into_drm_device(raw_drm) };
126+
127+
// SAFETY: `__drm_dev_alloc()` was successful, hence `drm_dev` must be valid and the
124128
// refcount must be non-zero.
125-
unsafe { bindings::drm_dev_put(ptr::addr_of_mut!((*raw_drm.as_ptr()).dev).cast()) };
129+
unsafe { bindings::drm_dev_put(drm_dev) };
126130
})?;
127131

128132
// SAFETY: The reference count is one, and now we take ownership of that reference as a
@@ -145,6 +149,14 @@ impl<T: drm::Driver> Device<T> {
145149
unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut()
146150
}
147151

152+
/// # Safety
153+
///
154+
/// `ptr` must be a valid pointer to `Self`.
155+
unsafe fn into_drm_device(ptr: NonNull<Self>) -> *mut bindings::drm_device {
156+
// SAFETY: By the safety requirements of this function, `ptr` is a valid pointer to `Self`.
157+
unsafe { &raw mut (*ptr.as_ptr()).dev }.cast()
158+
}
159+
148160
/// Not intended to be called externally, except via declare_drm_ioctls!()
149161
///
150162
/// # Safety
@@ -194,8 +206,11 @@ unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> {
194206
}
195207

196208
unsafe fn dec_ref(obj: NonNull<Self>) {
209+
// SAFETY: `obj` is a valid pointer to `Self`.
210+
let drm_dev = unsafe { Self::into_drm_device(obj) };
211+
197212
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
198-
unsafe { bindings::drm_dev_put(obj.cast().as_ptr()) };
213+
unsafe { bindings::drm_dev_put(drm_dev) };
199214
}
200215
}
201216

0 commit comments

Comments
 (0)