Skip to content

Commit 06ff274

Browse files
committed
Merge tag 'rust-xarray-for-v6.16' of https://github.com/Rust-for-Linux/linux into rust-next
Pull XArray updates from Andreas Hindborg: "Introduce Rust support for the 'xarray' data structure: - Add a Rust abstraction for the 'xarray' data structure. This abstraction allows Rust code to leverage the 'xarray' to store types that implement 'ForeignOwnable'. This support is a dependency for memory backing feature of the Rust null block driver, which is waiting to be merged. - Set up an entry in MAINTAINERS for the XArray Rust support. Patches will go to the new Rust XArray tree and then via the Rust subsystem tree for now. 'kernel' crate: - Allow 'ForeignOwnable' to carry information about the pointed-to type. This helps asserting alignment requirements for the pointer passed to the foreign language." * tag 'rust-xarray-for-v6.16' of https://github.com/Rust-for-Linux/linux: MAINTAINERS: add entry for Rust XArray API rust: xarray: Add an abstraction for XArray rust: types: add `ForeignOwnable::PointedTo`
2 parents 373827f + fa61619 commit 06ff274

File tree

12 files changed

+392
-49
lines changed

12 files changed

+392
-49
lines changed

MAINTAINERS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26408,6 +26408,17 @@ F: lib/test_xarray.c
2640826408
F: lib/xarray.c
2640926409
F: tools/testing/radix-tree
2641026410

26411+
XARRAY API [RUST]
26412+
M: Tamir Duberstein <tamird@gmail.com>
26413+
M: Andreas Hindborg <a.hindborg@kernel.org>
26414+
L: rust-for-linux@vger.kernel.org
26415+
S: Supported
26416+
W: https://rust-for-linux.com
26417+
B: https://github.com/Rust-for-Linux/linux/issues
26418+
C: https://rust-for-linux.zulipchat.com
26419+
T: git https://github.com/Rust-for-Linux/linux.git xarray-next
26420+
F: rust/kernel/xarray.rs
26421+
2641126422
XBOX DVD IR REMOTE
2641226423
M: Benjamin Valentin <benpicco@googlemail.com>
2641326424
S: Maintained

rust/bindings/bindings_helper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/tracepoint.h>
3838
#include <linux/wait.h>
3939
#include <linux/workqueue.h>
40+
#include <linux/xarray.h>
4041
#include <trace/events/rust_sample.h>
4142

4243
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
@@ -55,3 +56,8 @@ const gfp_t RUST_CONST_HELPER___GFP_ZERO = __GFP_ZERO;
5556
const gfp_t RUST_CONST_HELPER___GFP_HIGHMEM = ___GFP_HIGHMEM;
5657
const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN;
5758
const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL;
59+
60+
const xa_mark_t RUST_CONST_HELPER_XA_PRESENT = XA_PRESENT;
61+
62+
const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC = XA_FLAGS_ALLOC;
63+
const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 = XA_FLAGS_ALLOC1;

rust/helpers/helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@
3838
#include "vmalloc.c"
3939
#include "wait.c"
4040
#include "workqueue.c"
41+
#include "xarray.c"

rust/helpers/xarray.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/xarray.h>
4+
5+
int rust_helper_xa_err(void *entry)
6+
{
7+
return xa_err(entry);
8+
}
9+
10+
void rust_helper_xa_init_flags(struct xarray *xa, gfp_t flags)
11+
{
12+
return xa_init_flags(xa, flags);
13+
}
14+
15+
int rust_helper_xa_trylock(struct xarray *xa)
16+
{
17+
return xa_trylock(xa);
18+
}
19+
20+
void rust_helper_xa_lock(struct xarray *xa)
21+
{
22+
return xa_lock(xa);
23+
}
24+
25+
void rust_helper_xa_unlock(struct xarray *xa)
26+
{
27+
return xa_unlock(xa);
28+
}

rust/kernel/alloc/kbox.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -360,68 +360,70 @@ where
360360
}
361361
}
362362

