ksummit.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@kernel.org>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Wedson Almeida Filho <wedsonaf@google.com>,
	Vegard Nossum <vegard.nossum@oracle.com>,
	 Linus Walleij <linus.walleij@linaro.org>,
	Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>,
	 Greg KH <greg@kroah.com>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	 Kees Cook <keescook@chromium.org>, Jan Kara <jack@suse.cz>,
	 James Bottomley <James.Bottomley@hansenpartnership.com>,
	 Julia Lawall <julia.lawall@inria.fr>,
	Roland Dreier <roland@kernel.org>,
	ksummit@lists.linux.dev,  Viresh Kumar <viresh.kumar@linaro.org>
Subject: Re: [TECH TOPIC] Rust for Linux
Date: Tue, 20 Jul 2021 18:33:38 -0700	[thread overview]
Message-ID: <CALCETrWH4N17C+uHaDbzGkgS005feaOVQ25yGo9Zy0cb3+eeGA@mail.gmail.com> (raw)
In-Reply-To: <YPdiMHr/t5K6RJck@pendragon.ideasonboard.com>

On Tue, Jul 20, 2021 at 4:54 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Wedson,
>
> On Mon, Jul 19, 2021 at 10:09:46PM +0100, Wedson Almeida Filho wrote:
> > On Mon, Jul 19, 2021 at 10:37:52PM +0300, Laurent Pinchart wrote:
> > > On Mon, Jul 19, 2021 at 07:06:36PM +0100, Wedson Almeida Filho wrote:
> > > > On Mon, Jul 19, 2021 at 06:02:06PM +0200, Vegard Nossum wrote:
> > > > > On 7/19/21 3:15 PM, Wedson Almeida Filho wrote:
> > > > > > On Mon, Jul 19, 2021 at 01:24:49PM +0100, Wedson Almeida Filho wrote:
> > > > > >> On Fri, Jul 09, 2021 at 12:13:25AM +0200, Linus Walleij wrote:
> > > > > >>> I have seen that QEMU has a piece of code for the Arm PrimeCell
> > > > > >>> PL061 GPIO block which corresponds to drivers/gpio/gpio-pl061.c
> > > > > >>> Note that this hardware apart from being used in all Arm reference
> > > > > >>> designs is used on ARMv4T systems that are not supported by
> > > > > >>> LLVM but only GCC, which might complicate things.
> > > > > >>
> > > > > >> Here is a working PL061 driver in Rust (converted form the C one):
> > > > > >> https://raw.githubusercontent.com/wedsonaf/linux/pl061/drivers/gpio/gpio_pl061_rust.rs
> > > > > >
> > > > > > I'm also attaching an html rending of the C and Rust versions side by side where
> > > > > > I try to line the definitions up to make it easier to contrast the two
> > > > > > implementations.
> > > > >
> > > > > This is really cool :-) As a Rust noob, I have a few questions:
> > > > >
> > > > > 1. I'm curious about some of the writeb() vs. try_writeb() calls:
> > > > >
> > > > > fn direction_output(data: &Ref<DeviceData>, offset: u32, value: bool) ->
> > > > > Result {
> > > > >         let woffset = bit(offset + 2).into();
> > > > >         let _guard = data.lock();
> > > > >         let pl061 = data.resources().ok_or(Error::ENXIO)?;
> > > > >         pl061.base.try_writeb((value as u8) << offset, woffset)?;
> > > > >         let mut gpiodir = pl061.base.readb(GPIODIR);
> > > > >         gpiodir |= bit(offset);
> > > > >         pl061.base.writeb(gpiodir, GPIODIR);
> > > > >
> > > > >         // gpio value is set again, because pl061 doesn't allow to set
> > > > > value of a gpio pin before
> > > > >         // configuring it in OUT mode.
> > > > >         pl061.base.try_writeb((value as u8) << offset, woffset)?;
> > > > >         Ok(())
> > > > >     }
> > > > >
> > > > > Here you have try_writeb() (and error return) where there was just a
> > > > > writeb() without any error handling in the C version. Is this what
> > > > > Miguel was answering a bit down the thread where the address is computed
> > > > > ((value as u8) << offset) so it _needs_ to use the try_() version?
> > > >
> > > > The `writeb` variant only works when we know at compile-time that the offset is
> > > > within bounds (the compiler will reject the code otherwise). When the value is
> > > > computed at runtime we use a `try` version that checks before performing the
> > > > write. We need this to guarantee memory safety.
> > > >
> > > > > If offset can be anything but a "correct" value here, should there be a
> > > > > check for that somewhere else and then the computed value can be
> > > > > subsequently treated as safe (i.e. there's a second try_writeb() in the
> > > > > function that now presumably does the runtime check a second time,
> > > > > redundantly)?
> > > >
> > > > Oh, that's a neat idea. We can certainly implement something like this:
> > > >
> > > > let woffset = pl061.base.vet_offsetb(bit(offset + 2))?;
> > > >
> > > > Then woffset would be passed to writeb variants that are guaranteed to succeed.
> > > > (Rust helps us ensure that woffset cannot change without checks, which would be
> > > > harder to do in C.)
> > > >
> > > > > 2. In many places you have the C code:
> > > > >
> > > > > struct pl061 *pl061 = dev_get_drvdata(dev);
> > > > >
> > > > > with the equivalent Rust code as:
> > > > >
> > > > > let pl061 = data.resources().ok_or(Error::ENXIO)?;
> > > > >
> > > > > Why doesn't the C code need to check for errors here? Or put
> > > > > differently, why can the Rust version fail?
> > > >
> > > > There are two aspecs worth noting here:
> > > > 1. In C there is cast from void * to struct pl061 * without really knowing if
> > > > the stored pointer is of the right type. For example, if I simply change the
> > > > struct type to say `struct mutex` in the code above, it will still compile,
> > > > though it will be clearly wrong. In Rust we prevent this by not exposing drvdata
> > > > directly to drivers, and using type-specialised functions to set/get drvdata, so
> > > > it *knows* that the type is right. So in this sense Rust is better because it
> > > > offers type guarantees without additional runtime cost. (In Rust, if you change
> > > > the type of the function to say `&Mutex`, it won't compile.
> > > >
> > > > 2. The extra check we have here is because of a feature that the C code doesn't
> > > > have: revocable resources. If we didn't want to have this, we could do say
> > > > `data.base.writeb(...)` directly, but then we could have situations where `base`
> > > > is used after the device was removed. By having these checks we guarantee that
> > > > anyone can hold a reference to device state, but they can no longer use hw
> > > > resources after the device is removed.
> > >
> > > If the driver reached a code path with an I/O write after .remove()
> > > returns, the game is likely over already. It would be more interesting
> > > to see how we could prevent that from happening in the first place.
> > > Checking individual I/O writes at runtime will not only add additional
> > > CPU costs, but will also produce code paths that are not well tested.
> >
> > You may be conflating checking offsets in individual writes/reads with accessing
> > hw resources. Note that these are different things.
>
> Yes, it's the data.resources().ok_or() that I was talking about, not the
> I/O writes, sorry.
>
> > > It
> > > feels that we're inventing a problem just to be able to showcase the
> > > solution :-)
> >
> > Thanks for taking a look. I beg to differ though, as this solves (on the Rust
> > side) a problem you described the other day on this very thread. The solution is
> > different from what you propose though :)
> >
> > - The internal data structures of drivers are refcounted. Drivers then share
> >   this internal representation with other subsystems (e.g., cdev).
>
> Refcounting the driver-specific structure is good, that matches what I
> proposed (it's of course implemented differently in C and rust, but
> that's expected).
>
> > - On `remove`, the registrations with other subsystems are removed (so no
> >   additional sharing of internal data should happen), but existing calls and
> >   references to internal data structures continue to exist. This part is
> >   important: we don't "revoke" the references, but we do revoke the hw resources
> >   part of the internal state.
>
> No issue here either. The handling of the internal data structure (the
> "non-revoke" part to be precise) matches my proposal too I believe.
> Revoking the I/O memory is of course rust-specific.
>
> > - Attempts to access hardware resources freed during `remove` *must* be
> >   prevented, that's where the calls to `resources()` are relevant -- if a
> >   subsystem calls into the driver with one of the references it held on to, they
> >   won't be able to access the (already released) hw resources.
>
> That's where our opinions differ. Yes, those accesses must be prevented,
> but I don't think the right way to do so is to check if the I/O memory
> resource is still valid. We should instead prevent reaching driver code
> paths that make those I/O accesses, by waiting for all calls in progress
> to return, and preventing new calls from being made. This is a more
> generic solution in the sense that it doesn't prevent accessing I/O
> memory only, but avoids any operation that is not supposed to take
> place. My reasoning is that drivers will be written with the assumption
> that, for instance, nobody will try to set the GPIO direction once
> .remove() returns. Even if the direction_output() function correctly
> checks if the I/O memory is available and returns an error if it isn't,
> it may also contain other logic that will not work correctly after
> .remove() as the developer will not have considered that case. This
> uncorrect logic may or may not lead to bugs, and some categories of bugs
> may be prevented by rust (such as accessing I/O memory after .remove()),
> but I don't think that's relevant. The subsystem, with minimal help from
> the driver's implementation of the .remove() function if necessary,
> should prevent operations from being called when they shouldn't, and
> especially when the driver's author will not expect them to be called.
> That way we'll address whole classes of issues in one go. And if we do
> so, checking if I/O memory access has been revoked isn't required
> anymore, as we guarantee if isn't.
>
> True, this won't prevent I/O memory from being accessed after .remove()
> in other contexts, for instance in a timer handler that the driver would
> have registered and forgotten to cancel in .remove(). And maybe the I/O
> memory revoking mechanism runtime overhead may be a reasonable price to
> pay for avoiding this, I don't know. I however believe that regardless
> of whether I/O memory is revoked or not, implementing a mechanism in the
> subsytem to avoid erroneous conditions from happening in the first place
> is where we'll get the largest benefit with a (hopefully) reasonable
> effort.

Preventing functions from being called, when those functions are
scattered all over the place (sysfs, etc) may be hard.  Preventing
access to a resource seems much more tractable.  That being said,
preventing access to the I/O resource in particular seems a bit odd to
me.  It's really the whole device that's gone after it has been
removed.  So maybe the whole device (for some reasonable definition of
"whole device") could get revoked?

--Andy

  reply	other threads:[~2021-07-21  1:33 UTC|newest]

Thread overview: 201+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-25 22:09 [TECH TOPIC] Rust for Linux Miguel Ojeda
2021-07-05 23:51 ` Linus Walleij
2021-07-06  4:30   ` Leon Romanovsky
2021-07-06  9:55     ` Linus Walleij
2021-07-06 10:16       ` Geert Uytterhoeven
2021-07-06 17:59         ` Linus Walleij
2021-07-06 18:36           ` Miguel Ojeda
2021-07-06 19:12             ` Linus Walleij
2021-07-06 21:32               ` Miguel Ojeda
2021-07-07 14:10             ` Arnd Bergmann
2021-07-07 15:28               ` Miguel Ojeda
2021-07-07 15:50                 ` Andrew Lunn
2021-07-07 16:34                   ` Miguel Ojeda
2021-07-07 16:55                 ` Arnd Bergmann
2021-07-07 17:54                   ` Miguel Ojeda
2021-07-06 10:22       ` Leon Romanovsky
2021-07-06 14:30       ` Miguel Ojeda
2021-07-06 14:32         ` Miguel Ojeda
2021-07-06 15:03         ` Sasha Levin
2021-07-06 15:33           ` Miguel Ojeda
2021-07-06 15:42             ` Laurent Pinchart
2021-07-06 16:09               ` Mike Rapoport
2021-07-06 18:29               ` Miguel Ojeda
2021-07-06 18:38                 ` Laurent Pinchart
2021-07-06 19:45                   ` Steven Rostedt
2021-07-06 19:59                   ` Miguel Ojeda
2021-07-06 18:53             ` Sasha Levin
2021-07-06 21:50               ` Miguel Ojeda
2021-07-07  4:57                 ` Leon Romanovsky
2021-07-07 13:39                 ` Alexandre Belloni
2021-07-07 13:50                   ` Miguel Ojeda
2021-07-06 18:26         ` Linus Walleij
2021-07-06 19:11           ` Miguel Ojeda
2021-07-06 19:13         ` Johannes Berg
2021-07-06 19:43           ` Miguel Ojeda
2021-07-06 10:20     ` James Bottomley
2021-07-06 14:55       ` Miguel Ojeda
2021-07-06 15:01         ` Sasha Levin
2021-07-06 15:36           ` Miguel Ojeda
2021-07-09 10:02         ` Marco Elver
2021-07-09 16:02           ` Miguel Ojeda
2021-07-06 18:09       ` Linus Walleij
2021-07-06 14:24     ` Miguel Ojeda
2021-07-06 14:33       ` Laurent Pinchart
2021-07-06 14:56       ` Leon Romanovsky
2021-07-06 15:29         ` Miguel Ojeda
2021-07-07  4:38           ` Leon Romanovsky
2021-07-06 20:00   ` Roland Dreier
2021-07-06 20:36     ` Linus Walleij
2021-07-06 22:00       ` Laurent Pinchart
2021-07-07  7:27         ` Julia Lawall
2021-07-07  7:45           ` Greg KH
2021-07-07  7:52             ` James Bottomley
2021-07-07 13:49               ` Miguel Ojeda
2021-07-07 14:08                 ` James Bottomley
2021-07-07 15:15                   ` Miguel Ojeda
2021-07-07 15:44                     ` Greg KH
2021-07-07 17:01                       ` Wedson Almeida Filho
2021-07-07 17:20                         ` Greg KH
2021-07-07 19:19                           ` Wedson Almeida Filho
2021-07-07 20:38                             ` Jan Kara
2021-07-07 23:09                               ` Wedson Almeida Filho
2021-07-08  6:11                                 ` Greg KH
2021-07-08 13:36                                   ` Wedson Almeida Filho
2021-07-08 18:51                                     ` Greg KH
2021-07-08 19:31                                       ` Andy Lutomirski
2021-07-08 19:35                                         ` Geert Uytterhoeven
2021-07-08 21:56                                           ` Andy Lutomirski
2021-07-08 19:49                                       ` Linus Walleij
2021-07-08 20:34                                         ` Miguel Ojeda
2021-07-08 22:13                                           ` Linus Walleij
2021-07-09  7:24                                             ` Geert Uytterhoeven
2021-07-19 12:24                                             ` Wedson Almeida Filho
2021-07-19 13:15                                               ` Wedson Almeida Filho
2021-07-19 14:02                                                 ` Arnd Bergmann
2021-07-19 14:13                                                   ` Linus Walleij
2021-07-19 21:32                                                     ` Arnd Bergmann
2021-07-19 21:33                                                     ` Arnd Bergmann
2021-07-20  1:46                                                       ` Miguel Ojeda
2021-07-20  6:43                                                         ` Johannes Berg
2021-07-19 14:43                                                   ` Geert Uytterhoeven
2021-07-19 18:24                                                     ` Miguel Ojeda
2021-07-19 18:47                                                       ` Steven Rostedt
2021-07-19 14:54                                                   ` Miguel Ojeda
2021-07-19 17:32                                                   ` Wedson Almeida Filho
2021-07-19 21:31                                                     ` Arnd Bergmann
2021-07-19 17:37                                                   ` Miguel Ojeda
2021-07-19 16:02                                                 ` Vegard Nossum
2021-07-19 17:45                                                   ` Miguel Ojeda
2021-07-19 17:54                                                     ` Miguel Ojeda
2021-07-19 18:06                                                   ` Wedson Almeida Filho
2021-07-19 19:37                                                     ` Laurent Pinchart
2021-07-19 21:09                                                       ` Wedson Almeida Filho
2021-07-20 23:54                                                         ` Laurent Pinchart
2021-07-21  1:33                                                           ` Andy Lutomirski [this message]
2021-07-21  1:42                                                             ` Laurent Pinchart
2021-07-21 13:54                                                               ` Linus Walleij
2021-07-21 14:13                                                                 ` Wedson Almeida Filho
2021-07-21 14:19                                                                   ` Linus Walleij
2021-07-22 11:33                                                                     ` Wedson Almeida Filho
2021-07-23  0:45                                                                       ` Linus Walleij
2021-07-21  4:39                                                             ` Wedson Almeida Filho
2021-07-23  1:04                                                               ` Laurent Pinchart
2021-07-21  4:23                                                           ` Wedson Almeida Filho
2021-07-23  1:13                                                             ` Laurent Pinchart
2021-07-19 22:57                                                 ` Alexandre Belloni
2021-07-20  7:15                                                   ` Miguel Ojeda
2021-07-20  9:39                                                     ` Alexandre Belloni
2021-07-20 12:10                                                       ` Miguel Ojeda
2021-07-19 13:53                                               ` Linus Walleij
2021-07-19 14:42                                                 ` Wedson Almeida Filho
2021-07-19 22:16                                                   ` Linus Walleij
2021-07-20  1:20                                                     ` Wedson Almeida Filho
2021-07-20 13:21                                                       ` Andrew Lunn
2021-07-20 13:38                                                         ` Miguel Ojeda
2021-07-20 14:04                                                           ` Andrew Lunn
2021-07-20 13:55                                                         ` Greg KH
2021-07-20  1:21                                                     ` Miguel Ojeda
2021-07-20 16:00                                                       ` Mark Brown
2021-07-20 22:42                                                       ` Linus Walleij
2021-07-19 14:43                                                 ` Miguel Ojeda
2021-07-19 15:15                                                   ` Andrew Lunn
2021-07-19 15:43                                                     ` Miguel Ojeda
2021-07-09  7:03                                         ` Viresh Kumar
2021-07-09 17:06                                         ` Mark Brown
2021-07-09 17:43                                           ` Miguel Ojeda
2021-07-10  9:53                                             ` Jonathan Cameron
2021-07-10 20:09                                         ` Kees Cook
2021-07-08 13:55                                   ` Miguel Ojeda
2021-07-08 14:58                                     ` Greg KH
2021-07-08 15:02                                       ` Mark Brown
2021-07-08 16:38                                       ` Andy Lutomirski
2021-07-08 18:01                                         ` Greg KH
2021-07-08 18:00                                       ` Miguel Ojeda
2021-07-08 18:44                                         ` Greg KH
2021-07-08 23:09                                           ` Miguel Ojeda
2021-07-08  7:20                                 ` Geert Uytterhoeven
2021-07-08 13:41                                   ` Wedson Almeida Filho
2021-07-08 13:43                                     ` Geert Uytterhoeven
2021-07-08 13:54                                       ` Wedson Almeida Filho
2021-07-08 14:16                                         ` Geert Uytterhoeven
2021-07-08 14:24                                           ` Wedson Almeida Filho
2021-07-09  7:04                                             ` Jerome Glisse
2021-07-08 14:04                                       ` Miguel Ojeda
2021-07-08 14:18                                         ` Geert Uytterhoeven
2021-07-08 14:28                                           ` Miguel Ojeda
2021-07-08 14:33                                             ` Geert Uytterhoeven
2021-07-08 14:35                                               ` Miguel Ojeda
2021-07-09 11:55                                                 ` Geert Uytterhoeven
2021-07-08 16:07                                               ` Andy Lutomirski
2021-07-07 20:58                           ` Miguel Ojeda
2021-07-07 21:47                             ` Laurent Pinchart
2021-07-07 22:44                               ` Miguel Ojeda
2021-07-07 17:01           ` Miguel Ojeda
2021-07-07 10:50       ` Mark Brown
2021-07-07 10:56         ` Julia Lawall
2021-07-07 11:27           ` James Bottomley
2021-07-07 11:34         ` James Bottomley
2021-07-07 12:20           ` Greg KH
2021-07-07 12:38             ` James Bottomley
2021-07-07 12:45               ` Greg KH
2021-07-07 17:17                 ` Laurent Pinchart
2021-07-08  6:49                   ` cdev/devm_* issues (was Re: [TECH TOPIC] Rust for Linux) Greg KH
2021-07-08  8:23                     ` Laurent Pinchart
2021-07-08 23:06                     ` Linus Walleij
2021-07-09  0:02                       ` Dan Williams
2021-07-09 16:53                       ` Wedson Almeida Filho
2021-07-13  8:59                         ` Linus Walleij
     [not found]                           ` <CAHp75VfW7PxAyU=eYPNWFU_oUY=aStz-4W5gX87KSo402YhMXQ@mail.gmail.com>
2021-07-21 13:46                             ` Linus Walleij
2021-07-21 15:49                               ` Andy Shevchenko
2021-07-10  7:09                     ` Dan Carpenter
2021-07-12 13:42                       ` Jason Gunthorpe
2021-07-15  9:54                     ` Daniel Vetter
2021-07-21  9:08                       ` Dan Carpenter
2021-07-22  9:56                         ` Daniel Vetter
2021-07-22 10:09                           ` Dan Carpenter
2021-07-08  9:08                   ` [TECH TOPIC] Rust for Linux Mauro Carvalho Chehab
2021-07-10 16:42                     ` Laurent Pinchart
2021-07-10 17:18                       ` Andy Lutomirski
2021-07-07 15:17           ` Mark Brown
2021-07-06 21:45     ` Bart Van Assche
2021-07-06 23:08       ` Stephen Hemminger
2021-07-07  2:41         ` Bart Van Assche
2021-07-07 18:57           ` Linus Torvalds
2021-07-07 20:32             ` Bart Van Assche
2021-07-07 20:39               ` Linus Torvalds
2021-07-07 21:40                 ` Laurent Pinchart
2021-07-08  7:22                 ` Geert Uytterhoeven
2021-07-07 21:02               ` Laurent Pinchart
2021-07-07 22:11               ` Miguel Ojeda
2021-07-07 22:43                 ` Laurent Pinchart
2021-07-07 23:21                   ` Miguel Ojeda
2021-07-07 23:40                     ` Laurent Pinchart
2021-07-08  0:27                       ` Miguel Ojeda
2021-07-08  0:56                         ` Laurent Pinchart
2021-07-08  6:26             ` Alexey Dobriyan
2021-07-06 19:05 ` Bart Van Assche
2021-07-06 19:27   ` Miguel Ojeda
2021-07-07 15:48 ` Steven Rostedt
2021-07-07 16:44   ` Miguel Ojeda
2023-08-07 10:03 Miguel Ojeda

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=CALCETrWH4N17C+uHaDbzGkgS005feaOVQ25yGo9Zy0cb3+eeGA@mail.gmail.com \
    --to=luto@kernel.org \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=greg@kroah.com \
    --cc=jack@suse.cz \
    --cc=julia.lawall@inria.fr \
    --cc=keescook@chromium.org \
    --cc=ksummit@lists.linux.dev \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linus.walleij@linaro.org \
    --cc=miguel.ojeda.sandonis@gmail.com \
    --cc=roland@kernel.org \
    --cc=vegard.nossum@oracle.com \
    --cc=viresh.kumar@linaro.org \
    --cc=wedsonaf@google.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).