This patch makes rust_misc_device handle uring_cmd. Command ops are like
ioctl that set or get values in simple way.
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
samples/rust/rust_misc_device.rs | 34 ++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index c881fd6dbd08..1044bde86e8d 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -101,6 +101,7 @@
c_str,
device::Device,
fs::File,
+ io_uring::IoUringCmd,
ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
new_mutex,
@@ -114,6 +115,9 @@
const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81);
const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82);
+const RUST_MISC_DEV_URING_CMD_SET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x83);
+const RUST_MISC_DEV_URING_CMD_GET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x84);
+
module! {
type: RustMiscDeviceModule,
name: "rust_misc_device",
@@ -190,6 +194,36 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result
Ok(0)
}
+
+ fn uring_cmd(
+ me: Pin<&RustMiscDevice>,
+ io_uring_cmd: Pin<&mut IoUringCmd>,
+ _issue_flags: u32,
+ ) -> Result<i32> {
+ dev_info!(me.dev, "UringCmd Rust Misc Device Sample\n");
+
+ let cmd = io_uring_cmd.cmd_op();
+ let cmd_data = io_uring_cmd.sqe().cmd_data().as_ptr() as *const usize;
+
+ // SAFETY: `cmd_data` is guaranteed to be a valid pointer to the command data
+ // within the SQE structure.
+ // FIXME: switch to read_once() when it's available.
+ let addr = unsafe { core::ptr::read_volatile(cmd_data) };
+
+ match cmd {
+ RUST_MISC_DEV_URING_CMD_SET_VALUE => {
+ me.set_value(UserSlice::new(addr, 8).reader())?;
+ }
+ RUST_MISC_DEV_URING_CMD_GET_VALUE => {
+ me.get_value(UserSlice::new(addr, 8).writer())?;
+ }
+ _ => {
+ dev_err!(me.dev, "-> uring_cmd not recognised: {}\n", cmd);
+ return Err(ENOTTY);
+ }
+ }
+ Ok(0)
+ }
}
#[pinned_drop]
--
2.43.0
Hi Sidong, > On 27 Jul 2025, at 12:03, Sidong Yang <sidong.yang@furiosa.ai> wrote: > > This patch makes rust_misc_device handle uring_cmd. Command ops are like > ioctl that set or get values in simple way. > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > --- > samples/rust/rust_misc_device.rs | 34 ++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs > index c881fd6dbd08..1044bde86e8d 100644 > --- a/samples/rust/rust_misc_device.rs > +++ b/samples/rust/rust_misc_device.rs > @@ -101,6 +101,7 @@ > c_str, > device::Device, > fs::File, > + io_uring::IoUringCmd, > ioctl::{_IO, _IOC_SIZE, _IOR, _IOW}, > miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, > new_mutex, > @@ -114,6 +115,9 @@ > const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81); > const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82); > > +const RUST_MISC_DEV_URING_CMD_SET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x83); > +const RUST_MISC_DEV_URING_CMD_GET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x84); > + > module! { > type: RustMiscDeviceModule, > name: "rust_misc_device", > @@ -190,6 +194,36 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result > > Ok(0) > } > + > + fn uring_cmd( > + me: Pin<&RustMiscDevice>, “me” ? > + io_uring_cmd: Pin<&mut IoUringCmd>, > + _issue_flags: u32, > + ) -> Result<i32> { > + dev_info!(me.dev, "UringCmd Rust Misc Device Sample\n"); > + > + let cmd = io_uring_cmd.cmd_op(); > + let cmd_data = io_uring_cmd.sqe().cmd_data().as_ptr() as *const usize; > + > + // SAFETY: `cmd_data` is guaranteed to be a valid pointer to the command data > + // within the SQE structure. This is what core::ptr::read_volatile says: Safety Behavior is undefined if any of the following conditions are violated: • src must be valid for reads. • src must be properly aligned. • src must point to a properly initialized value of type T. You must prove that the pre-conditions above are fulfilled here. > + // FIXME: switch to read_once() when it's available. > + let addr = unsafe { core::ptr::read_volatile(cmd_data) }; So drivers have to write “unsafe” directly? It isn’t forbidden, but we should try our best to avoid it. > + > + match cmd { > + RUST_MISC_DEV_URING_CMD_SET_VALUE => { > + me.set_value(UserSlice::new(addr, 8).reader())?; > + } > + RUST_MISC_DEV_URING_CMD_GET_VALUE => { > + me.get_value(UserSlice::new(addr, 8).writer())?; > + } > + _ => { > + dev_err!(me.dev, "-> uring_cmd not recognised: {}\n", cmd); > + return Err(ENOTTY); > + } > + } > + Ok(0) > + } > } > Who calls this function? > #[pinned_drop] > -- > 2.43.0 > > — Daniel
On Fri, Aug 01, 2025 at 11:11:44AM -0300, Daniel Almeida wrote: > Hi Sidong, > > > On 27 Jul 2025, at 12:03, Sidong Yang <sidong.yang@furiosa.ai> wrote: > > > > This patch makes rust_misc_device handle uring_cmd. Command ops are like > > ioctl that set or get values in simple way. > > > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > > --- > > samples/rust/rust_misc_device.rs | 34 ++++++++++++++++++++++++++++++++ > > 1 file changed, 34 insertions(+) > > > > diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs > > index c881fd6dbd08..1044bde86e8d 100644 > > --- a/samples/rust/rust_misc_device.rs > > +++ b/samples/rust/rust_misc_device.rs > > @@ -101,6 +101,7 @@ > > c_str, > > device::Device, > > fs::File, > > + io_uring::IoUringCmd, > > ioctl::{_IO, _IOC_SIZE, _IOR, _IOW}, > > miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, > > new_mutex, > > @@ -114,6 +115,9 @@ > > const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81); > > const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82); > > > > +const RUST_MISC_DEV_URING_CMD_SET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x83); > > +const RUST_MISC_DEV_URING_CMD_GET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x84); > > + > > module! { > > type: RustMiscDeviceModule, > > name: "rust_misc_device", > > @@ -190,6 +194,36 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result > > > > Ok(0) > > } > > + > > + fn uring_cmd( > > + me: Pin<&RustMiscDevice>, > > "me" ? ioctl() uses the args name with "me". > > > + io_uring_cmd: Pin<&mut IoUringCmd>, > > + _issue_flags: u32, > > + ) -> Result<i32> { > > + dev_info!(me.dev, "UringCmd Rust Misc Device Sample\n"); > > + > > + let cmd = io_uring_cmd.cmd_op(); > > + let cmd_data = io_uring_cmd.sqe().cmd_data().as_ptr() as *const usize; > > + > > + // SAFETY: `cmd_data` is guaranteed to be a valid pointer to the command data > > + // within the SQE structure. > > This is what core::ptr::read_volatile says: > > Safety > Behavior is undefined if any of the following conditions are violated: > o src must be valid for reads. > o src must be properly aligned. > o src must point to a properly initialized value of type T. > > You must prove that the pre-conditions above are fulfilled here. Okay, I would describe pre-conditions. > > > + // FIXME: switch to read_once() when it's available. > > + let addr = unsafe { core::ptr::read_volatile(cmd_data) }; > > So drivers have to write "unsafe" directly? It isn´t forbidden, but > we should try our best to avoid it. I don't know it's the best way to use &[u8] `cmd_data` in driver. The driver should cast the `cmd_data` to user structure i32 in this time. is there any safe way to provide safe interface for user driver? > > > + > > + match cmd { > > + RUST_MISC_DEV_URING_CMD_SET_VALUE => { > > + me.set_value(UserSlice::new(addr, 8).reader())?; > > + } > > + RUST_MISC_DEV_URING_CMD_GET_VALUE => { > > + me.get_value(UserSlice::new(addr, 8).writer())?; > > + } > > + _ => { > > + dev_err!(me.dev, "-> uring_cmd not recognised: {}\n", cmd); > > + return Err(ENOTTY); > > + } > > + } > > + Ok(0) > > + } > > } > > > > Who calls this function? This function would be called in io_uring subsystem. In detail, there is caller io_uring_cmd() in io_uring/uring_cmd.c. When io_uring subsystem noticed that submission queue entry which has uring cmd op pushed to submission queue, it would be submitted and actually calls this function. > > > #[pinned_drop] > > -- > > 2.43.0 > > > > > > - Daniel >
© 2016 - 2025 Red Hat, Inc.