linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion
@ 2025-02-02 13:05 Asahi Lina
  2025-02-02 13:05 ` [PATCH 1/6] rust: types: Add Ownable/Owned types Asahi Lina
                   ` (7 more replies)
  0 siblings, 8 replies; 67+ messages in thread
From: Asahi Lina @ 2025-02-02 13:05 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross
  Cc: Jann Horn, Matthew Wilcox, Paolo Bonzini, Danilo Krummrich,
	Wedson Almeida Filho, Valentin Obst, Andrew Morton, linux-mm,
	airlied, Abdiel Janulgue, rust-for-linux, linux-kernel, asahi,
	Asahi Lina

This series refactors the existing Page wrapper to support borrowing
`struct page` objects without ownership on the Rust side, and converting
page references to/from physical memory addresses.

The series overlaps with the earlier submission in [1] and follows a
different approach, based on the discussion that happened there.

The primary use case for this is implementing IOMMU-style page table
management in Rust. This allows drivers for IOMMUs and MMU-containing
SoC devices to be written in Rust (such as embedded GPUs). The intended
logic is similar to how ARM SMMU page tables are managed in the
drivers/iommu tree.

First, introduce a concept of Owned<T> and an Ownable trait. These are
similar to ARef<T> and AlwaysRefCounted, but are used for types which
are not ref counted but rather have a single intended owner.

Then, refactor the existing Page support to use the new mechanism. Pages
returned from the page allocator are not intended to be ref counted by
consumers (see previous discussion in [1]), so this keeps Rust's view of
page ownership as a simple "owned or not". Of course, this is still
composable as Arc<Owned<Page>> if Rust code needs to reference count its
own Page allocations for whatever reason.

Then, make some existing private methods public, since this is needed to
reasonably use allocated pages as IOMMU page tables.

Along the way we also add a small module to represent a core kernel
address types (PhysicalAddr, DmaAddr, ResourceSize, Pfn). In the future,
this might grow with helpers to make address math safer and more
Rust-like.

Finally, add methods to:
- Get a page's physical address
- Convert an owned Page into its physical address
- Convert a physical address back to its owned Page
- Borrow a Page from a physical address, in both checked (with checks
  that a struct page exists and is accessible as regular RAM) and not
  checked forms (useful when the user knows the physaddr is valid,
  for example because it got it from Page::into_phys()).

Of course, all but the first two have to be `unsafe` by nature, but that
comes with the territory of writing low level memory management code.

These methods allow page table code to know the physical address of
pages (needed to build intermediate level PTEs) and to essentially
transfer ownership of the pages into the page table structure itself,
and back into Page objects when freeing page tables. Without that, the
code would have to keep track of page allocations in duplicate, once in
Rust code and once in the page table structure itself, which is less
desirable.

For Apple GPUs, the address space shared between firmware and the driver
is actually pre-allocated by the bootloader, with the top level page
table already pre-allocated, and the firmware owning some PTEs within it
while the kernel populates others. This cooperation works well when the
kernel can reference this top level page table by physical address. The
only thing the driver needs to ensure is that it never attempts to free
it in this case, nor the page tables corresponding to virtual address
ranges it doesn't own. Without the ability to just borrow the
pre-allocated top level page and access it, the driver would have to
special-case this and manually manage the top level PTEs outside the
main page table code, as well as introduce different page table
configurations with different numbers of levels so the kernel's view is
one lever shallower.

The physical address borrow feature is also useful to generate virtual
address space dumps for crash dumps, including firmware pages. The
intent is that firmware pages are configured in the Device Tree as
reserved System RAM (without no-map), which creates struct page objects
for them and makes them available in the kernel's direct map. Then the
driver's page table code can walk the page tables and make a snapshot of
the entire address space, including firmware code and data pages,
pre-allocated shared segments, and driver-allocated objects (which are
GEM objects), again without special casing anything. The checks in
`Page::borrow_phys()` should ensure that the page is safe to access as
RAM, so this will skip MMIO pages and anything that wasn't declared to
the kernel in the DT.

Example usage:
https://github.com/AsahiLinux/linux/blob/gpu/rust-wip/drivers/gpu/drm/asahi/pgtable.rs

The last patch is a minor cleanup to the Page abstraction noticed while
preparing this series.

[1] https://lore.kernel.org/lkml/20241119112408.779243-1-abdiel.janulgue@gmail.com/T/#u

Signed-off-by: Asahi Lina <lina@asahilina.net>
---
Asahi Lina (6):
      rust: types: Add Ownable/Owned types
      rust: page: Convert to Ownable
      rust: page: Make with_page_mapped() and with_pointer_into_page() public
      rust: addr: Add a module to declare core address types
      rust: page: Add physical address conversion functions
      rust: page: Make Page::as_ptr() pub(crate)

 rust/helpers/page.c  |  26 ++++++++++++
 rust/kernel/addr.rs  |  15 +++++++
 rust/kernel/lib.rs   |   1 +
 rust/kernel/page.rs  | 101 ++++++++++++++++++++++++++++++++++++++--------
 rust/kernel/types.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 236 insertions(+), 17 deletions(-)
