From patchwork Sun Feb 2 13:05:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asahi Lina X-Patchwork-Id: 13956517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id D067CC0218F for ; Sun, 2 Feb 2025 13:06:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BBC4E6B0083; Sun, 2 Feb 2025 08:06:43 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B42196B0088; Sun, 2 Feb 2025 08:06:43 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9D7326B0085; Sun, 2 Feb 2025 08:06:43 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 841846B007B for ; Sun, 2 Feb 2025 08:06:43 -0500 (EST) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 1F554460F1 for ; Sun, 2 Feb 2025 13:06:43 +0000 (UTC) X-FDA: 83075029086.04.91E4738 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by imf08.hostedemail.com (Postfix) with ESMTP id 059A9160016 for ; Sun, 2 Feb 2025 13:06:40 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=asahilina.net header.s=default header.b=sHtpEBEh; spf=pass (imf08.hostedemail.com: domain of lina@asahilina.net designates 212.63.210.85 as permitted sender) smtp.mailfrom=lina@asahilina.net; dmarc=pass (policy=quarantine) header.from=asahilina.net ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1738501601; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=VHZ6wBxvdDNAC6lAQt6lr8sN3EN1UVIQIOXgJVAgc7E=; b=GszvUaaTal8xk5f583Rg28xPCFdLfUqCVdZmcRSHGdv3eqeXbjC1lJ3vJ9XxovzFrAuSU7 O+IhUkeIoUxHsPUAiUfWxY4E1nH6k+vgM/oZaTijpxSRZESVaVG2syNPAngdKUyIaSjsNh ctABnMu3REeVh28erQpGhxrSloAAeXM= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1738501601; a=rsa-sha256; cv=none; b=YraEaJ/eGsxHwSwgkX6/JuCqSzSqKkLGrZVZ2feVkPqH1WrycLs97bsesK2T01st95XucR TGfyF0bEUuhjhfQkM81UaHpFVosxTTBCjm9/glVNNEJ+roZGxmauyrUSa1ZUq9uumcel0x 3zhvr1yxgVLQRbrDbjZPpQt+Umr2Qfw= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=asahilina.net header.s=default header.b=sHtpEBEh; spf=pass (imf08.hostedemail.com: domain of lina@asahilina.net designates 212.63.210.85 as permitted sender) smtp.mailfrom=lina@asahilina.net; dmarc=pass (policy=quarantine) header.from=asahilina.net Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 7E9F0425F5; Sun, 2 Feb 2025 13:06:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=asahilina.net; s=default; t=1738501596; bh=lYa739FBsMmfPZUrxXPgYM7y6ANDDXCOgs8EeLdJuIU=; h=From:Subject:Date:To:Cc; b=sHtpEBEhN8aV54g4n630xVvX5grEtjQF6eEzFIu6irPJ2o0LOElCtM5i0h0mmdxbl wPoq6uAj3SMfjGtyRDZ7Z+DdKm0UGzLuHwr41mtlui6hgWnIz5z7Jqrxpg8UrqfSAE X+qH5dfBo8BeBOUMj5RVAFX9Bv4W/glyDKIUICvzSIQlcJ4TohFhkbhwp4WloTikuk +SnF/wY7Sd5geLJIaxj/QaydPj44xbCGWWpHC+PqHLo/nWAUW6leAoFVZK8BglNE1J 5d8aKOeJ6o9X+rrHwnqtO250YNsNN2KY6ZPWBK3VidX1jrYPbS9UdzMobjPpSqO+IW G0nsm2+VuMIGA== From: Asahi Lina Subject: [PATCH 0/6] rust: page: Support borrowing `struct page` and physaddr conversion Date: Sun, 02 Feb 2025 22:05:42 +0900 Message-Id: <20250202-rust-page-v1-0-e3170d7fe55e@asahilina.net> MIME-Version: 1.0 X-B4-Tracking: v=1; b=H4sIAKZtn2cC/6tWKk4tykwtVrJSqFYqSi3LLM7MzwNyDHUUlJIzE vPSU3UzU4B8JSMDI1MDIKFbVFpcoluQCJSwMLCwNDIws0xLNrdQAqovKEpNy6wAmxUdW1sLALQ AkMFbAAAA X-Change-ID: 20250202-rust-page-80892069fc78 To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_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@kvack.org, airlied@redhat.com, Abdiel Janulgue , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, Asahi Lina X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1738501594; l=5446; i=lina@asahilina.net; s=20240902; h=from:subject:message-id; bh=lYa739FBsMmfPZUrxXPgYM7y6ANDDXCOgs8EeLdJuIU=; b=F/JZiGpp7pVG5cTzcCbqbdB1Briqb0CLln0Ql7ruoo0pkNq6xVwI5VO+3SILodtMfPrJtDrIP OJxPqS357wVDzcDfaHa1+XGEvfN6Alc2PpHDzUP6O/JBAcS0Wuz72nq X-Developer-Key: i=lina@asahilina.net; a=ed25519; pk=tpv7cWfUnHNw5jwf6h4t0gGgglt3/xcwlfs0+A/uUu8= X-Stat-Signature: f7c4ppb5pdu6sepoft6bkpozdzrk1hjj X-Rspamd-Queue-Id: 059A9160016 X-Rspam-User: X-Rspamd-Server: rspam06 X-HE-Tag: 1738501600-593506 X-HE-Meta: U2FsdGVkX1/QjikGvqcqzw91FepEwvKDXiv1cF0Jm3n92KtoXKAv3hjAPQnKNo4ScsbBTixOuWRYJbsG3AfJ6vsqRjn6u+dxzbVpMHFgiCVTIpoGprodcjG0UBeBmb5b5hAD5qvp4/X+WuEU3u9/XJciE/xqunVZSlulXGGtc7859XLusGfYkLJlYUTacqVLEhc0wrf9BSm/Irwecj51ziCeSTx3ZyMDaAxT6Gwt2NRQiLSkOTDLMnz40pqogCKqOJCgJJDugcb5/qErKuW5lTONPGGVnUOetBMlankBHeS37DpfCymlX2zOV7Sw2BSn2bqsL8CZBaES6PfvIuGh39N4BXrhBXHm9a4n9o5UzsbsWJT1tdDvX4AbZQvX0axI6Hi1Dz2YhpOD8nGZuu+4J/fuwUDluH1aDPfaOAgMScxxK5g6dwFO6kL4MGiwykRa+d9gRSctfvNubvb7HEEP2J/DvVbSBgCuHmxVv1EzL8xhpVlw04f2mdT6VVE90mhFm5zgzLF5uUN9KFj+9v6YMXB3ViIvDNfYadHyo7FoNteqylBZK8vHBfAMWgqpEghnlQ7UieP5VDX+LVW1NXN87nVW8ayX3STyMd3KX7VSOOzof3AGhSUkb/9gbLoNRAkTZw5v5b608PdE2GARJSlCcUTZLbELJxNrv5deX8yuEuDjsK81qJ/ZdQj3wgoO812rODCww2YfHAsd06beKBJ7nT5s+N1iqEft4q9xYc6j7oThlgsAADA3RqjrX50bqK3e5cV558TJU7TSqz41q+/IYBRty8wcQBwZToRRfX5/qex/CAh0EXcgXRMH3SEwvlDfzLi5ixiEeFyBfvoWSvHCOsS+KJRl0/a6NDGp0cR12pYWU+UZp9W8rl+v2/BXpSWmnY42OYnVLRUY5iqj/E9EApu1Wkm8z6vI8UYkOnlCr3wJVZNSdm03jbgTK6ILffiL8wSndacFCwln3rnG5vt zD1/W1uu CPFdaOhCscBLnzaaSXXSk1EQ37YMECApPHwYeS65kZuj3OE4Aj/cbKLLpBak7wEj0kZzfavJw+32oN2q6Ggzh7LoNHkLL7GFwiRlKuthnQ6R6kOWO1VznNtSV7nqd2Yf4eY5FWvOQzbdAA/SB02hw/M/cldhUnvOof/WSJInOCnX78k7wCxbTObpLWJ7+FSMXgMYU5p9Jrw7LMAw4wvaH/48ewzH6pRsuo+gY8A36uJ3Tly1T5JvawKTlTnjUphpyfNQ3yOSfo5rBH7YvVuokDJXmV8ubln+yILzKUBEmL5Nm/s+kWrSZ4qEX4/9KvvaERjGpGkvR/+GX7BGQpjKoL7675pi1Fp8SdJOjuDptg7WfSL9u6re+7UroOsUU8d3wQE5XbL6AvaUFdfKcnwrBCdc6SdsgnhgzuYIPhoN5TCXQwFNmLJO/XfChQVYiY0MBsVp3ve1Qu7daRLZ9qPic/kbhci3M7b8Zh9MQ+R8KNa81hWDx45EDTtwRxQee/LBeWl6uw6IGeMZys4s= X-Bogosity: Unsure, tests=bogofilter, spamicity=0.495135, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: 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 and an Ownable trait. These are similar to ARef 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> 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 --- 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