363-
impl<T: 'static, A> ForeignOwnable for Box<T, A>
363+
// SAFETY: The `into_foreign` function returns a pointer that is well-aligned.
364+
unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A>
364365
where
365366
A: Allocator,
366367
{
368+
type PointedTo = T;
367369
type Borrowed<'a> = &'a T;
368370
type BorrowedMut<'a> = &'a mut T;
369371

370-
fn into_foreign(self) -> *mut crate::ffi::c_void {
371-
Box::into_raw(self).cast()
372+
fn into_foreign(self) -> *mut Self::PointedTo {
373+
Box::into_raw(self)
372374
}
373375

374-
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
376+
unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self {
375377
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
376378
// call to `Self::into_foreign`.
377-
unsafe { Box::from_raw(ptr.cast()) }
379+
unsafe { Box::from_raw(ptr) }
378380
}
379381

380-
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> &'a T {
382+
unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> &'a T {
381383
// SAFETY: The safety requirements of this method ensure that the object remains alive and
382384
// immutable for the duration of 'a.
383-
unsafe { &*ptr.cast() }
385+
unsafe { &*ptr }
384386
}
385387

386-
unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> &'a mut T {
387-
let ptr = ptr.cast();
388+
unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> &'a mut T {
388389
// SAFETY: The safety requirements of this method ensure that the pointer is valid and that
389390
// nothing else will access the value for the duration of 'a.
390391
unsafe { &mut *ptr }
391392
}
392393
}
393394

394-
impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
395+
// SAFETY: The `into_foreign` function returns a pointer that is well-aligned.
396+
unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
395397
where
396398
A: Allocator,
397399
{
400+
type PointedTo = T;
398401
type Borrowed<'a> = Pin<&'a T>;
399402
type BorrowedMut<'a> = Pin<&'a mut T>;
400403

401-
fn into_foreign(self) -> *mut crate::ffi::c_void {
404+
fn into_foreign(self) -> *mut Self::PointedTo {
402405
// SAFETY: We are still treating the box as pinned.
403-
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast()
406+
Box::into_raw(unsafe { Pin::into_inner_unchecked(self) })
404407
}
405408

406-
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
409+
unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self {
407410
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
408411
// call to `Self::into_foreign`.
409-
unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) }
412+
unsafe { Pin::new_unchecked(Box::from_raw(ptr)) }
410413
}
411414