---
base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04
change-id: 20250202-rust-page-80892069fc78

Cheers,
~~ Lina


^ permalink raw reply	[flat|nested] 67+ messages in thread
* Re: [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion
@ 2025-03-06 19:21 Oliver Mangold
  0 siblings, 0 replies; 67+ messages in thread
From: Oliver Mangold @ 2025-03-06 19:21 UTC (permalink / raw)
  To: Andreas Hindborg
  Cc: Abdiel Janulgue, Asahi Lina, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Alice Ryhl, Trevor Gross, Jann Horn, Matthew Wilcox,
	Paolo Bonzini, Wedson Almeida Filho, Valentin Obst, Andrew Morton,
	linux-mm, airlied, rust-for-linux, linux-kernel, asahi,
	Danilo Krummrich

On 250219 1024, Andreas Hindborg wrote:
> 
> 
> The series has application in `rnull` as well and I will probably add it
> as a dependency for next version.
> 
> 

Hi,

would anyone mind if I pick this up? I'm working on that patch:

https://lore.kernel.org/all/20250305-unique-ref-v4-1-a8fdef7b1c2c@pm.me/

There is a lot of overlap, so it would make sense, I think, to base
it on this one.

Oliver


^ permalink raw reply	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2025-03-06 19:21 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-02 13:05 [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion Asahi Lina
2025-02-02 13:05 ` [PATCH 1/6] rust: types: Add Ownable/Owned types Asahi Lina
2025-02-03  9:13   ` Alice Ryhl
2025-02-03 14:17     ` Asahi Lina
2025-02-03 18:17       ` Alice Ryhl
2025-02-03 19:17         ` Asahi Lina
2025-02-19  8:34           ` Andreas Hindborg
2025-02-19  8:37   ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 2/6] rust: page: Convert to Ownable Asahi Lina
2025-02-03  9:17   ` Alice Ryhl
2025-02-03  9:39   ` Fiona Behrens
2025-02-19  8:46   ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 3/6] rust: page: Make with_page_mapped() and with_pointer_into_page() public Asahi Lina
2025-02-03  9:10   ` Alice Ryhl
2025-02-03  9:43   ` Fiona Behrens
2025-02-19  8:48   ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 4/6] rust: addr: Add a module to declare core address types Asahi Lina
2025-02-03  9:09   ` Alice Ryhl
2025-02-03 15:04   ` Boqun Feng
2025-02-04 11:50     ` Asahi Lina
2025-02-04 14:50       ` Boqun Feng
2025-02-19  8:51   ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 5/6] rust: page: Add physical address conversion functions Asahi Lina
2025-02-03  9:35   ` Alice Ryhl
2025-02-04 11:43     ` Asahi Lina
2025-02-03  9:53   ` Fiona Behrens
2025-02-03 10:01     ` Alice Ryhl
2025-02-19  9:06   ` Andreas Hindborg
2025-02-02 13:05 ` [PATCH 6/6] rust: page: Make Page::as_ptr() pub(crate) Asahi Lina
2025-02-03  9:08   ` Alice Ryhl
2025-02-19  9:08   ` Andreas Hindborg
2025-02-03  9:58 ` [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion Simona Vetter
2025-02-03 14:32   ` Asahi Lina
2025-02-03 21:05     ` Zi Yan
2025-02-04 10:26       ` David Hildenbrand
2025-02-04 11:41         ` Asahi Lina
2025-02-04 11:59           ` David Hildenbrand
2025-02-04 13:05             ` Asahi Lina
2025-02-04 14:38               ` David Hildenbrand
2025-02-04 17:59                 ` Asahi Lina
2025-02-04 20:10                   ` David Hildenbrand
2025-02-04 21:06                     ` Asahi Lina
2025-02-06 17:58                       ` David Hildenbrand
2025-02-06 19:18                         ` Asahi Lina
2025-02-06 19:27                           ` Asahi Lina
2025-02-12 19:06                             ` David Hildenbrand
2025-02-12 19:01                           ` David Hildenbrand
2025-02-05  7:40                 ` Simona Vetter
2025-02-12 19:07                   ` David Hildenbrand
2025-02-04 10:33   ` David Hildenbrand
2025-02-04 18:39     ` Jason Gunthorpe
2025-02-04 19:01       ` Asahi Lina
2025-02-04 20:05       ` David Hildenbrand
2025-02-04 20:26         ` Jason Gunthorpe
2025-02-04 20:41           ` David Hildenbrand
2025-02-04 20:47             ` David Hildenbrand
2025-02-04 21:18               ` Asahi Lina
2025-02-06 18:02                 ` David Hildenbrand
2025-02-04 20:49             ` Jason Gunthorpe
2025-02-05 23:17               ` Matthew Wilcox
2025-02-06 18:04                 ` David Hildenbrand
2025-02-03 10:22 ` Danilo Krummrich
2025-02-03 14:41   ` Asahi Lina
2025-02-15 19:47     ` Asahi Lina
2025-02-17  8:50       ` Abdiel Janulgue
2025-02-19  9:24         ` Andreas Hindborg
  -- strict thread matches above, loose matches on Subject: below --
2025-03-06 19:21 Oliver Mangold

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).