From: Zhao Liu <zhao1.liu@intel.com>
To: Paolo Bonzini <bonzini@gnu.org>
Cc: qemu-devel <qemu-devel@nongnu.org>,
qemu-rust@nongnu.org,
"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Daniel Berrange" <berrange@redhat.com>,
"Kevin Wolf" <kwolf@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>
Subject: Re: Rust in QEMU update, April 2025
Date: Wed, 21 May 2025 00:23:14 +0800 [thread overview]
Message-ID: <aCysct2L8Bosqy0N@intel.com> (raw)
In-Reply-To: <d3d1944e-2482-4aa7-b621-596246a08107@gnu.org>
(Resend as the previous email may have failed.)
> Remaining unsafe code
> '''''''''''''''''''''
>
> qdev bindings cover basic classes and interfaces, including
> GPIO pins, timers, clocks and MemoryRegionOps. VMState
> still needs unsafe callbacks for pre_save/post_load, with
> the final version waiting for a bump of the minimum supported
> Rust version to 1.83.0.
>
> Apart from VMState, the remaining instances of `unsafe` blocks in the
> pl011 and HPET code can all be removed without bumping the language
> version.
>
> HPET does some very simple memory accesses; a good safe solution
> for this may be the ``vm-memory`` crate. While I have not looked into
> using it, ``vm-memory`` and ``vm-virtio`` were written with QEMU's
> use cases in mind.
I'm working on this and trying to wrap simple memory access by
vm-memory.
> A coding style for devices
> ''''''''''''''''''''''''''
>
> pl011 and HPET were developed independently and sometimes have different
> idioms that could be unified. Peter Maydell made several observations:
>
> Something I do notice is that there's some inconsistency in
> how we've structured things between the two devices, e.g.:
...
> * pl011 has defined named fields for its registers, but hpet does
> things like::
>
> self.config.get() & (1 << HPET_CFG_LEG_RT_SHIFT) != 0
On the one hand, this way is more friendly and easy to review for C
developers (comparing with the C version), and on the other hand,
there are similar writeups in other projects (crosvm/firecracker). So,
HPET also shows a clumsy and conservative approach :-).
> * pl011 has a split between PL011State and PL011Registers,
> but HPET does not. As I mentioned in an email thread a
> little while back, I feel like the State/Registers split
> is something we should either make a more clear deliberate
> formalised separation that's part of how we recommend
> device models should be designed
Sorry, I just noticed this point.
I tried to abstract a HPETRegisters but found out it didn't work well in
HPET case...So I didn't insist.
The following is the lesson I learned when I wrote HPET in Rust in the
first time (copied from my HPET v2 cover letter [*]):
Additional Experience
=====================
PL011 provides a pattern to group all registers in one BqlRefCell
instead of multiple BqlCells.
I also tried to leverage this design to HPET, but it didn't fit very
well with this issue:
* HPETState abstracts many helpers to check register bit and tell
caller about the state, e.g., is_legacy_mode(),
is_timer_int_active(), etc.
But this also means these helpers can't be used in BqlRefCell::
borrow_mut() context again, otherwise, they would cause the runtime
bql check panic.
- Some cases are easy to fix, i.e, use borrow_mut to modify the
registers after the helpers' call.
- Some cases would by tricky, like memory write callback, since it has
complex logic and it's hard to decouple register changes from the
reset logic as clearly as PL011 does.
The fix for this case is either to avoid using register helpers
again in the borrow_mut context of write(), or to use BqlCell
instead of BqlRefCell to get finer-grained access control to avoid
refactoring code logic.
I chose the latter.
So I think this might be a practical lesson that the choice of BqlCell
and BqlRefCell is also indeed related to code logic: If the code logic
is too complex to decouple borrow() and borrow_mut() (and the compiler
doesn't check this, only the runtime's panic_already_borrowed() will
complains!) , then BqlCell should be chosen. Because fine-grained access
is easier to control and avoid errors. :-)
[*]: https://lore.kernel.org/qemu-devel/20250125125137.1223277-1-zhao1.liu@intel.com/
Thanks,
Zhao
next prev parent reply other threads:[~2025-05-20 16:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-02 12:13 Rust in QEMU update, April 2025 Paolo Bonzini
2025-05-05 12:26 ` Manos Pitsidianakis
2025-05-05 13:44 ` Paolo Bonzini
2025-05-05 14:03 ` Peter Maydell
2025-05-06 8:40 ` Manos Pitsidianakis
2025-05-14 13:16 ` Paolo Bonzini
2025-05-20 16:23 ` Zhao Liu [this message]
2025-05-20 17:48 ` Paolo Bonzini
2025-05-21 8:42 ` Zhao Liu
2025-05-21 8:36 ` Paolo Bonzini
2025-05-21 9:35 ` Manos Pitsidianakis
2025-05-21 10:51 ` Paolo Bonzini
2025-05-21 21:00 ` 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=aCysct2L8Bosqy0N@intel.com \
--to=zhao1.liu@intel.com \
--cc=alex.bennee@linaro.org \
--cc=berrange@redhat.com \
--cc=bonzini@gnu.org \
--cc=kwolf@redhat.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=peter.maydell@linaro.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).