Skip to content

Commit cd0bbd5

Browse files
committed
Merge tag 'regulator-fix-v7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fix from Mark Brown: "A fix from Alice for the rust bindings, they didn't handle the stub implementation of the C API used when CONFIG_REGULATOR is disabled leading to undefined behaviour" * tag 'regulator-fix-v7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: rust: regulator: do not assume that regulator_get() returns non-null
2 parents 3005200 + 8121353 commit cd0bbd5

1 file changed

Lines changed: 18 additions & 15 deletions

File tree

rust/kernel/regulator.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ use crate::{
2323
prelude::*,
2424
};
2525

26-
use core::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull};
26+
use core::{
27+
marker::PhantomData,
28+
mem::ManuallyDrop, //
29+
};
2730

2831
mod private {
2932
pub trait Sealed {}
@@ -229,15 +232,17 @@ pub fn devm_enable_optional(dev: &Device<Bound>, name: &CStr) -> Result {
229232
///
230233
/// # Invariants
231234
///
232-
/// - `inner` is a non-null wrapper over a pointer to a `struct
233-
/// regulator` obtained from [`regulator_get()`].
235+
/// - `inner` is a pointer obtained from a successful call to
236+
/// [`regulator_get()`]. It is treated as an opaque token that may only be
237+
/// accessed using C API methods (e.g., it may be `NULL` if the C API returns
238+
/// `NULL`).
234239
///
235240
/// [`regulator_get()`]: https://docs.kernel.org/driver-api/regulator.html#c.regulator_get
236241
pub struct Regulator<State>
237242
where
238243
State: RegulatorState,
239244
{
240-
inner: NonNull<bindings::regulator>,
245+
inner: *mut bindings::regulator,
241246
_phantom: PhantomData<State>,
242247
}
243248

@@ -249,7 +254,7 @@ impl<T: RegulatorState> Regulator<T> {
249254
// SAFETY: Safe as per the type invariants of `Regulator`.
250255
to_result(unsafe {
251256
bindings::regulator_set_voltage(
252-
self.inner.as_ptr(),
257+
self.inner,
253258
min_voltage.as_microvolts(),
254259
max_voltage.as_microvolts(),
255260
)
@@ -259,7 +264,7 @@ impl<T: RegulatorState> Regulator<T> {
259264
/// Gets the current voltage of the regulator.
260265
pub fn get_voltage(&self) -> Result<Voltage> {
261266
// SAFETY: Safe as per the type invariants of `Regulator`.
262-
let voltage = unsafe { bindings::regulator_get_voltage(self.inner.as_ptr()) };
267+
let voltage = unsafe { bindings::regulator_get_voltage(self.inner) };
263268

264269
to_result(voltage).map(|()| Voltage::from_microvolts(voltage))
265270
}
@@ -270,10 +275,8 @@ impl<T: RegulatorState> Regulator<T> {
270275
// received from the C code.
271276
from_err_ptr(unsafe { bindings::regulator_get(dev.as_raw(), name.as_char_ptr()) })?;
272277

273-
// SAFETY: We can safely trust `inner` to be a pointer to a valid
274-
// regulator if `ERR_PTR` was not returned.
275-
let inner = unsafe { NonNull::new_unchecked(inner) };
276-
278+
// INVARIANT: `inner` is a pointer obtained from `regulator_get()`, and
279+
// the call was successful.
277280
Ok(Self {
278281
inner,
279282
_phantom: PhantomData,
@@ -282,12 +285,12 @@ impl<T: RegulatorState> Regulator<T> {
282285

283286
fn enable_internal(&self) -> Result {
284287
// SAFETY: Safe as per the type invariants of `Regulator`.
285-
to_result(unsafe { bindings::regulator_enable(self.inner.as_ptr()) })
288+
to_result(unsafe { bindings::regulator_enable(self.inner) })
286289
}
287290

288291
fn disable_internal(&self) -> Result {
289292
// SAFETY: Safe as per the type invariants of `Regulator`.
290-
to_result(unsafe { bindings::regulator_disable(self.inner.as_ptr()) })
293+
to_result(unsafe { bindings::regulator_disable(self.inner) })
291294
}
292295
}
293296

@@ -349,7 +352,7 @@ impl<T: IsEnabled> Regulator<T> {
349352
/// Checks if the regulator is enabled.
350353
pub fn is_enabled(&self) -> bool {
351354
// SAFETY: Safe as per the type invariants of `Regulator`.
352-
unsafe { bindings::regulator_is_enabled(self.inner.as_ptr()) != 0 }
355+
unsafe { bindings::regulator_is_enabled(self.inner) != 0 }
353356
}
354357
}
355358

@@ -359,11 +362,11 @@ impl<T: RegulatorState> Drop for Regulator<T> {
359362
// SAFETY: By the type invariants, we know that `self` owns a
360363
// reference on the enabled refcount, so it is safe to relinquish it
361364
// now.
362-
unsafe { bindings::regulator_disable(self.inner.as_ptr()) };
365+
unsafe { bindings::regulator_disable(self.inner) };
363366
}
364367
// SAFETY: By the type invariants, we know that `self` owns a reference,
365368
// so it is safe to relinquish it now.
366-
unsafe { bindings::regulator_put(self.inner.as_ptr()) };
369+
unsafe { bindings::regulator_put(self.inner) };
367370
}
368371
}
369372

0 commit comments

Comments
 (0)