412-
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a T> {
415+
unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a T> {
413416
// SAFETY: The safety requirements for this function ensure that the object is still alive,
414417
// so it is safe to dereference the raw pointer.
415418
// The safety requirements of `from_foreign` also ensure that the object remains alive for
416419
// the lifetime of the returned value.
417-
let r = unsafe { &*ptr.cast() };
420+
let r = unsafe { &*ptr };
418421

419422
// SAFETY: This pointer originates from a `Pin<Box<T>>`.
420423
unsafe { Pin::new_unchecked(r) }
421424
}
422425

423-
unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Pin<&'a mut T> {
424-
let ptr = ptr.cast();
426+
unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> Pin<&'a mut T> {
425427
// SAFETY: The safety requirements for this function ensure that the object is still alive,
426428
// so it is safe to dereference the raw pointer.
427429
// The safety requirements of `from_foreign` also ensure that the object remains alive for

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub mod transmute;
102102
pub mod types;
103103
pub mod uaccess;
104104
pub mod workqueue;
105+
pub mod xarray;
105106

106107
#[doc(hidden)]
107108
pub use bindings;

rust/kernel/miscdevice.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
200200
// type.
201201
//
202202
// SAFETY: The open call of a file can access the private data.
203-
unsafe { (*raw_file).private_data = ptr.into_foreign() };
203+
unsafe { (*raw_file).private_data = ptr.into_foreign().cast() };
204204

205205
0
206206
}
@@ -211,7 +211,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
211211
/// must be associated with a `MiscDeviceRegistration<T>`.
212212
unsafe extern "C" fn release(_inode: *mut bindings::inode, file: *mut bindings::file) -> c_int {
213213
// SAFETY: The release call of a file owns the private data.
214-
let private = unsafe { (*file).private_data };
214+
let private = unsafe { (*file).private_data }.cast();
215215
// SAFETY: The release call of a file owns the private data.
216216
let ptr = unsafe { <T::Ptr as ForeignOwnable>::from_foreign(private) };
217217

@@ -228,7 +228,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
228228
/// `file` must be a valid file that is associated with a `MiscDeviceRegistration<T>`.
229229
unsafe extern "C" fn ioctl(file: *mut bindings::file, cmd: c_uint, arg: c_ulong) -> c_long {
230230
// SAFETY: The ioctl call of a file can access the private data.
231-
let private = unsafe { (*file).private_data };
231+
let private = unsafe { (*file).private_data }.cast();
232232
// SAFETY: Ioctl calls can borrow the private data of the file.
233233
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
234234

@@ -253,7 +253,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
253253
arg: c_ulong,
254254
) -> c_long {
255255
// SAFETY: The compat ioctl call of a file can access the private data.
256-
let private = unsafe { (*file).private_data };
256+
let private = unsafe { (*file).private_data }.cast();
257257
// SAFETY: Ioctl calls can borrow the private data of the file.
258258
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
259259

@@ -274,7 +274,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
274274
/// - `seq_file` must be a valid `struct seq_file` that we can write to.
275275
unsafe extern "C" fn show_fdinfo(seq_file: *mut bindings::seq_file, file: *mut bindings::file) {
276276
// SAFETY: The release call of a file owns the private data.
277-
let private = unsafe { (*file).private_data };
277+
let private = unsafe { (*file).private_data }.cast();
278278
// SAFETY: Ioctl calls can borrow the private data of the file.
279279
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
280280
// SAFETY:

rust/kernel/pci.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<T: Driver + 'static> Adapter<T> {
8989
extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) {
9090
// SAFETY: The PCI bus only ever calls the remove callback with a valid pointer to a
9191
// `struct pci_dev`.
92-
let ptr = unsafe { bindings::pci_get_drvdata(pdev) };
92+
let ptr = unsafe { bindings::pci_get_drvdata(pdev) }.cast();
9393

9494
// SAFETY: `remove_callback` is only ever called after a successful call to
9595
// `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized

rust/kernel/platform.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<T: Driver + 'static> Adapter<T> {
8080

8181
extern "C" fn remove_callback(pdev: *mut bindings::platform_device) {
8282
// SAFETY: `pdev` is a valid pointer to a `struct platform_device`.
83-
let ptr = unsafe { bindings::platform_get_drvdata(pdev) };
83+
let ptr = unsafe { bindings::platform_get_drvdata(pdev) }.cast();
8484

8585
// SAFETY: `remove_callback` is only ever called after a successful call to
8686
// `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized

rust/kernel/sync/arc.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ pub struct Arc<T: ?Sized> {
140140
_p: PhantomData<ArcInner<T>>,
141141
}
142142

143+
#[doc(hidden)]
143144
#[pin_data]
144145
#[repr(C)]
145-
struct ArcInner<T: ?Sized> {
146+
pub struct ArcInner<T: ?Sized> {
146147
refcount: Opaque<bindings::refcount_t>,
147148
data: T,
148149
}
@@ -371,36 +372,38 @@ impl<T: ?Sized> Arc<T> {
371372
}
372373
}
373374

374-
impl<T: 'static> ForeignOwnable for Arc<T> {
375+
// SAFETY: The `into_foreign` function returns a pointer that is well-aligned.
376+
unsafe impl<T: 'static> ForeignOwnable for Arc<T> {
377+
type PointedTo = ArcInner<T>;
375378
type Borrowed<'a> = ArcBorrow<'a, T>;
376379
type BorrowedMut<'a> = Self::Borrowed<'a>;
377380

378-
fn into_foreign(self) -> *mut crate::ffi::c_void {
379-
ManuallyDrop::new(self).ptr.as_ptr().cast()
381+
fn into_foreign(self) -> *mut Self::PointedTo {
382+
ManuallyDrop::new(self).ptr.as_ptr()
380383
}
381384

382-
unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self {
385+
unsafe fn from_foreign(ptr: *mut Self::PointedTo) -> Self {
383386
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
384387
// call to `Self::into_foreign`.
385-
let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
388+
let inner = unsafe { NonNull::new_unchecked(ptr) };
386389

387390
// SAFETY: By the safety requirement of this function, we know that `ptr` came from
388391
// a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
389392
// holds a reference count increment that is transferrable to us.
390393
unsafe { Self::from_inner(inner) }
391394
}
392395

393-
unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
396+
unsafe fn borrow<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> {
394397
// SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
395398
// call to `Self::into_foreign`.
396-
let inner = unsafe { NonNull::new_unchecked(ptr.cast::<ArcInner<T>>()) };
399+
let inner = unsafe { NonNull::new_unchecked(ptr) };
397400

398401
// SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
399402
// for the lifetime of the returned value.
400403
unsafe { ArcBorrow::new(inner) }
401404
}
402405

403-
unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
406+
unsafe fn borrow_mut<'a>(ptr: *mut Self::PointedTo) -> ArcBorrow<'a, T> {
404407
// SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
405408
// requirements for `borrow`.
406409
unsafe { Self::borrow(ptr) }

0 commit comments

Comments
 (0)