* [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice
@ 2026-04-08 13:59 Sidong Yang
2026-04-08 13:59 ` [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h Sidong Yang
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 13:59 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
This series introduces Rust abstractions for io_uring commands
(`IORING_OP_URING_CMD`) and wires them up to the miscdevice framework,
allowing Rust drivers to handle io_uring passthrough commands.
The series is structured as follows:
1. Add io_uring C headers to Rust bindings.
2. Zero-init pdu in io_uring_cmd_prep() to avoid UB from stale data.
3. Core io_uring Rust abstractions (IoUringCmd, QueuedIoUringCmd,
IoUringSqe, UringCmdAction type-state pattern).
4. MiscDevice trait extension with uring_cmd callback.
5. Sample demonstrating async uring_cmd handling via workqueue.
The sample completes asynchronously using a workqueue rather than
`io_uring_cmd_complete_in_task()`. The latter is primarily needed
when completion originates from IRQ/softirq context (e.g. NVMe),
whereas workqueue workers already run in process context and can
safely call `io_uring_cmd_done()` directly. A Rust binding for
`complete_in_task` can be added in a follow-up series.
Copy-based `read_pdu()`/`write_pdu()` are kept instead of returning
`&T`/`&mut T` references because the PDU is a `[u8; 32]` byte array
whose alignment may not satisfy `T`'s requirements.
Changes since v3:
- read_pdu(): replaced MaybeUninit + copy_nonoverlapping(c_void) with
read_unaligned (Caleb, Benno).
- write_pdu(): fixed c_void cast to u8 in copy_nonoverlapping (Benno).
- IoUringSqe::opcode(): use read_volatile for SQE field access (Caleb).
- IoUringSqe::cmd_data(): removed unnecessary runtime opcode check;
safety is guaranteed by construction since IoUringSqe can only be
obtained from IoUringCmd::sqe() inside a uring_cmd callback (Caleb).
- Removed unused mut in sample WorkItem::run() (compiler warning).
Changes since v2:
- Adopted type-state pattern for IoUringCmd (IoUringCmd -> QueuedIoUringCmd)
to enforce correct completion flow at compile time.
- UringCmdAction enum with Complete/Queued variants prevents returning
Queued without holding a QueuedIoUringCmd handle.
- Fixed error code handling (use proper kernel error types).
- Suppressed unused result warning with `let _ = ...enqueue(work)`.
Sidong Yang (5):
rust: bindings: add io_uring headers in bindings_helper.h
io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB
rust: io_uring: introduce rust abstraction for io-uring cmd
rust: miscdevice: Add `uring_cmd` support
samples: rust: Add `uring_cmd` example to `rust_misc_device`
io_uring/uring_cmd.c | 1 +
rust/bindings/bindings_helper.h | 2 +
rust/helpers/helpers.c | 1 +
rust/helpers/io_uring.c | 9 +
rust/kernel/io_uring.rs | 457 +++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
rust/kernel/miscdevice.rs | 79 ++++++
samples/rust/rust_misc_device.rs | 53 +++-
8 files changed, 602 insertions(+), 1 deletion(-)
create mode 100644 rust/helpers/io_uring.c
create mode 100644 rust/kernel/io_uring.rs
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
@ 2026-04-08 13:59 ` Sidong Yang
2026-04-08 14:31 ` Miguel Ojeda
2026-04-08 13:59 ` [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB Sidong Yang
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 13:59 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
This patch adds two headers io_uring.h io_uring/cmd.h in bindings_helper
for implementing rust io_uring abstraction.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
rust/bindings/bindings_helper.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index faf3ee634ced..01f2c6044ae5 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -88,6 +88,8 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/xarray.h>
+#include <linux/io_uring.h>
+#include <linux/io_uring/cmd.h>
#include <trace/events/rust_sample.h>
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
2026-04-08 13:59 ` [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h Sidong Yang
@ 2026-04-08 13:59 ` Sidong Yang
2026-04-09 5:27 ` Greg Kroah-Hartman
2026-04-08 14:00 ` [PATCH v4 3/5] rust: io_uring: introduce rust abstraction for io-uring cmd Sidong Yang
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 13:59 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
The pdu field in io_uring_cmd may contain stale data when a request
object is recycled from the slab cache. Accessing uninitialized or
garbage memory can lead to undefined behavior in users of the pdu.
Ensure the pdu buffer is cleared during io_uring_cmd_prep() so that
each command starts from a well-defined state. This avoids exposing
uninitialized memory and prevents potential misinterpretation of data
from previous requests.
No functional change is intended other than guaranteeing that pdu is
always zero-initialized before use.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
io_uring/uring_cmd.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
index ee7b49f47cb5..fa3a6f832460 100644
--- a/io_uring/uring_cmd.c
+++ b/io_uring/uring_cmd.c
@@ -209,6 +209,7 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (!ac)
return -ENOMEM;
ioucmd->sqe = sqe;
+ memset(&ioucmd->pdu, 0, sizeof(ioucmd->pdu));
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/5] rust: io_uring: introduce rust abstraction for io-uring cmd
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
2026-04-08 13:59 ` [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h Sidong Yang
2026-04-08 13:59 ` [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB Sidong Yang
@ 2026-04-08 14:00 ` Sidong Yang
2026-04-08 14:00 ` [PATCH v4 4/5] rust: miscdevice: Add `uring_cmd` support Sidong Yang
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 14:00 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
Implement the io-uring abstractions needed for miscdevices and other
char devices that have io-uring command interface.
* `io_uring::IoUringCmd` : Rust abstraction for `io_uring_cmd` which
will be used as arg for `MiscDevice::uring_cmd()`. And driver can get
`cmd_op` sent from userspace. Also it has `flags` which includes option
that is reissued.
* `io_uring::IoUringSqe` : Rust abstraction for `io_uring_sqe` which
can be obtained from `IoUringCmd::sqe()` and driver could get `cmd_data`
from userspace. Also `IoUringSqe` has more data like opcode which can be used
in drivers.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
rust/helpers/helpers.c | 1 +
rust/helpers/io_uring.c | 9 +
rust/kernel/io_uring.rs | 457 ++++++++++++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
4 files changed, 468 insertions(+)
create mode 100644 rust/helpers/io_uring.c
create mode 100644 rust/kernel/io_uring.rs
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index e05c6e7e4abb..3fa2b3d9f83a 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -62,6 +62,7 @@
#include "irq.c"
#include "fs.c"
#include "io.c"
+#include "io_uring.c"
#include "jump_label.c"
#include "kunit.c"
#include "maple_tree.c"
diff --git a/rust/helpers/io_uring.c b/rust/helpers/io_uring.c
new file mode 100644
index 000000000000..818859867b34
--- /dev/null
+++ b/rust/helpers/io_uring.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/io_uring/cmd.h>
+
+__rust_helper void rust_helper_io_uring_cmd_done32(struct io_uring_cmd *cmd, s32 ret,
+ u64 res2, unsigned int issue_flags)
+{
+ io_uring_cmd_done32(cmd, ret, res2, issue_flags);
+}
diff --git a/rust/kernel/io_uring.rs b/rust/kernel/io_uring.rs
new file mode 100644
index 000000000000..adec60537cfb
--- /dev/null
+++ b/rust/kernel/io_uring.rs
@@ -0,0 +1,457 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: (C) 2025 Furiosa AI
+
+//! Abstractions for io-uring.
+//!
+//! This module provides abstractions for the io-uring interface for character devices.
+//!
+//!
+//! C headers: [`include/linux/io_uring/cmd.h`](srctree/include/linux/io_uring/cmd.h) and
+//! [`include/linux/io_uring/io_uring.h`](srctree/include/linux/io_uring/io_uring.h)
+
+use core::ptr::NonNull;
+
+use crate::error::from_result;
+use crate::transmute::{AsBytes, FromBytes};
+use crate::{fs::File, types::Opaque};
+
+use crate::prelude::*;
+
+/// Size in bytes of the protocol data unit (PDU) embedded in `io_uring_cmd`.
+///
+/// Matches the size of the `pdu` field in `struct io_uring_cmd` as defined in
+/// `include/linux/io_uring/cmd.h`.
+pub(crate) const PDU_SIZE: usize = 32;
+
+/// Opcode of an [`IoUringSqe`].
+///
+/// Each submission queue entry in io_uring specifies an operation
+/// to perform, such as read, write, or a driver-specific `URING_CMD`.
+#[repr(transparent)]
+#[derive(PartialEq)]
+pub struct Opcode(u8);
+
+impl Opcode {
+ /// Driver-specific passthrough command.
+ pub const URING_CMD: Self = Self(bindings::io_uring_op_IORING_OP_URING_CMD as u8);
+}
+
+/// A fresh `io_uring_cmd` received from the driver callback.
+///
+/// Represents a submission received from userspace via `IORING_OP_URING_CMD`.
+/// A driver obtains this from the `uring_cmd` callback in [`crate::miscdevice::MiscDevice`].
+///
+/// The driver must either complete the command synchronously by calling
+/// [`Self::complete`], or queue it for asynchronous completion by calling
+/// [`Self::queue`], which yields a [`QueuedIoUringCmd`] handle.
+///
+/// # Invariants
+///
+/// `self.inner` is non-null, properly aligned, and points to a valid, live
+/// `bindings::io_uring_cmd` for the duration of the driver callback.
+pub struct IoUringCmd {
+ inner: NonNull<bindings::io_uring_cmd>,
+}
+
+// SAFETY: `io_uring_cmd` is a kernel-allocated structure. The kernel
+// guarantees that it remains alive until the driver either returns a
+// non-`EIOCBQUEUED` result or calls `io_uring_cmd_done32()`. Moving the
+// pointer to another thread is safe: the kernel object is not tied to any
+// particular CPU or task context.
+unsafe impl Send for IoUringCmd {}
+
+// SAFETY: All `&self` methods on `IoUringCmd` only read from the underlying
+// `io_uring_cmd` (cmd_op, flags, sqe, file). `write_pdu` takes `&mut self`,
+// so the borrow checker prevents concurrent mutable access. Sharing
+// `&IoUringCmd` across threads is therefore safe.
+unsafe impl Sync for IoUringCmd {}
+
+/// An [`IoUringCmd`] that has been queued for asynchronous completion.
+///
+/// The only way to obtain a `QueuedIoUringCmd` is through [`IoUringCmd::queue`],
+/// which ensures the command was properly handed off to the async path before
+/// [`UringCmdAction::Queued`] is returned to the vtable.
+///
+/// Call [`Self::done`] exactly once to post the completion to userspace.
+///
+/// # Invariants
+///
+/// `self.inner` is non-null, properly aligned, and points to a valid, live
+/// `bindings::io_uring_cmd` until [`Self::done`] is called.
+pub struct QueuedIoUringCmd {
+ inner: NonNull<bindings::io_uring_cmd>,
+}
+
+// SAFETY: Same reasoning as for `IoUringCmd`. After `queue()`, the handle is
+// intentionally moved to a different context (e.g. a workqueue) to call
+// `done()` later.
+unsafe impl Send for QueuedIoUringCmd {}
+
+// SAFETY: All `&self` methods on `QueuedIoUringCmd` only read from the
+// underlying `io_uring_cmd`.
+unsafe impl Sync for QueuedIoUringCmd {}
+
+/// Proof that a `uring_cmd` request completed synchronously.
+pub struct CompleteAction {
+ ret: i32,
+}
+
+impl CompleteAction {
+ /// Returns the userspace result for this synchronous completion.
+ #[inline]
+ pub fn ret(&self) -> i32 {
+ self.ret
+ }
+}
+
+/// Proof that a `uring_cmd` request was queued for asynchronous completion.
+///
+/// This type has a private field and can only be constructed inside this module,
+/// so it can only be obtained through [`IoUringCmd::queue`].
+pub struct QueuedAction {
+ _private: (),
+}
+
+/// Completion mode for `uring_cmd`.
+pub enum UringCmdAction {
+ /// Request is completed synchronously and returns this result to userspace.
+ Complete(CompleteAction),
+ /// Request is queued for asynchronous completion.
+ ///
+ /// This variant can only be constructed by calling [`IoUringCmd::queue`],
+ /// which enforces that the caller holds a [`QueuedIoUringCmd`] handle and
+ /// will eventually call [`QueuedIoUringCmd::done`].
+ Queued(QueuedAction),
+}
+
+impl IoUringCmd {
+ /// Returns the `cmd_op` associated with this command.
+ #[inline]
+ pub fn cmd_op(&self) -> u32 {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ unsafe { (*self.as_raw()).cmd_op }
+ }
+
+ /// Returns the flags field of this command.
+ ///
+ /// The returned value is `io_uring_cmd.flags`, which is a combination of:
+ /// - User-set flags from `sqe->uring_cmd_flags` (bits 0–1):
+ /// `IORING_URING_CMD_FIXED`, `IORING_URING_CMD_MULTISHOT`.
+ /// - Kernel-set flags (bits 30–31):
+ /// `IORING_URING_CMD_CANCELABLE`, `IORING_URING_CMD_REISSUE`.
+ ///
+ /// Note: this is **not** the `issue_flags` parameter passed to the
+ /// `uring_cmd` callback, which carries `IO_URING_F_*` flags such as
+ /// `IO_URING_F_NONBLOCK`.
+ #[inline]
+ pub fn flags(&self) -> u32 {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ unsafe { (*self.as_raw()).flags }
+ }
+
+ /// Reads the protocol data unit (PDU) as a value of type `T`.
+ ///
+ /// # Errors
+ ///
+ /// Returns [`EINVAL`] if `size_of::<T>()` exceeds the PDU size.
+ #[inline]
+ pub fn read_pdu<T: FromBytes>(&self) -> Result<T> {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let inner = unsafe { &*self.inner.as_ref() };
+
+ if size_of::<T>() > inner.pdu.len() {
+ return Err(EINVAL);
+ }
+
+ let ptr = inner.pdu.as_ptr() as *const T;
+
+ // SAFETY: `ptr` is a valid pointer derived from `self.inner`, which
+ // is guaranteed by the type invariant. `size_of::<T>()` bytes are
+ // available in the PDU (checked above). `read_unaligned` is used
+ // because the PDU is a byte array and may not satisfy `T`'s alignment.
+ // `T: FromBytes` guarantees that every bit-pattern is a valid value.
+ Ok(unsafe { core::ptr::read_unaligned(ptr) })
+ }
+
+ /// Writes `value` to the PDU of this command.
+ ///
+ /// # Errors
+ ///
+ /// Returns [`EINVAL`] if `size_of::<T>()` exceeds the PDU size.
+ #[inline]
+ pub fn write_pdu<T: AsBytes>(&mut self, value: &T) -> Result<()> {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let inner = unsafe { self.inner.as_mut() };
+
+ let len = size_of::<T>();
+ if len > inner.pdu.len() {
+ return Err(EINVAL);
+ }
+
+ let src = (value as *const T).cast::<u8>();
+ let dst = &raw mut inner.pdu as *mut u8;
+
+ // SAFETY:
+ // * `src` points to valid memory because `T: AsBytes`.
+ // * `dst` is valid and derived from `self.inner`, which is guaranteed
+ // by the type invariant.
+ // * The byte count does not exceed the PDU length (checked above).
+ unsafe {
+ core::ptr::copy_nonoverlapping(src, dst, len);
+ }
+
+ Ok(())
+ }
+
+ /// Constructs an [`IoUringCmd`] from a raw pointer.
+ ///
+ /// # Safety
+ ///
+ /// The caller must guarantee that:
+ /// - `ptr` is non-null, properly aligned, and points to a valid, initialised
+ /// `bindings::io_uring_cmd`.
+ /// - The pointed-to object remains alive until the driver either returns a
+ /// non-`EIOCBQUEUED` value or calls [`QueuedIoUringCmd::done`].
+ /// - No other mutable reference to the same object exists for the duration
+ /// of the returned handle's lifetime.
+ #[inline]
+ pub(crate) unsafe fn from_raw(ptr: *mut bindings::io_uring_cmd) -> Result<Self> {
+ let Some(inner) = NonNull::new(ptr) else {
+ return Err(EINVAL);
+ };
+
+ Ok(Self { inner })
+ }
+
+ /// Returns a raw pointer to the underlying `io_uring_cmd`.
+ #[inline]
+ fn as_raw(&self) -> *mut bindings::io_uring_cmd {
+ self.inner.as_ptr()
+ }
+
+ /// Returns the file associated with this command.
+ ///
+ /// The returned reference is valid for the lifetime of `&self`. The kernel
+ /// holds a reference to the file for the entire lifetime of the enclosing
+ /// `io_kiocb`, so this is safe to call at any point while `IoUringCmd` is
+ /// alive.
+ #[inline]
+ pub fn file(&self) -> &File {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let file = unsafe { (*self.as_raw()).file };
+
+ // SAFETY:
+ // * The `io_kiocb` holds a reference to the file for its entire
+ // lifetime, so `file` is valid and has a positive refcount.
+ // * There is no active fdget_pos region on the file on this thread.
+ unsafe { File::from_raw_file(file) }
+ }
+
+ /// Returns a reference to the [`IoUringSqe`] associated with this command.
+ #[inline]
+ pub fn sqe(&self) -> &IoUringSqe {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let sqe = unsafe { self.inner.as_ref().sqe };
+ // SAFETY: `sqe` is a valid pointer set by the io_uring core during
+ // submission queue entry preparation and remains valid for the lifetime
+ // of the `io_uring_cmd`.
+ unsafe { IoUringSqe::from_raw(sqe) }
+ }
+
+ /// Marks this command as completed synchronously with the provided return value.
+ ///
+ /// The vtable will return `ret` directly to the io_uring core, which posts
+ /// the completion queue entry. No further action is needed from the driver.
+ #[inline]
+ pub fn complete(self, ret: i32) -> UringCmdAction {
+ UringCmdAction::Complete(CompleteAction { ret })
+ }
+
+ /// Queues this command for asynchronous completion.
+ ///
+ /// Returns a [`UringCmdAction::Queued`] token to return from the driver
+ /// callback and a [`QueuedIoUringCmd`] handle that must be used to call
+ /// [`QueuedIoUringCmd::done`] at a later point.
+ ///
+ /// Because [`QueuedAction`] has a private field, [`UringCmdAction::Queued`]
+ /// can **only** be constructed through this method. This prevents a driver
+ /// from accidentally returning `Queued` after already completing the command
+ /// via `done()`.
+ #[inline]
+ pub fn queue(self) -> (UringCmdAction, QueuedIoUringCmd) {
+ let queued = QueuedIoUringCmd { inner: self.inner };
+ (UringCmdAction::Queued(QueuedAction { _private: () }), queued)
+ }
+}
+
+impl QueuedIoUringCmd {
+ /// Returns the `cmd_op` associated with this command.
+ #[inline]
+ pub fn cmd_op(&self) -> u32 {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ unsafe { (*self.inner.as_ptr()).cmd_op }
+ }
+
+ /// Returns the file associated with this command.
+ ///
+ /// See [`IoUringCmd::file`] for safety details.
+ #[inline]
+ pub fn file(&self) -> &File {
+ // SAFETY: Same as `IoUringCmd::file`.
+ let file = unsafe { (*self.inner.as_ptr()).file };
+ // SAFETY: The `io_kiocb` holds a reference to the file for its entire
+ // lifetime, so `file` is valid and has a positive refcount.
+ unsafe { File::from_raw_file(file) }
+ }
+
+ /// Reads the PDU as a value of type `T`.
+ ///
+ /// See [`IoUringCmd::read_pdu`] for details and error conditions.
+ #[inline]
+ pub fn read_pdu<T: FromBytes>(&self) -> Result<T> {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let inner = unsafe { &*self.inner.as_ref() };
+
+ if size_of::<T>() > inner.pdu.len() {
+ return Err(EINVAL);
+ }
+
+ let ptr = inner.pdu.as_ptr() as *const T;
+
+ // SAFETY: Same as `IoUringCmd::read_pdu`.
+ Ok(unsafe { core::ptr::read_unaligned(ptr) })
+ }
+
+ /// Writes `value` to the PDU of this command.
+ ///
+ /// See [`IoUringCmd::write_pdu`] for details and error conditions.
+ #[inline]
+ pub fn write_pdu<T: AsBytes>(&mut self, value: &T) -> Result<()> {
+ // SAFETY: `self.inner` is guaranteed by the type invariant to point
+ // to a live `io_uring_cmd`, so dereferencing is safe.
+ let inner = unsafe { self.inner.as_mut() };
+
+ let len = size_of::<T>();
+ if len > inner.pdu.len() {
+ return Err(EINVAL);
+ }
+
+ let src = (value as *const T).cast::<u8>();
+ let dst = &raw mut inner.pdu as *mut u8;
+
+ // SAFETY: Same as `IoUringCmd::write_pdu`.
+ unsafe {
+ core::ptr::copy_nonoverlapping(src, dst, len);
+ }
+
+ Ok(())
+ }
+
+ /// Posts the asynchronous completion to userspace.
+ ///
+ /// # Parameters
+ ///
+ /// - `ret`: Result to return to userspace.
+ /// - `res2`: Extra result word for `IORING_SETUP_CQE32` big-CQE rings;
+ /// pass `0` if not needed.
+ /// - `issue_flags`: The `issue_flags` value received by the `uring_cmd`
+ /// callback; pass it through unchanged.
+ #[inline]
+ pub fn done(self, ret: Result<i32>, res2: u64, issue_flags: u32) {
+ let ret = from_result(|| ret);
+ // SAFETY: `self.inner` is a valid `io_uring_cmd` that was previously
+ // queued (returned `EIOCBQUEUED` to io_uring). The kernel keeps the
+ // `io_kiocb` alive until this call completes.
+ unsafe {
+ bindings::io_uring_cmd_done32(self.inner.as_ptr(), ret, res2, issue_flags);
+ }
+ }
+}
+
+/// A Rust abstraction for `io_uring_sqe`.
+///
+/// Represents a Submission Queue Entry (SQE) that describes an I/O operation
+/// to be executed by the io_uring subsystem. Obtain an instance from
+/// [`IoUringCmd::sqe`].
+///
+/// This type should not be constructed directly by drivers.
+///
+/// # Invariants
+///
+/// `self.inner` always points to a valid, live `bindings::io_uring_sqe`.
+/// The `repr(transparent)` attribute guarantees the same memory layout as the
+/// underlying binding.
+#[repr(transparent)]
+pub struct IoUringSqe {
+ inner: Opaque<bindings::io_uring_sqe>,
+}
+
+impl IoUringSqe {
+ /// Returns the opcode of this SQE.
+ pub fn opcode(&self) -> Opcode {
+ // SAFETY: `self.inner` guaranteed by the type invariant to point
+ // to a live `io_uring_sqe`, so dereferencing is safe. Volatile
+ // read is used because the SQE may reside in memory shared with
+ // userspace.
+ Opcode(unsafe { core::ptr::addr_of!((*self.inner.get()).opcode).read_volatile() })
+ }
+
+ /// Reads the inline `cmd` data of this SQE as a value of type `T`.
+ ///
+ /// Only the standard `io_uring_sqe` layout is supported
+ /// (`IORING_SETUP_SQE128` is not handled here).
+ ///
+ /// # Errors
+ ///
+ /// Returns [`EINVAL`] if `size_of::<T>()` exceeds the inline command buffer.
+ pub fn cmd_data<T: FromBytes>(&self) -> Result<T> {
+ // SAFETY: `self.inner` guaranteed by the type invariant to point
+ // to a live `io_uring_sqe`, so dereferencing is safe.
+ let sqe = unsafe { &*self.inner.get() };
+
+ // SAFETY: Accessing the `sqe.cmd` union field is safe because
+ // `IoUringSqe` can only be obtained from `IoUringCmd::sqe()`, which
+ // is only available inside a `uring_cmd` callback where the opcode
+ // is guaranteed to be `IORING_OP_URING_CMD` by the io_uring core.
+ let cmd = unsafe { sqe.__bindgen_anon_6.cmd.as_ref() };
+ let cmd_len = size_of_val(&sqe.__bindgen_anon_6.bindgen_union_field);
+
+ if cmd_len < size_of::<T>() {
+ return Err(EINVAL);
+ }
+
+ let cmd_ptr = cmd.as_ptr() as *const T;
+
+ // SAFETY: `cmd_ptr` is valid, derived from `self.inner` which is
+ // guaranteed by the type invariant. `read_unaligned` is used because
+ // the cmd data may not satisfy `T`'s alignment requirements.
+ // `T: FromBytes` guarantees that every bit-pattern is a valid value.
+ Ok(unsafe { core::ptr::read_unaligned(cmd_ptr) })
+ }
+
+ /// Constructs an [`IoUringSqe`] reference from a raw pointer.
+ ///
+ /// # Safety
+ ///
+ /// The caller must guarantee that:
+ /// - `ptr` is non-null, properly aligned, and points to a valid, initialised
+ /// `bindings::io_uring_sqe`.
+ /// - The pointed-to object remains valid for the entire lifetime `'a`.
+ /// - No mutable access to the same object occurs while the returned
+ /// reference is alive.
+ #[inline]
+ pub(crate) unsafe fn from_raw<'a>(ptr: *const bindings::io_uring_sqe) -> &'a IoUringSqe {
+ // SAFETY: The caller guarantees that the pointer is not dangling and
+ // stays valid for the duration of 'a. The cast is valid because
+ // `IoUringSqe` is `repr(transparent)` over `bindings::io_uring_sqe`.
+ unsafe { &*ptr.cast() }
+ }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 0fa9d820fe7c..235d1d03dde2 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -76,6 +76,7 @@
pub mod impl_flags;
pub mod init;
pub mod io;
+pub mod io_uring;
pub mod ioctl;
pub mod iommu;
pub mod iov;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 4/5] rust: miscdevice: Add `uring_cmd` support
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
` (2 preceding siblings ...)
2026-04-08 14:00 ` [PATCH v4 3/5] rust: io_uring: introduce rust abstraction for io-uring cmd Sidong Yang
@ 2026-04-08 14:00 ` Sidong Yang
2026-04-08 14:00 ` [PATCH v4 5/5] samples: rust: Add `uring_cmd` example to `rust_misc_device` Sidong Yang
2026-04-09 5:25 ` [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Greg Kroah-Hartman
5 siblings, 0 replies; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 14:00 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
This patch introduces support for `uring_cmd` to the `miscdevice`
framework. This is achieved by adding a new `uring_cmd` method to the
`MiscDevice` trait and wiring it up to the corresponding
`file_operations` entry.
The `uring_cmd` function provides a mechanism for `io_uring` to issue
commands to a device driver.
The new `uring_cmd` method takes the device, an `IoUringCmd` object,
and issue flags as arguments. The `IoUringCmd` object is a safe Rust
abstraction around the raw `io_uring_cmd` struct.
To enable `uring_cmd` for a specific misc device, the `HAS_URING_CMD`
constant must be set to `true` in the `MiscDevice` implementation.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
rust/kernel/miscdevice.rs | 79 +++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index c3c2052c9206..7fe6021c2c96 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -14,6 +14,7 @@
error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR},
ffi::{c_int, c_long, c_uint, c_ulong},
fs::{File, Kiocb},
+ io_uring::{self, IoUringCmd, UringCmdAction},
iov::{IovIterDest, IovIterSource},
mm::virt::VmaNew,
prelude::*,
@@ -190,6 +191,29 @@ fn show_fdinfo(
) {
build_error!(VTABLE_DEFAULT_ERROR)
}
+
+ /// Handler for `uring_cmd`.
+ ///
+ /// Invoked when userspace submits an `IORING_OP_URING_CMD` entry to the
+ /// io-uring submission queue for a file backed by this driver.
+ ///
+ /// The driver must either complete the command synchronously by calling
+ /// [`IoUringCmd::complete`] and returning `Ok(UringCmdAction::Complete(_))`,
+ /// or queue it for asynchronous completion by calling [`IoUringCmd::queue`]
+ /// and returning `Ok(UringCmdAction::Queued(_))`. In the latter case the
+ /// driver must eventually call [`crate::io_uring::QueuedIoUringCmd::done`]
+ /// to post the completion to userspace.
+ ///
+ /// `issue_flags` carries `IO_URING_F_*` flags (e.g. `IO_URING_F_NONBLOCK`)
+ /// and should be forwarded to [`crate::io_uring::QueuedIoUringCmd::done`]
+ /// unchanged when completing asynchronously.
+ fn uring_cmd(
+ _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
+ _io_uring_cmd: IoUringCmd,
+ _issue_flags: u32,
+ ) -> Result<UringCmdAction> {
+ build_error!(VTABLE_DEFAULT_ERROR)
+ }
}
/// A vtable for the file operations of a Rust miscdevice.
@@ -387,6 +411,56 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
T::show_fdinfo(device, m, file);
}
+ /// # Safety
+ ///
+ /// - The pointer `ioucmd` is not null and points to a valid `bindings::io_uring_cmd`.
+ unsafe extern "C" fn uring_cmd(
+ ioucmd: *mut bindings::io_uring_cmd,
+ issue_flags: ffi::c_uint,
+ ) -> c_int {
+ // SAFETY: `file` referenced by `ioucmd` is valid pointer. It's assigned in
+ // uring cmd preparation. So dereferencing is safe.
+ let raw_file = unsafe { (*ioucmd).file };
+
+ // SAFETY: `private_data` is guaranteed that it has valid pointer after
+ // this file opened. So dereferencing is safe.
+ let private = unsafe { (*raw_file).private_data }.cast();
+
+ // SAFETY: `ioucmd` is not null and points to valid memory `bindings::io_uring_cmd`
+ // and the memory pointed by `ioucmd` is valid and will not be moved or
+ // freed for the lifetime of returned value `ioucmd`
+ let ioucmd = unsafe { IoUringCmd::from_raw(ioucmd) };
+ let mut ioucmd = match ioucmd {
+ Ok(ioucmd) => ioucmd,
+ Err(e) => {
+ return e.to_errno();
+ }
+ };
+
+ // Zero-initialize the PDU for fresh (non-reissued) commands so that
+ // drivers reading from it always start from a clean state. On reissue
+ // the PDU retains its contents from the previous attempt, which is the
+ // expected behaviour (e.g. a driver may store state there across
+ // -EAGAIN retries).
+ if (ioucmd.flags() & bindings::IORING_URING_CMD_REISSUE) == 0 {
+ if let Err(e) = ioucmd.write_pdu(&[0u8; io_uring::PDU_SIZE]) {
+ return e.to_errno();
+ }
+ }
+
+ // SAFETY: This call is safe because `private` is returned by
+ // `into_foreign` in [`open`]. And it's guaranteed
+ // that `from_foreign` is called by [`release`] after the end of
+ // the lifetime of `device`
+ let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
+
+ match T::uring_cmd(device, ioucmd, issue_flags) {
+ Ok(UringCmdAction::Complete(action)) => action.ret(),
+ Ok(UringCmdAction::Queued(_)) => EIOCBQUEUED.to_errno(),
+ Err(e) => e.to_errno(),
+ }
+ }
+
const VTABLE: bindings::file_operations = bindings::file_operations {
open: Some(Self::open),
release: Some(Self::release),
@@ -419,6 +493,11 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
} else {
None
},
+ uring_cmd: if T::HAS_URING_CMD {
+ Some(Self::uring_cmd)
+ } else {
+ None
+ },
..pin_init::zeroed()
};
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 5/5] samples: rust: Add `uring_cmd` example to `rust_misc_device`
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
` (3 preceding siblings ...)
2026-04-08 14:00 ` [PATCH v4 4/5] rust: miscdevice: Add `uring_cmd` support Sidong Yang
@ 2026-04-08 14:00 ` Sidong Yang
2026-04-09 5:25 ` [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Greg Kroah-Hartman
5 siblings, 0 replies; 10+ messages in thread
From: Sidong Yang @ 2026-04-08 14:00 UTC (permalink / raw)
To: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin
Cc: Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring, Sidong Yang
This patch extends the `rust_misc_device` sample to demonstrate how to
use the `uring_cmd` interface for asynchronous device operations.
The new implementation handles two `uring_cmd` operations:
* `RUST_MISC_DEV_URING_CMD_SET_VALUE`: Sets a value in the device.
* `RUST_MISC_DEV_URING_CMD_GET_VALUE`: Gets a value from the device.
To use this new functionality, users can submit `IORING_OP_URING_CMD`
operations to the `rust_misc_device` character device.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
samples/rust/rust_misc_device.rs | 53 +++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 87a1fe63533a..ef506e8b26fe 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -98,13 +98,15 @@
use kernel::{
device::Device,
fs::{File, Kiocb},
+ io_uring::{IoUringCmd, QueuedIoUringCmd, UringCmdAction},
ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
iov::{IovIterDest, IovIterSource},
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
new_mutex,
prelude::*,
- sync::{aref::ARef, Mutex},
+ sync::{Arc, aref::ARef, Mutex},
uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
+ workqueue::{impl_has_work, new_work, HasWork},
};
const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
@@ -151,6 +153,42 @@ struct RustMiscDevice {
dev: ARef<Device>,
}
+#[pin_data]
+struct IoUringCmdWork {
+ #[pin]
+ ioucmd: Mutex<Option<(QueuedIoUringCmd, u32)>>,
+ #[pin]
+ work: kernel::workqueue::Work<IoUringCmdWork>,
+}
+
+impl_has_work! {
+ impl HasWork<Self> for IoUringCmdWork { self.work }
+}
+
+impl kernel::workqueue::WorkItem for IoUringCmdWork {
+ type Pointer = Arc<IoUringCmdWork>;
+
+ fn run(work: Arc<IoUringCmdWork>) {
+ pr_info!("IoUringCmdWork::run()");
+
+ if let Some((ioucmd, issue_flags)) = work.ioucmd.lock().take() {
+ ioucmd.done(Ok(0), 0, issue_flags);
+ }
+ }
+}
+
+impl IoUringCmdWork {
+ fn new(ioucmd: QueuedIoUringCmd, issue_flags: u32) -> Result<Arc<Self>> {
+ Arc::pin_init(
+ pin_init!(Self {
+ ioucmd <- new_mutex!(Some((ioucmd, issue_flags))),
+ work <- new_work!("IoUringCmdWork::work"),
+ }),
+ GFP_KERNEL,
+ )
+ }
+}
+
#[vtable]
impl MiscDevice for RustMiscDevice {
type Ptr = Pin<KBox<Self>>;
@@ -220,6 +258,19 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result
Ok(0)
}
+
+ fn uring_cmd(
+ me: Pin<&RustMiscDevice>,
+ ioucmd: IoUringCmd,
+ issue_flags: u32,
+ ) -> Result<UringCmdAction> {
+ dev_info!(me.dev, "UringCmd Rust Misc Device Sample\n");
+
+ let (action, queued_ioucmd) = ioucmd.queue();
+ let work = IoUringCmdWork::new(queued_ioucmd, issue_flags)?;
+ let _ = kernel::workqueue::system().enqueue(work);
+ Ok(action)
+ }
}
#[pinned_drop]
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h
2026-04-08 13:59 ` [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h Sidong Yang
@ 2026-04-08 14:31 ` Miguel Ojeda
2026-04-09 1:20 ` Sidong Yang
0 siblings, 1 reply; 10+ messages in thread
From: Miguel Ojeda @ 2026-04-08 14:31 UTC (permalink / raw)
To: Sidong Yang
Cc: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin,
Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring
On Wed, Apr 8, 2026 at 4:00 PM Sidong Yang <sidong.yang@furiosa.ai> wrote:
>
> This patch adds two headers io_uring.h io_uring/cmd.h in bindings_helper
> for implementing rust io_uring abstraction.
>
> Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
If there is a reason for putting it at the bottom, then please note it
in the commit message.
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h
2026-04-08 14:31 ` Miguel Ojeda
@ 2026-04-09 1:20 ` Sidong Yang
0 siblings, 0 replies; 10+ messages in thread
From: Sidong Yang @ 2026-04-09 1:20 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin,
Miguel Ojeda, Arnd Bergmann, Greg Kroah-Hartman, rust-for-linux,
linux-kernel, io-uring
On Wed, Apr 08, 2026 at 04:31:35PM +0200, Miguel Ojeda wrote:
> On Wed, Apr 8, 2026 at 4:00 PM Sidong Yang <sidong.yang@furiosa.ai> wrote:
> >
> > This patch adds two headers io_uring.h io_uring/cmd.h in bindings_helper
> > for implementing rust io_uring abstraction.
> >
> > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
>
> If there is a reason for putting it at the bottom, then please note it
> in the commit message.
Hi Miguel,
There is no reason for putting it at the bottom, They should be placed
in the proper order. This will be fixed in next version.
Thanks,
Sidong
>
> Thanks!
>
> Cheers,
> Miguel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
` (4 preceding siblings ...)
2026-04-08 14:00 ` [PATCH v4 5/5] samples: rust: Add `uring_cmd` example to `rust_misc_device` Sidong Yang
@ 2026-04-09 5:25 ` Greg Kroah-Hartman
5 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-04-09 5:25 UTC (permalink / raw)
To: Sidong Yang
Cc: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin,
Miguel Ojeda, Arnd Bergmann, rust-for-linux, linux-kernel,
io-uring
On Wed, Apr 08, 2026 at 01:59:57PM +0000, Sidong Yang wrote:
> This series introduces Rust abstractions for io_uring commands
> (`IORING_OP_URING_CMD`) and wires them up to the miscdevice framework,
> allowing Rust drivers to handle io_uring passthrough commands.
>
> The series is structured as follows:
>
> 1. Add io_uring C headers to Rust bindings.
> 2. Zero-init pdu in io_uring_cmd_prep() to avoid UB from stale data.
> 3. Core io_uring Rust abstractions (IoUringCmd, QueuedIoUringCmd,
> IoUringSqe, UringCmdAction type-state pattern).
> 4. MiscDevice trait extension with uring_cmd callback.
> 5. Sample demonstrating async uring_cmd handling via workqueue.
>
> The sample completes asynchronously using a workqueue rather than
> `io_uring_cmd_complete_in_task()`. The latter is primarily needed
> when completion originates from IRQ/softirq context (e.g. NVMe),
> whereas workqueue workers already run in process context and can
> safely call `io_uring_cmd_done()` directly. A Rust binding for
> `complete_in_task` can be added in a follow-up series.
>
> Copy-based `read_pdu()`/`write_pdu()` are kept instead of returning
> `&T`/`&mut T` references because the PDU is a `[u8; 32]` byte array
> whose alignment may not satisfy `T`'s requirements.
Samples are great and all, but I would really like to see a real user of
this before adding any more miscdev apis to the kernel. Can you submit
this as a series that also adds the driver that needs this at the same
time?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB
2026-04-08 13:59 ` [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB Sidong Yang
@ 2026-04-09 5:27 ` Greg Kroah-Hartman
0 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-04-09 5:27 UTC (permalink / raw)
To: Sidong Yang
Cc: Jens Axboe, Daniel Almeida, Caleb Sander Mateos, Benno Lossin,
Miguel Ojeda, Arnd Bergmann, rust-for-linux, linux-kernel,
io-uring
On Wed, Apr 08, 2026 at 01:59:59PM +0000, Sidong Yang wrote:
> The pdu field in io_uring_cmd may contain stale data when a request
> object is recycled from the slab cache. Accessing uninitialized or
> garbage memory can lead to undefined behavior in users of the pdu.
Who accesses this? If that happens, then yes this is a problem, but if
not, then there's no need for this change, right (i.e. either this is a
bug to be fixed now or not.)
> Ensure the pdu buffer is cleared during io_uring_cmd_prep() so that
> each command starts from a well-defined state. This avoids exposing
> uninitialized memory and prevents potential misinterpretation of data
> from previous requests.
Where is the memory exposed and who misinterprets it?
> No functional change is intended other than guaranteeing that pdu is
> always zero-initialized before use.
This strongly implies that this is not needed at all.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-09 5:27 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-08 13:59 [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Sidong Yang
2026-04-08 13:59 ` [PATCH v4 1/5] rust: bindings: add io_uring headers in bindings_helper.h Sidong Yang
2026-04-08 14:31 ` Miguel Ojeda
2026-04-09 1:20 ` Sidong Yang
2026-04-08 13:59 ` [PATCH v4 2/5] io_uring/cmd: zero-init pdu in io_uring_cmd_prep() to avoid UB Sidong Yang
2026-04-09 5:27 ` Greg Kroah-Hartman
2026-04-08 14:00 ` [PATCH v4 3/5] rust: io_uring: introduce rust abstraction for io-uring cmd Sidong Yang
2026-04-08 14:00 ` [PATCH v4 4/5] rust: miscdevice: Add `uring_cmd` support Sidong Yang
2026-04-08 14:00 ` [PATCH v4 5/5] samples: rust: Add `uring_cmd` example to `rust_misc_device` Sidong Yang
2026-04-09 5:25 ` [PATCH v4 0/5] Rust io_uring command abstraction for miscdevice Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox