qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Cc: "Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
	qemu-devel <qemu-devel@nongnu.org>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Mads Ynddal" <mads@ynddal.dk>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Alex Benné e" <alex.bennee@linaro.org>,
	"Marc-Andr é Lureau" <marcandre.lureau@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Philippe Mathieu-Daud é" <philmd@linaro.org>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Gustavo Romero" <gustavo.romero@linaro.org>,
	rowan.hart@intel.com
Subject: Re: [RFC PATCH v2 3/5] rust: add PL011 device model
Date: Tue, 18 Jun 2024 08:00:00 +0200	[thread overview]
Message-ID: <CABgObfY4BeuDC9XXhe-JLH_pOk2Sid5P_WvDgtWzYRv0-0EyHg@mail.gmail.com> (raw)
In-Reply-To: <24ee6724-a7d4-47eb-8f89-939a2699bd6a@linaro.org>

On Tue, Jun 18, 2024 at 1:33 AM Pierrick Bouvier
<pierrick.bouvier@linaro.org> wrote:
>
> On 6/17/24 14:04, Manos Pitsidianakis wrote:
> > On Mon, 17 Jun 2024 17:32, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >> On Mon, Jun 17, 2024 at 4:04 PM Manos Pitsidianakis
> >> <manos.pitsidianakis@linaro.org> wrote:
> >>> I respectfully disagree and recommend taking another look at the code.
> >>>
> >>> The device actually performs all logic in non-unsafe methods and is
> >>> typed instead of operating on raw integers as fields/state. The C stuff
> >>> is the FFI boundary calls which you cannot avoid; they are the same
> >>> things you'd wrap under these bindings we're talking about.
> >>
> >> Indeed, but the whole point is that the bindings wrap unsafe code in
> >> such a way that the safety invariants hold. Not doing this, especially
> >> for a device that does not do DMA (so that there are very few ways
> >> that things can go wrong in the first place), runs counter to the
> >> whole philosophy of Rust.
> >>
> >> For example, you have:
> >>
> >>     pub fn realize(&mut self) {
> >>         unsafe {
> >>             qemu_chr_fe_set_handlers(
> >>                 addr_of_mut!(self.char_backend),
> >>                 Some(pl011_can_receive),
> >>                 Some(pl011_receive),
> >>                 Some(pl011_event),
> >>                 None,
> >>                 addr_of_mut!(*self).cast::<c_void>(),
> >>                 core::ptr::null_mut(),
> >>                 true,
> >>             );
> >>         }
> >>     }
> >>
> >> where you are implicitly relying on the fact that pl011_can_receive(),
> >> pl011_receive(), pl011_event() are never called from the
> >> MemoryRegionOps read() and write() callbacks. Otherwise you'd have two
> >> mutable references at the same time, one as an argument to the
> >> callbacks:
> >>
> >>    pub fn read(&mut self, offset: hwaddr, ...
> >>
> >> and one from e.g. "state.as_mut().put_fifo()" in pl011_receive().
> >>
> >> This is not Rust code. It makes no attempt at enforcing the whole
> >> "shared XOR mutable" which is the basis of Rust's reference semantics.
> >> In other words, this is as safe as C code---sure, it can use nice
> >> abstractions for register access, it has "unsafe" added in front of
> >> pointer dereferences, but it is not safe.
> >>
> >> Again, I'm not saying it's a bad first step. It's *awesome* if we
> >> treat it as what it is: a guide towards providing safe bindings
> >> between Rust and C (which often implies them being idiomatic). But if
> >> we don't accept this, if there is no plan to make the code safe, it is
> >> a potential huge source of technical debt.
> >>
> >>> QEMU calls the device's FFI callbacks with its pointer and arguments,
> >>> the pointer gets dereferenced to the actual Rust type which qemu
> >>> guarantees is valid, then the Rust struct's methods are called to handle
> >>> each functionality. There is nothing actually unsafe here, assuming
> >>> QEMU's invariants and code are correct.
> >>
> >> The same can be said of C code, can't it? There is nothing unsafe in C
> >> code, assuming there are no bugs...
> >
> > Paolo, first please tone down your condescending tone, it's incredibly
> > offensive. I'm honestly certain this is not on purpose otherwise I'd not
> > engage at all.
>
> The best compliment you had was "I'm not saying it's a bad first step",
> and I would say this differently: It's a great first step!

Don't quote me out of context; I said It's an "awesome" first step,
though I qualified that we should treat it as "a guide towards
providing safe bindings between Rust and C". That is, as long as we
agree that it is not production quality code. Which it doesn't have to
be!

> We should have a first version where we stick to the C API, with all the
> Rust code being as Rusty as possible: benefit from typed enums, error
> handling, bounds checking and other nice things.
>
> It's useless to iterate/debate for two years on the list before landing
> something upstream. We can start with this, have one or two devices that
> use this build system, and then focus on designing a good interface for
> this.

I never said that I want perfection before landing upstream. I want _a path_.

When I read "there was consensus in the community call that we won't
be writing Rust APIs for internal C QEMU interfaces; or at least,
that's not the goal"[1], then sorry but I think that it's better to
stick with C.

On the other hand, if there is a path towards proper, maintainable
Rust, then I am even okay even with committing something that
technically contains undefined behavior.

[1] https://lore.kernel.org/qemu-devel/ez270.x96k6aeu0rpw@linaro.org/

> As I mentioned in my previous answer, this device already makes a good
> progress: it eliminates a whole class of memory errors, and the only
> issue brought by unsafe code is concurrency issues. And this should be
> our focus once we get the build infrastructure done!

Let's not exaggerate the benefits: no pointers were converted to RAII
(Box<> or Rc<>) in the course of writing the Rust code; so there are
no memory errors that can be eliminated by the rewrite. In fact, new
memory errors can also be introduced, because safe Rust has stricter
aliasing rules than C.

This is not a problem! It's just that we need to be realistic to
understand where to focus next and why. To build our path.

(Also, a small correction so that we're on the same page on the fix:
it's reentrancy, not concurrency).

Paolo



  reply	other threads:[~2024-06-18  6:02 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-11 10:33 [RFC PATCH v2 0/5] Implement ARM PL011 in Rust Manos Pitsidianakis
2024-06-11 10:33 ` [RFC PATCH v2 1/5] build-sys: Add rust feature option Manos Pitsidianakis
2024-06-19  4:44   ` Richard Henderson
2024-06-19 16:52   ` Richard Henderson
2024-06-19 17:32     ` Manos Pitsidianakis
2024-06-11 10:33 ` [RFC PATCH v2 2/5] rust: add bindgen step as a meson dependency Manos Pitsidianakis
2024-06-17 21:01   ` Paolo Bonzini
2024-06-11 10:33 ` [RFC PATCH v2 3/5] rust: add PL011 device model Manos Pitsidianakis
2024-06-12 12:29   ` Paolo Bonzini
2024-06-12 14:14     ` Manos Pitsidianakis
2024-06-12 15:20       ` Paolo Bonzini
2024-06-12 16:06       ` Daniel P. Berrangé
2024-06-12 20:57         ` Manos Pitsidianakis
2024-06-12 21:27           ` Paolo Bonzini
2024-06-13  5:09             ` Manos Pitsidianakis
2024-06-13  7:13             ` Daniel P. Berrangé
2024-06-13  7:56               ` Paolo Bonzini
2024-06-13  8:49                 ` Manos Pitsidianakis
2024-06-13  9:16                 ` Daniel P. Berrangé
2024-06-13 20:57                   ` Paolo Bonzini
2024-06-14  6:38                     ` Manos Pitsidianakis
2024-06-14 17:50                       ` Paolo Bonzini
2024-06-17  8:45                         ` Manos Pitsidianakis
2024-06-17 11:32                           ` Paolo Bonzini
2024-06-17 13:54                             ` Manos Pitsidianakis
2024-06-17 14:32                               ` Paolo Bonzini
2024-06-17 21:04                                 ` Manos Pitsidianakis
2024-06-17 23:33                                   ` Pierrick Bouvier
2024-06-18  6:00                                     ` Paolo Bonzini [this message]
2024-06-18  6:00                                   ` Paolo Bonzini
2024-06-17 23:18                                 ` Pierrick Bouvier
2024-06-18  9:13                             ` Daniel P. Berrangé
2024-06-18  9:29                               ` Paolo Bonzini
2024-06-18  9:49                                 ` Peter Maydell
2024-06-13 16:20                 ` Zhao Liu
2024-06-13 17:56                   ` Paolo Bonzini
2024-06-13  8:30   ` Zhao Liu
2024-06-13  8:41     ` Manos Pitsidianakis
2024-06-13  8:53       ` Daniel P. Berrangé
2024-06-13  8:59         ` Manos Pitsidianakis
2024-06-13  9:20           ` Daniel P. Berrangé
2024-06-19  5:34   ` Richard Henderson
2024-06-19 16:43     ` Paolo Bonzini
2024-06-19 16:54       ` Daniel P. Berrangé
2024-06-19 17:23         ` Paolo Bonzini
2024-07-11  4:21   ` Zhao Liu
2024-07-11  5:35     ` Manos Pitsidianakis
2024-06-11 10:33 ` [RFC PATCH v2 4/5] DO NOT MERGE: add rustdoc build for gitlab pages Manos Pitsidianakis
2024-06-11 10:33 ` [RFC PATCH v2 5/5] DO NOT MERGE: replace TYPE_PL011 with x-pl011-rust in arm virt machine Manos Pitsidianakis
2024-06-12  8:37 ` [RFC PATCH v2 0/5] Implement ARM PL011 in Rust Daniel P. Berrangé
2024-06-13  5:13   ` Manos Pitsidianakis
2024-06-13  7:56     ` Daniel P. Berrangé
2024-06-19  3:31 ` Richard Henderson
2024-06-19 17:36   ` Manos Pitsidianakis

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=CABgObfY4BeuDC9XXhe-JLH_pOk2Sid5P_WvDgtWzYRv0-0EyHg@mail.gmail.com \
    --to=pbonzini@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=gustavo.romero@linaro.org \
    --cc=mads@ynddal.dk \
    --cc=manos.pitsidianakis@linaro.org \
    --cc=marcandre.lureau@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=pierrick.bouvier@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rowan.hart@intel.com \
    --cc=stefanha@redhat.com \
    --cc=thuth@redhat.com \
    --cc=zhao1.liu@intel.com \
    /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).