All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhao Liu <zhao1.liu@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-rust@nongnu.org
Subject: Re: [PATCH 04/12] rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirements
Date: Thu, 6 Mar 2025 19:35:10 +0800	[thread overview]
Message-ID: <Z8mIbmv9fFmCzEsg@intel.com> (raw)
In-Reply-To: <90a21eff-a7b4-41dd-99df-c36fd83a1c08@redhat.com>

> While neither is good, a zeroed area of memory behaves better than an
> uninitialized one...  In particular, Drop calls timer_del() which works fine
> with a zeroed QEMUTimer.  With Opaque::uninit() you could have a crash just
> with
> 
>     drop(Timer::new());

Good point.

> > // No compiling error or runtime panic
> > let t: MaybeUninit<bindings::QEMUTimer> = MaybeUninit::zeroed();
> > let _t = unsafe { t.assume_init() };
> > 
> > Further more, I spent some time trying to figure out if MaybeUninit in
> > Opaque<> could help identify UB caused by uninitialized Timer, but I found
> > it doesn't work. :-(
> > 
> > // No compiling error or runtime panic
> > let mut v: UnsafeCell<MaybeUninit<bindings::QEMUTimer>> = UnsafeCell::new(MaybeUninit::uninit());
> > let _v = unsafe { v.get_mut().assume_init() };
> > 
> > But when I adjust MaybeUninit as the outer wrapper, the UB check can
> > work:
> > 
> > // Runtime panic: Illegal instruction
> > let v: MaybeUninit<UnsafeCell<bindings::QEMUTimer>> = MaybeUninit::uninit();
> > let _v = unsafe { v.assume_init() };
> > 
> > Compared with linux's Opaque, it also puts MaybeUninit on the outermost
> > layer.
> 
> Yes, I admit I just copied what Linux does. :)

Thanks for pointing this! I realized I referred the old code, since this
commit, linux puts the UnsafeCell to the outer layer [2]

[2]: https://github.com/torvalds/linux/commit/35cad617df2eeef8440a38e82bb2d81ae32ca50d

It seems that, at least from the Linux view, here the role of MaybeUninit
(as the cases I tested) is not a main concern, and Rust convention is
superior...

> > And there's another example:
> > 
> > https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.raw_get
> > 
> > Emm, I guess now we have UnsafeCell<MaybeUninit<>> because interior
> > mutability is expected... but this layout breaks MaybeUninit's functionality.
> 
> Thanks for the example from the documentation!  Indeed it should be possible
> to do
> 
>     /// Returns a raw mutable pointer to the opaque data.
>     pub const fn as_mut_ptr(&self) -> *mut T {
>         UnsafeCell::raw_get(self.value.as_ptr())
>     }
> 
>     /// Returns a raw pointer to the opaque data that can be passed to a
>     /// C function as `void *`.
>     pub const fn as_void_ptr(&self) -> *mut std::ffi::c_void {
>         self.as_mut_ptr().cast()
>     }
> 
>     pub const fn raw_get(slot: *const Self) -> *mut T {
>         // SAFETY: even if uninitialized, slot points to a MaybeUninit
>         let slot = slot.cast::<MaybeUninit<UnsafeCell<T>>>;
>         UnsafeCell::raw_get(slot.as_ptr())
>     }
> 
> if Opaque<> uses a MaybeUninit<UnsafeCell<T>>.  I'm a bit worried of
> deviating from what Linux does though...

Thank you, this convertion to UnsafeCell<MaybeUninit<T>> in Linux
history convinces me... I also agree that we should follow it for now :-).

Regards,
Zhao




  reply	other threads:[~2025-03-06 11:24 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-27 14:22 [PATCH v2 00/12] rust: wrap all C types exposed through qemu_api Paolo Bonzini
2025-02-27 14:22 ` [PATCH 01/12] rust: cell: add wrapper for FFI types Paolo Bonzini
2025-02-27 14:22 ` [PATCH 02/12] rust: qemu_api_macros: add Wrapper derive macro Paolo Bonzini
2025-02-27 14:22 ` [PATCH 03/12] rust: vmstate: add std::pin::Pin as transparent wrapper Paolo Bonzini
2025-03-03 13:25   ` Zhao Liu
2025-02-27 14:22 ` [PATCH 04/12] rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirements Paolo Bonzini
2025-03-03 13:48   ` Zhao Liu
2025-03-03 15:58     ` Paolo Bonzini
2025-03-04  9:13       ` Zhao Liu
2025-03-06 10:45         ` Paolo Bonzini
2025-03-06 11:35           ` Zhao Liu [this message]
2025-03-03 14:28   ` Zhao Liu
2025-03-03 14:51     ` Paolo Bonzini
2025-03-03 16:15       ` Zhao Liu
2025-02-27 14:22 ` [PATCH 05/12] rust: irq: wrap IRQState with Opaque<> Paolo Bonzini
2025-03-03 15:07   ` Zhao Liu
2025-02-27 14:22 ` [PATCH 06/12] rust: qom: wrap Object " Paolo Bonzini
2025-02-27 14:22 ` [PATCH 07/12] rust: qdev: wrap Clock and DeviceState " Paolo Bonzini
2025-02-27 14:22 ` [PATCH 08/12] rust: hpet: do not access fields of SysBusDevice Paolo Bonzini
2025-03-03 15:09   ` Zhao Liu
2025-02-27 14:22 ` [PATCH 09/12] rust: sysbus: wrap SysBusDevice with Opaque<> Paolo Bonzini
2025-03-03 15:19   ` Zhao Liu
2025-02-27 14:22 ` [PATCH 10/12] rust: memory: wrap MemoryRegion " Paolo Bonzini
2025-03-03 15:25   ` Zhao Liu
2025-03-05  7:09   ` Zhao Liu
2025-02-27 14:22 ` [PATCH 11/12] rust: chardev: wrap Chardev " Paolo Bonzini
2025-02-27 14:22 ` [PATCH 12/12] rust: bindings: remove more unnecessary Send/Sync impls Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z8mIbmv9fFmCzEsg@intel.com \
    --to=zhao1.liu@intel.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-rust@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.