From: Zhi Wang <zhiw@nvidia.com>
To: Danilo Krummrich <dakr@redhat.com>
Cc: "maarten.lankhorst@linux.intel.com"
<maarten.lankhorst@linux.intel.com>,
"mripard@kernel.org" <mripard@kernel.org>,
"tzimmermann@suse.de" <tzimmermann@suse.de>,
"airlied@gmail.com" <airlied@gmail.com>,
"daniel@ffwll.ch" <daniel@ffwll.ch>,
"ojeda@kernel.org" <ojeda@kernel.org>,
"alex.gaynor@gmail.com" <alex.gaynor@gmail.com>,
"wedsonaf@gmail.com" <wedsonaf@gmail.com>,
"boqun.feng@gmail.com" <boqun.feng@gmail.com>,
"gary@garyguo.net" <gary@garyguo.net>,
"bjorn3_gh@protonmail.com" <bjorn3_gh@protonmail.com>,
"benno.lossin@proton.me" <benno.lossin@proton.me>,
"a.hindborg@samsung.com" <a.hindborg@samsung.com>,
"aliceryhl@google.com" <aliceryhl@google.com>,
"fujita.tomonori@gmail.com" <fujita.tomonori@gmail.com>,
"lina@asahilina.net" <lina@asahilina.net>,
"pstanner@redhat.com" <pstanner@redhat.com>,
"ajanulgu@redhat.com" <ajanulgu@redhat.com>,
"lyude@redhat.com" <lyude@redhat.com>,
"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
"rust-for-linux@vger.kernel.org" <rust-for-linux@vger.kernel.org>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
"nouveau@lists.freedesktop.org" <nouveau@lists.freedesktop.org>
Subject: Re: [RFC PATCH 7/8] rust: add firmware abstractions
Date: Tue, 28 May 2024 21:20:33 +0000 [thread overview]
Message-ID: <b44bdeb1-8663-4b3f-9b09-cdeec2e42dd2@nvidia.com> (raw)
In-Reply-To: <ZlXnxGK24QaYLDmM@pollux>
On 28/05/2024 17.18, Danilo Krummrich wrote:
> External email: Use caution opening links or attachments
>
>
> On Tue, May 28, 2024 at 08:40:20AM +0000, Zhi Wang wrote:
>> On 27/05/2024 22.18, Danilo Krummrich wrote:
>>> External email: Use caution opening links or attachments
>>>
>>>
>>> On Tue, May 21, 2024 at 08:32:31AM +0300, Zhi Wang wrote:
>>>> On Mon, 20 May 2024 19:24:19 +0200
>>>> Danilo Krummrich <dakr@redhat.com> wrote:
>>>>
>>>>> Add an abstraction around the kernels firmware API to request firmware
>>>>> images. The abstraction provides functions to access the firmware
>>>>> buffer and / or copy it to a new buffer allocated with a given
>>>>> allocator backend.
>>>>>
>>>>
>>>> Was playing with firmware extractions based on this patch.
>>>> Unfortunately I ended up with a lot of pointer operations, unsafe
>>>> statements.
>>>>
>>>> As we know many vendors have a C headers for the definitions of the
>>>> firwmare content, the driver extract the data by applying a struct
>>>> pointer on it.
>>>>
>>>> But in rust, I feel it would nice that we can also have a common
>>>> firmware extractor for drivers, that can wrap the pointer operations,
>>>> take a list of the firmware struct members that converted from C headers
>>>> as the input, offer the driver some common ABI methods to query them.
>>>> Maybe that would ease the pain a lot.
>>>
>>> So, you mean some abstraction that takes a list of types, offsets in the
>>> firmware and a reference to the firmware itself and provides references to the
>>> corresponding objects?
>>>
>>> I agree it might be helpful to have some common infrastructure for this, but the
>>> operations on it would still be unsafe, since ultimately it involves
>>> dereferencing pointers.
>>>
>>
>> I think the goal is to 1) concentrate the "unsafe" operations in a
>> abstraction so the driver doesn't have to write explanation of unsafe
>> operations here and there, improve the readability of the driver that
>> interacts with vendor-firmware buffer. 2) ease the driver maintenance
>> burden.
>
> With a generic abstraction, as in 1), at lest some of the abstraction's
> functions would be unsafe themselves, since they have to rely on the layout
> (or offset) passed by the driver being correct. What if I pass a wrong layout /
> offset for a structure that contains a pointer? This might still result in an
> invalid pointer dereference. Am I missing something?
>
>>
>> Some solutions I saw in different projects written in rust for
>> de-referencing a per-defined struct:
>>
>> 1) Take the vendor firmware buffer as a whole, invent methods like
>> read/write with offset for operating the buffer.
>>
>> In this scheme, the driver is responsible for taking care of each data
>> member in a vendor firmware struct and also its valid offset. The
>> abstraction only covers the boundary of the whole firmware buffer.
>>
>> The cons is the readability of the operation of the vendor firmware
>> buffer in the driver is not good comparing with C code.
>>
>> Hate to think a lot of xxx = vendor_firmware_struct.read(offset); //
>> reading item A in the code.
>>
>> 2) Define the firmware struct in rust (might need to find a better way
>> to handle "union" in the definition of the vendor firmware struct). Use
>> macros to generate methods of accessing each data member for the vendor
>> firmware struct.
>>
>> Then the code in the driver will be like xxx =
>> vendor_firmware_struct.item_a(); in the driver.
>>
>> In this scheme, the abstraction and the generated methods covers the
>> boundary check. The "unsafe" statement can stay in the generated
>> struct-access methods.
>>
>> This might even be implemented as a more generic rust feature in the kernel.
>
> This sounds more like a driver specific abstraction to me, which, as you write,
> we can probably come up with some macros that help implementing it.
>
> But again, what if the offsets are within the boundary, but still at a wrong
> offset? What if the data obtained from a wrong offset leads to other safety
> implications when further processing them? I think no generic abstraction can
> ever cover the safety parts of this (entirely). I think there are always semanic
> parts to this the driver has to cover.
>
I was thinking of a proc_macro that takes a vender-firmware struct
definition. As it can get the type and the name of each member, then it
can generate methods like xxx::member_a() that returns the value from
the "unsafe {*(type *)(pointer + offset)}". Thus, the unsafe stuff stays
in the generated methods.
For offset, I was hoping the macro can automatically calculate it based
on the member offset (the vendor-firmware definition) when generating
xxx::member_x(). (Maybe it can also take alignment into account)
As the return value has a rust type, rust should catch it if the caller
wants to do something crazy there.
> Generally, I think we should aim for some generalization, but I think we should
> not expect it to cover all the safety aspects.
>
I agree. I was mostly thinking how to ease the pain of driver and see
how the best we can do for it.
>>
>> The cons is still the driver might need to sync between the C-version
>> definition and rust-version definition.
>
> What do you mean with the driver needs to sync between a C and a Rust version of
> structure definitions?
>
Let's say a C driver maintains quite some headers and support some not
very new HWs. A new rust driver maintains some headers that written in
rust, it needs those headers as well. Now the firmware updates, both the
C headers and rust headers needs to be updated accordingly due to ABI
changes.
I was thinking if that process can be optimized, at least trying to
avoid the sync process, which might be painful if the amount of the
headers are huge.
>>
>> 3) Also re-using C bindings generation in the kernel came to my mind
>> when thinking of this problem, since it allows the rust code to access
>> the C struct, but they don't have the boundary check. Still need another
>> layer/macros to wrap it.
>
> I think we should have the structure definitions in Rust directly.
>
> - Danilo
>
>>
>>
>>>>
>>>> Thanks,
>>>> Zhi.
>>>>
>
next prev parent reply other threads:[~2024-05-28 21:20 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-20 17:20 [RFC PATCH 0/8] [RFC] DRM Rust abstractions and Nova Danilo Krummrich
2024-05-20 17:20 ` [RFC PATCH 1/8] rust: drm: ioctl: Add DRM ioctl abstraction Danilo Krummrich
2024-05-20 17:20 ` [RFC PATCH 2/8] rust: Add a Sealed trait Danilo Krummrich
2024-05-20 17:20 ` [RFC PATCH 3/8] rust: drm: Add Device and Driver abstractions Danilo Krummrich
2024-05-21 21:23 ` Rob Herring
2024-05-27 19:26 ` Danilo Krummrich
2024-06-09 5:15 ` Asahi Lina
2024-06-09 14:18 ` Danilo Krummrich
2024-06-11 15:46 ` Rob Herring
2024-05-20 17:20 ` [RFC PATCH 4/8] rust: drm: implement `AsRef` for DRM device Danilo Krummrich
2024-05-20 17:24 ` Danilo Krummrich
2024-05-20 17:24 ` [RFC PATCH 5/8] rust: drm: file: Add File abstraction Danilo Krummrich
2024-05-20 17:24 ` [RFC PATCH 6/8] rust: drm: gem: Add GEM object abstraction Danilo Krummrich
2024-06-06 15:26 ` Daniel Almeida
2024-05-20 17:24 ` [RFC PATCH 7/8] rust: add firmware abstractions Danilo Krummrich
2024-05-21 5:32 ` Zhi Wang
2024-05-27 19:18 ` Danilo Krummrich
2024-05-28 8:40 ` Zhi Wang
2024-05-28 10:17 ` FUJITA Tomonori
2024-05-28 10:45 ` Zhi Wang
2024-05-28 14:18 ` Danilo Krummrich
2024-05-28 21:20 ` Zhi Wang [this message]
2024-05-21 23:53 ` FUJITA Tomonori
2024-05-22 7:37 ` Philipp Stanner
2024-05-22 23:15 ` FUJITA Tomonori
2024-05-23 2:48 ` Boqun Feng
2024-05-27 19:22 ` Danilo Krummrich
2024-05-28 11:01 ` FUJITA Tomonori
2024-05-28 12:19 ` Danilo Krummrich
2024-05-28 12:45 ` Greg KH
2024-05-28 13:17 ` Danilo Krummrich
2024-05-29 0:28 ` FUJITA Tomonori
2024-05-29 19:57 ` Greg KH
2024-05-29 23:28 ` FUJITA Tomonori
2024-05-30 2:01 ` Danilo Krummrich
2024-05-30 4:24 ` FUJITA Tomonori
2024-05-30 6:47 ` Danilo Krummrich
2024-05-31 7:50 ` FUJITA Tomonori
2024-05-31 9:59 ` Danilo Krummrich
2024-06-07 12:11 ` FUJITA Tomonori
2024-06-07 12:36 ` Greg KH
2024-06-07 13:05 ` Danilo Krummrich
2024-06-07 13:33 ` Danilo Krummrich
2024-06-07 15:41 ` Greg KH
2024-06-07 17:55 ` Danilo Krummrich
2024-06-07 23:28 ` FUJITA Tomonori
2024-06-10 13:13 ` Danilo Krummrich
2024-06-07 12:43 ` Danilo Krummrich
2024-05-29 0:38 ` FUJITA Tomonori
2024-05-28 12:06 ` Danilo Krummrich
2024-05-20 17:24 ` [RFC PATCH 8/8] nova: add initial driver stub Danilo Krummrich
2024-05-20 17:30 ` Device / Driver and PCI Rust abstractions Danilo Krummrich
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=b44bdeb1-8663-4b3f-9b09-cdeec2e42dd2@nvidia.com \
--to=zhiw@nvidia.com \
--cc=a.hindborg@samsung.com \
--cc=airlied@gmail.com \
--cc=ajanulgu@redhat.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@redhat.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=lina@asahilina.net \
--cc=lyude@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=pstanner@redhat.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tzimmermann@suse.de \
--cc=wedsonaf@gmail.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).