From patchwork Tue Apr 8 09:22:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042480 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 32318C369A4 for ; Tue, 8 Apr 2025 09:24:05 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9894D6B0008; Tue, 8 Apr 2025 05:24:03 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 95FD86B000A; Tue, 8 Apr 2025 05:24:03 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7DAB66B000C; Tue, 8 Apr 2025 05:24:03 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 5B70E6B0008 for ; Tue, 8 Apr 2025 05:24:03 -0400 (EDT) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 27BB8160985 for ; Tue, 8 Apr 2025 09:24:04 +0000 (UTC) X-FDA: 83310340008.03.D2DEC8B Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf25.hostedemail.com (Postfix) with ESMTP id 2C5C0A000C for ; Tue, 8 Apr 2025 09:24:01 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=fvP7kzoz; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 3MOv0ZwkKCCE7IF9BOVEIDLLDIB.9LJIFKRU-JJHS79H.LOD@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3MOv0ZwkKCCE7IF9BOVEIDLLDIB.9LJIFKRU-JJHS79H.LOD@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104242; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ki4H2x3bNdUZgaxD5TSjlFdpv0BBNOUt/zA8zBiktxo=; b=hGW+EXjo6vu2Tpy60Xs19FKCmR/dKkJEm/0WAOo4dGfENIRDJEgh3O+sy6mgTzwi1V84vO JpgmcwpuFfHT6NkFTnCh4R5LZ4TBVo2dz/Hy3lfX0rhMD1KQvcUsQc2mu45VenLeZ1pKfy qTKG99OHaBUJ/6xvG3IH9TS2wG5LdVI= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=fvP7kzoz; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 3MOv0ZwkKCCE7IF9BOVEIDLLDIB.9LJIFKRU-JJHS79H.LOD@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3MOv0ZwkKCCE7IF9BOVEIDLLDIB.9LJIFKRU-JJHS79H.LOD@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104242; a=rsa-sha256; cv=none; b=f1qkLem0KELwBuHvquv7FUwSMeknBRtGMJd25Dnet+o0GO1sK7gxsscN1eG7TkfLqguuJQ K2do5O/4+FQRNCh3Y0hYap6TQYUpvDHYUAnQZsD1nrODrTHyA+NIGt1EUFR7Lnnx5+PjPA BB9Z9iPnFb6vT6mfBF1+7v9zRKxvhWA= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43ceb011ea5so35603855e9.2 for ; Tue, 08 Apr 2025 02:24:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104240; x=1744709040; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ki4H2x3bNdUZgaxD5TSjlFdpv0BBNOUt/zA8zBiktxo=; b=fvP7kzozSgM1aU7l25qfID5a1ZbGHxVp6+eI8v6LF9nJBF/jNxAgn1+Wq2p0B/2Hjk +YOqWIth6Ze9+8D8Ivt07Np/NAdR6aJx4S52teCJfgerSh0nJwLCz2dt80SdP/cvJbp6 Gm7jgy6qJwTsGhBTT0rUnAPxiMrmzcNjh9wHNN2lFzIONqudXaaPcS8QFVoo3fci2Ibt NhcpkoVZz+JTZuMJLLPQgHC4D8zq+VJPpEI6s8u++vKXzZc9sAhDRjkmugGqzatwLPXj tOM01uzkjLLrVYVFUEYGlsaXLObCb7zcC7NNtJspVoqSFiNLx7+jEsfXJUcyK3Z/Dcv1 tQVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104240; x=1744709040; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ki4H2x3bNdUZgaxD5TSjlFdpv0BBNOUt/zA8zBiktxo=; b=wwnXdXIuA+X8DousXhb4bLq7ZBu/hjnPzy26WE9djzr7da9EIQLGe2eK1YVEp/MKsM 6bTKKALLfuqA9T0L/155z+vpPhqsiZ5R9SDvNSUK/l84vsvtMBD7JKMREpiKDrolf5qp UjpxEuqFfNTsfOTUh62H1vwD5vzxQJXx8NnZciJjjZvV2LH/e3GI8pl0XxBxjX1uB1eV o6R1+p61PcVMszIap6jtki5bZQfEG7jaw2/fVhu9CNiNev8aO6ss2iTyH7k0V6DqBEyF j3ES6iiIuXraKhNWtyhLMLFpVO3u06LsPAFrBQnOVuFK1sXSwY3Ld/bMAsEZKhsIwUU8 bp7g== X-Forwarded-Encrypted: i=1; AJvYcCUQqx5q3u6LEvkscu+Zyxov/c5D9NNgbQWPAtK14CPTiMN3GdelyPhg8Pebl0rP+5SVqBlG83J+GQ==@kvack.org X-Gm-Message-State: AOJu0Yw8BJL2havhcDoPRz327x0ZCrLid0s3RHeqIpg1myJPIcsLRLBh 024n6LQz46Tk8NjcfUcASIBYpBS06B77ag95Yh6IT/l1uoVz+LWmqdSOelPe/yp0oA4p2Q0mXRj 2Y13fAwLN6BsugQ== X-Google-Smtp-Source: AGHT+IHYfn2jFMPzZbozv1znd+quFlDYUIdmNio1DMNMO7NMjqNG77qP6RfgBjCyxquhSAqEKulRpzj7mSohx+c= X-Received: from wmbh6.prod.google.com ([2002:a05:600c:a106:b0:43d:9035:df36]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1385:b0:43d:46de:b0eb with SMTP id 5b1f17b1804b1-43ecf85f4e8mr141716885e9.12.1744104240706; Tue, 08 Apr 2025 02:24:00 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:38 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=10913; i=aliceryhl@google.com; h=from:subject:message-id; bh=yxKBHgKEF0Pk92dXT07hzBYbzkqnu7N3MQCAKHqDQNA=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OslaWj4W4zK8+NCEygrsxAUbocMAkAmSrImM xsssH4ZEoaJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrJQAKCRAEWL7uWMY5 Rg9WEAC11iTd6isdQt5qWtvteId/5hP34edfgj8zeH/4CCCW00Sw4HXzTdwHcAegqA1muaKjn0f J9g0wzBZm1fKyRsYLajYxd5Z59jJLlnRrAE5QfbCH90AXUJdc6FftYwB/Jg/JubN3dPNeUYGScU 3ISw9I3xEMA11Px/O+Ai4VVQhN5aR6M44VEyeWxjUgIN2aj7S1pfgnhM+AfmSU2HAYhOHnIqqGe /sVoQtjoOWcfn4/4+Ghg4n5I9Fa3BB6UMd65UaRMBOm9sOzKe3pPw3zybomx1Pb48m/cr1jsJuC SF2dgkMwbO6tvcB5B9exQAD2f2mXfABlxB5KQMzrm9yUaNVYyYEeVU9bluKJIZpPgA/mXkL3NLu 2r0p7NITtj68BUpmG84+W+baaOb30suihSe42mN7lZ88HnlMBmjdk8X8wbt9hvqd5FuG+kYUmiO JJIXTk8EEz7zJ5QD8ZeS+M9vxo7Ut7u5dh9ysXcliHRqMkXioNnPn90W1qvICxl+Tmpz9ENOlwG khFeLyAnteQfbc1E2BSvhXJxziluA8Mq8jwVSWB8/EI7d/h2/a7AiIZJrV6DuwFBUVNaThNUegs A7dNpcPApjwoUJCn2UaYGBgaP3qBi8wES2xeBK2IpYNgpUA9i2MojX3EhyzyigwWiEoWdI7h5kx Ga+MA9pPHmxkk9w== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-1-d8b446e885d9@google.com> Subject: [PATCH v16 1/9] mm: rust: add abstraction for struct mm_struct From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Balbir Singh X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: 2C5C0A000C X-Stat-Signature: p8die7gi3azqxxqqsn6zzdutuhptfrbz X-Rspam-User: X-HE-Tag: 1744104241-325841 X-HE-Meta: U2FsdGVkX1+B2iZ80NYYd2Mkuxgbduu7fX4h9xBgM3ksR6ALlBA/nri8JogJb498tZPwx0oGFjAfUHJtDamQk1n9GGKiiK8vTXAKD9C35myTGoNmOUhAyOczJJCyU7qOTumLxW3up3eix67p2VIpNvLIdnHrU3bZxzIu9cEuE30sgiZZVHFayjss5j9yJDMiDxh9UcGPxzfTLz4GvP+nZ3xoD9V7LZEEMPf5DVQyZ5IlZ25K0MyvDGwKlVWBEmG2Y2bbtvkMGy8PB6SEn4pwa/euCZ+IRERnYHY/CeBIteUAOY5NVfcmWdwmUc6z0Xs57e1aX7Ubh2eIHNTGiihH6kXurDFQSGhiMBQ6eFqBFfCMxv+1u55lm1IbiDhQrqrLrpTjcw8iUVx8yt7ETuah6xSeIHNrBsuDJ3a9izS8tCuovn8D9D5aWHhHalrfBPHvIR3xmU8hSrALdx+4eTOnXTKghzz4pjdrA/BrvJzhf8tWhkAHz451n5kNI2CSP2mWMrtjPrLB448fU3rU65uOEHOhKYVR02dvt9Nojf9Llwf5f3Ns3S+f6EjSr0ODvBL/YP1hhd1sgXMRC9qHlpREYPychjGjkT05N90SfI4ZbbM8E56QU8kX0FbcO/KLj3yygUt1rN0HronpZYxQlJ+r+uChpann9ZDWF36gWE1hdBjR6LXtwKYeAezZ4YiS9TeYxzQjto+bEZtu1QeaMVaTT3DCbudSBSlqgtJTRQlqdj3z3ukXCorgZ+NOou4kHs5tTFXUFsP4cGXpiBXAKXU9UCRXqVo3GvFDobxCT+Uta8vvTHFeY4RW9QHg8ySfhTzn/dObRJsONrwN4F83cvZ16Swu3Xpi3WXRdh2bw5y5OhL63YqIj9OsLJdtbr7pv4pYJiClp7Urw0OU+CU2q3SmfKUoj77ywpR+9vFzFYmy2VerW5gVEXVR98Pq2uspkj2v0KLLhwLPo0+vMRvURC1 B+rwL3f/ o4lST6V/23bS5nrj83m/rEfZRZS3Rh+5Mb8NEkl+SYXjw58PTf0KyV2ChXWTjxPjTqCoky7XPLF3UlvLvUoeXVKxj6vrKwQgZIS2vzOs4MdRmUnxANAFKBsn5mTSRQOlT2rqnMJYlRbjy/DlmJ45J0AKnz30wx/kt2D3XOn7TVpaJuD5Ogu61kvd03NegnnIWeuhvDN40/zL/J2JweraJeXvhQExSQzpqFiwvt5yxCnYNFkf70koECynU3mTig+M0oTwtqi60u+/YUUhK1AhQ+jpPR/VZPpqP5TRpVIhBi0qo+krciPlp6i83FcYUypH0VohkfNKcW5jW7/bZC0ici8gpD7nqTZmS2HHwIQwHQWtAb/H64adUoWn2tm7pLZX4zPMAWuFSX5e6bAgS7F0BA0OyuFTqiVG3gtr94QBpJFj7aQjNKKhIZn8w/LfgdCZD8aPonMNzx/thBFEhQyAWMBsSbRJUVgNdBImSW9BV1sUsIbYcmgbq9E8MvJhSbh+hz1Zmk/JmEV/BLmDZZEUO0001fXpkLqu5qVc798li//tdnuk6FEbvNVRvEdNvNijQ0b18S+tvs1whnspDc+VwkgHKRudinhPHbOJGblwwsgcIhao/C7xKdcCehMEZ4mYznQ7P5eZ7p7OIi9/FBBU3DfgiQIoyZOXUX90aI9IBbB3+bHOsq1U7jSvRNx0//z0KtnjrZGScye74nmfLlMd83mbDFSIk68QmbzLLDDsNNhqWdAsZGeQBIhohumuPG9iAaJald/PtV/5BCyJi6Lc9ImwKrk43oqARLPjF1gdgoQax+mXx+VdeobfO2eulBI4Ffgj2JatudoyVcus= X-Bogosity: Ham, tests=bogofilter, spamicity=0.117842, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: These abstractions allow you to reference a `struct mm_struct` using both mmgrab and mmget refcounts. This is done using two Rust types: * Mm - represents an mm_struct where you don't know anything about the value of mm_users. * MmWithUser - represents an mm_struct where you know at compile time that mm_users is non-zero. This allows us to encode in the type system whether a method requires that mm_users is non-zero or not. For instance, you can always call `mmget_not_zero` but you can only call `mmap_read_lock` when mm_users is non-zero. The struct is called Mm to keep consistency with the C side. The ability to obtain `current->mm` is added later in this series. The mm module is defined to only exist when CONFIG_MMU is set. This avoids various errors due to missing types and functions when CONFIG_MMU is disabled. More fine-grained cfgs can be considered in the future. See the thread at [1] for more info. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Acked-by: Balbir Singh Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Link: https://lore.kernel.org/all/202503091916.QousmtcY-lkp@intel.com/ Signed-off-by: Alice Ryhl --- rust/helpers/helpers.c | 1 + rust/helpers/mm.c | 39 +++++++++ rust/kernel/lib.rs | 1 + rust/kernel/mm.rs | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+) diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index e1c21eba9b15b672c5e4ab10c4e4c01ed407fae6..48b80bbc0645b2f4abc2b8e28972b0550b5abfea 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -19,6 +19,7 @@ #include "io.c" #include "jump_label.c" #include "kunit.c" +#include "mm.c" #include "mutex.c" #include "page.c" #include "platform.c" diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c new file mode 100644 index 0000000000000000000000000000000000000000..7201747a5d314b2b120b30c0b906715c04ca77a5 --- /dev/null +++ b/rust/helpers/mm.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +void rust_helper_mmgrab(struct mm_struct *mm) +{ + mmgrab(mm); +} + +void rust_helper_mmdrop(struct mm_struct *mm) +{ + mmdrop(mm); +} + +void rust_helper_mmget(struct mm_struct *mm) +{ + mmget(mm); +} + +bool rust_helper_mmget_not_zero(struct mm_struct *mm) +{ + return mmget_not_zero(mm); +} + +void rust_helper_mmap_read_lock(struct mm_struct *mm) +{ + mmap_read_lock(mm); +} + +bool rust_helper_mmap_read_trylock(struct mm_struct *mm) +{ + return mmap_read_trylock(mm); +} + +void rust_helper_mmap_read_unlock(struct mm_struct *mm) +{ + mmap_read_unlock(mm); +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index de07aadd1ff5fe46fd89517e234b97a6590c8e93..42ab6cf4053f2cadff0a512b8645699bfa6ec568 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -61,6 +61,7 @@ pub mod kunit; pub mod list; pub mod miscdevice; +pub mod mm; #[cfg(CONFIG_NET)] pub mod net; pub mod of; diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs new file mode 100644 index 0000000000000000000000000000000000000000..eda7a479cff7e79760bb49eb4bb16209bbfc6147 --- /dev/null +++ b/rust/kernel/mm.rs @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Memory management. +//! +//! This module deals with managing the address space of userspace processes. Each process has an +//! instance of [`Mm`], which keeps track of multiple VMAs (virtual memory areas). Each VMA +//! corresponds to a region of memory that the userspace process can access, and the VMA lets you +//! control what happens when userspace reads or writes to that region of memory. +//! +//! C header: [`include/linux/mm.h`](srctree/include/linux/mm.h) +#![cfg(CONFIG_MMU)] + +use crate::{ + bindings, + types::{ARef, AlwaysRefCounted, NotThreadSafe, Opaque}, +}; +use core::{ops::Deref, ptr::NonNull}; + +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// This represents the address space of a userspace process, so each process has one `Mm` +/// instance. It may hold many VMAs internally. +/// +/// There is a counter called `mm_users` that counts the users of the address space; this includes +/// the userspace process itself, but can also include kernel threads accessing the address space. +/// Once `mm_users` reaches zero, this indicates that the address space can be destroyed. To access +/// the address space, you must prevent `mm_users` from reaching zero while you are accessing it. +/// The [`MmWithUser`] type represents an address space where this is guaranteed, and you can +/// create one using [`mmget_not_zero`]. +/// +/// The `ARef` smart pointer holds an `mmgrab` refcount. Its destructor may sleep. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmgrab`. +/// +/// [`mmget_not_zero`]: Mm::mmget_not_zero +#[repr(transparent)] +pub struct Mm { + mm: Opaque, +} + +// SAFETY: It is safe to call `mmdrop` on another thread than where `mmgrab` was called. +unsafe impl Send for Mm {} +// SAFETY: All methods on `Mm` can be called in parallel from several threads. +unsafe impl Sync for Mm {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for Mm { + #[inline] + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmgrab(self.as_raw()) }; + } + + #[inline] + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmdrop(obj.cast().as_ptr()) }; + } +} + +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// This type is like [`Mm`], but with non-zero `mm_users`. It can only be used when `mm_users` can +/// be proven to be non-zero at compile-time, usually because the relevant code holds an `mmget` +/// refcount. It can be used to access the associated address space. +/// +/// The `ARef` smart pointer holds an `mmget` refcount. Its destructor may sleep. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. +#[repr(transparent)] +pub struct MmWithUser { + mm: Mm, +} + +// SAFETY: It is safe to call `mmput` on another thread than where `mmget` was called. +unsafe impl Send for MmWithUser {} +// SAFETY: All methods on `MmWithUser` can be called in parallel from several threads. +unsafe impl Sync for MmWithUser {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for MmWithUser { + #[inline] + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmget(self.as_raw()) }; + } + + #[inline] + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmput(obj.cast().as_ptr()) }; + } +} + +// Make all `Mm` methods available on `MmWithUser`. +impl Deref for MmWithUser { + type Target = Mm; + + #[inline] + fn deref(&self) -> &Mm { + &self.mm + } +} + +// These methods are safe to call even if `mm_users` is zero. +impl Mm { + /// Returns a raw pointer to the inner `mm_struct`. + #[inline] + pub fn as_raw(&self) -> *mut bindings::mm_struct { + self.mm.get() + } + + /// Obtain a reference from a raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that `ptr` points at an `mm_struct`, and that it is not deallocated + /// during the lifetime 'a. + #[inline] + pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a Mm { + // SAFETY: Caller promises that the pointer is valid for 'a. Layouts are compatible due to + // repr(transparent). + unsafe { &*ptr.cast() } + } + + /// Calls `mmget_not_zero` and returns a handle if it succeeds. + #[inline] + pub fn mmget_not_zero(&self) -> Option> { + // SAFETY: The pointer is valid since self is a reference. + let success = unsafe { bindings::mmget_not_zero(self.as_raw()) }; + + if success { + // SAFETY: We just created an `mmget` refcount. + Some(unsafe { ARef::from_raw(NonNull::new_unchecked(self.as_raw().cast())) }) + } else { + None + } + } +} + +// These methods require `mm_users` to be non-zero. +impl MmWithUser { + /// Obtain a reference from a raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that `ptr` points at an `mm_struct`, and that `mm_users` remains + /// non-zero for the duration of the lifetime 'a. + #[inline] + pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { + // SAFETY: Caller promises that the pointer is valid for 'a. The layout is compatible due + // to repr(transparent). + unsafe { &*ptr.cast() } + } + + /// Lock the mmap read lock. + #[inline] + pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmap_read_lock(self.as_raw()) }; + + // INVARIANT: We just acquired the read lock. + MmapReadGuard { + mm: self, + _nts: NotThreadSafe, + } + } + + /// Try to lock the mmap read lock. + #[inline] + pub fn mmap_read_trylock(&self) -> Option> { + // SAFETY: The pointer is valid since self is a reference. + let success = unsafe { bindings::mmap_read_trylock(self.as_raw()) }; + + if success { + // INVARIANT: We just acquired the read lock. + Some(MmapReadGuard { + mm: self, + _nts: NotThreadSafe, + }) + } else { + None + } + } +} + +/// A guard for the mmap read lock. +/// +/// # Invariants +/// +/// This `MmapReadGuard` guard owns the mmap read lock. +pub struct MmapReadGuard<'a> { + mm: &'a MmWithUser, + // `mmap_read_lock` and `mmap_read_unlock` must be called on the same thread + _nts: NotThreadSafe, +} + +impl Drop for MmapReadGuard<'_> { + #[inline] + fn drop(&mut self) { + // SAFETY: We hold the read lock by the type invariants. + unsafe { bindings::mmap_read_unlock(self.mm.as_raw()) }; + } +} From patchwork Tue Apr 8 09:22:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042481 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 665A0C3600C for ; Tue, 8 Apr 2025 09:24:07 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CC63C6B000A; Tue, 8 Apr 2025 05:24:05 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C77E26B000D; Tue, 8 Apr 2025 05:24:05 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A9FE26B000E; Tue, 8 Apr 2025 05:24:05 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 7E8E86B000A for ; Tue, 8 Apr 2025 05:24:05 -0400 (EDT) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 1976DAC537 for ; Tue, 8 Apr 2025 09:24:06 +0000 (UTC) X-FDA: 83310340092.06.A380D9E Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf07.hostedemail.com (Postfix) with ESMTP id 1CF7740014 for ; Tue, 8 Apr 2025 09:24:03 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=wHwocs6x; spf=pass (imf07.hostedemail.com: domain of 3Muv0ZwkKCCM9KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3Muv0ZwkKCCM9KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104244; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=9QyemcvIui2lVzxcGzSSLvwxhrDIAPa4Re4ibbE0iVw=; b=YKOcGHk+b/luRVDQtH55YT9g3IKcgtfRhIwPq+woJmoPOCCs+89Itp5NAq6qJa6CC5bcda DklHNRCIPJunzAKRtlpN+XIQoZM8CEXD9DHJDoiIWN60kl+EvJBQ9MTda5+SLcAt+3TJME BL5IB9te4PDJoOkBu1LMhPvS++pGWB8= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=wHwocs6x; spf=pass (imf07.hostedemail.com: domain of 3Muv0ZwkKCCM9KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3Muv0ZwkKCCM9KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104244; a=rsa-sha256; cv=none; b=j6JvxDE/exEK8J1F+tdM7nuM5CFq0H/NnmE/sbe9n2eEZ9zT0rdw+DDYizy8nOhVgPkFfK BHyB+auS33AqXeDK1p0GuCbm6j3fXbbSUBuBatP+WFkp++7tsVy6GpnV7/RVevLmNFetqg B+3KyypGtv+FSz3vo7rUHSzNUD1iSzs= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4394c489babso26291395e9.1 for ; Tue, 08 Apr 2025 02:24:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104243; x=1744709043; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9QyemcvIui2lVzxcGzSSLvwxhrDIAPa4Re4ibbE0iVw=; b=wHwocs6xuamrPXY2UxehRnoNkwBaV+PiwShrQ12HwTbIIHH+9jbuSh3QLar8cdn0Ru +lFdo09sWSeGYd84qPnPYYa/bbFyF4z8/fAaCEE9/2kFCu2mYeeI3mGaWC7qqigwpUyN mQcmaebkPQbtUWH2+NtocagcNSFCRPnxj3xhrIe5Hawsgz6KGTAHtxbgTUkaioBZzFPT 9E93sCjh00wdClomm3yc/N/X2cv5UJAg11eqdmwUxDAFRG4hDaJWihQ//eZIDVF9qsrl HlVIAcej+DsglsrI/wYMrlRpDQ2nxoE/ZtBWNr4jl6cgvPQXM9IrdOd8XlHAYhF3ZxDS 6Hng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104243; x=1744709043; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9QyemcvIui2lVzxcGzSSLvwxhrDIAPa4Re4ibbE0iVw=; b=vxec0iXjMts7Iji4AkPzZQt6r+hRTPZ5+f5SfwktnEJyWiehzf7Fb96cFQCAvg+i4Z jRIJzt/VCg2y9UFl2l+rzbUr9YIOASLEZqg1Eslup2b0dV2ILhsvVK5oYgR/vobvjIRQ 5SotZTrcbZ1qdCauecGnoJCoHhi0AMCfOtdSkTQ4cR3CUZbHqhUec+4hnFoAPH0jdGvc mnzWAAmI6qfhfXHvFvR+AXizwdxY1hDz8DZMnjcppz8m7VzBopFoV5WGnujGMH7B5KAl YzApK8o6p16GrPFyrum11u/C/h7xVk1CG6LKyoJW4bI3F0D4gFRZHORZamZiJhccP8qc A4NQ== X-Forwarded-Encrypted: i=1; AJvYcCWC7ZqYPvfuoqhQr7Q4HIksYOoSVVX1BLaP4JTG+O3x5fSbl3l1U/peZv9VGb4nZve1KyzsRYJtmA==@kvack.org X-Gm-Message-State: AOJu0YytRN7JsFmrxZaYV2OHPqmo9hIk3iacTEhLVkAIkh+W6jpKfmFQ pWTXacmA14u2PY6OJIwP4Ueix6s5Tnfoi4AhGaSG3IHRo0pMqpx7G+pUI+5Q0e2HRVd5/KQguvr Hqp+HVhckqtrw1Q== X-Google-Smtp-Source: AGHT+IFxxFUu1qGOXyvkCU5XAz4kFicPKHdX0TfjTmS5tS8Ie5mgbTz+4dEhe4qW9IslRJpSem7hRyy9es0XXr0= X-Received: from wmbh17.prod.google.com ([2002:a05:600c:a111:b0:43d:8f:dd29]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b94:b0:43d:649:4e50 with SMTP id 5b1f17b1804b1-43f0ab8c6d2mr38195215e9.13.1744104242867; Tue, 08 Apr 2025 02:24:02 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:39 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=12083; i=aliceryhl@google.com; h=from:subject:message-id; bh=GtH47wxbR+6d0aNTneO5pMigxZ/fp5PImw8k1ccf9Tg=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OsmVSvhUiA913nl+JAw+MlOHGWc8EvMXmmCp FwIUbqzQCWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrJgAKCRAEWL7uWMY5 RkWHEACjkc6iHWBOlrZetxMPhzthtkwd5NgmH0SN7rYXNpTp64E3opnX715hk0ef5PRZ5Nm/iIb OtkXcUfufrOdrLx+/qYdaVCOz06KYK7WD4uis3zU5B0Ri+aRTVulNIGlXRqepDmR3pYbp8PPF07 0Bu1WvumxR1Xim2M9XHDCOtyAd4G0vry0F+zjHGvWeleJmyha06PKWRZYj2bfpj+dtj7CHk+sE8 vaeAWQ91zCa0KwO8YUxDp2K1aQWMob4/+8GBkmrVq6XlGaWDd0cL6m6xqdcAaDXD9gBZ796xiaa tQyDvkO3tysYm+xTpw6NZ4pGfOIaFQugyjqhWbcLDuEPU7X6F67NZKIqf5ABJmqHcFniTyg8v9a 8uH2eJawIb6+7ZFgtzUdd2jcAmZxI58iVRiO2mzS5DMqX/KaCN+9nyf04fqol4eSsbJUGJDyxkw y387YiEA7VvHmYLbmmL0MqGs/u4koer7PHf2RPIANMWwarx4bceJPj2cB1L/JekMsMd6kC3uDNV i/5sM6BW2h+/uyu8vQMJBdH5xkUx0Rh73TCsADJOR22xGNHWo2v+9JFZU7kB8PwQBJrK3Px5GIc qBcE0dFheejnjo5NRQabW0CDywfmxR0dq969Q79nhVQDdkCNFzCNY4rCQ1YJ0IZvdgzRzXKqXkH cL7GVSoLH/eHi7w== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-2-d8b446e885d9@google.com> Subject: [PATCH v16 2/9] mm: rust: add vm_area_struct methods that require read access From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspamd-Queue-Id: 1CF7740014 X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: woirokc8jjzbrzym36qdy3u8ugwoy944 X-HE-Tag: 1744104243-924243 X-HE-Meta: U2FsdGVkX1860yjDqdduRX8AiYQ8GQoooueX97YIwJtZi/TatTM8nkfMqOoZWK6fzbfHTQRvILhTr5nXJj8mpAtlYhjUFi7sZhDc17js2yG27OA2eVSFiZFzq8bj1K9HtC+YoxtP2+ra9eLpa0HgYPLP5Fr7JsNjJ6NSpdnSM+zkHUK3FgEjxh3cmYgH4MWhFjBfv9/+IsVViYhY1KjuSVw0takRpM/x0uf4KLaqiAj2uZ3t/u0wlcOK8UhgO9ILQIMUbRKc2J1OV2C/gqvP0OeD0G2EMbY1Il8oAalMIMzXpnQeY+Lhty5POSem4toX9Uh9PD+JG1b4UIuwrRaPGkj/lI9CrQdW4vxqDLz8jhlohfInTH6ujEnO5Am+HNakFKemSwToemr99yrjCqqgT89Pl0mDKgxvLHqZWJTSTtQTqJLJqODQ7m3suJQiyKCVIrG98tmsWUNdkMJbMPdjcRVpKavxiQpMVLwShyUIFaDQsBgG2fwQZPRkNfuCimdnCfbMgJ1cyqPwCKTJ3ppl9da1pnu1PyCg0Gd5BTT+FW5ygR2AIq+D4IkCoMpXH2YPfU6VxAsie0SEyYjlLJF+osEgpuXplwgM0bbRP9VqjJgLeNTpVVdF2n9YcIcDxqyZdMIPWWwzO2B91UusWxdzyC9uQS2w6/SyBX2fBvdX/utAX+1MQVgVZyXePXdH21uebX146esDAWxRfdthFaUa+QSQDq2pQlpSjZ7/PoNZ+a2go+pqfep5iaQBn0qE6GbIsmbmN8d/4VS8eBhiUgQs94ymaQsa2yIJgRq9ZjIzPOYD4P4BM7LmYGm8yrZkVc2SA7bX4BebFL3Uk4qinVeegpL7hUeZb+NdEPfB2K19Dc7Y0kUQX/VP+UpBGSdGvheViJFr0bMwxSwVRBfF1HPlaTK49GPDp9VYH/MFdex6vWIxEvS+f0m9/giShAWYlEFQ9q0egd8BjpRHIleWQoS EVylg8qU f9ym4I8WX+m/QfSjwckRkgxbxgzrXaOYfzgvChcTlFQfhQToH1DNaNtkUxCUEiUga/O8JiJlGCXNoiFgYNtbEB+q5W6Fl5MUP/vZ7VloMLKAsZtdwmPk6t1wIiq9AJtjTbWapAde7/oPgQmZDYMHDFV6T+lukL4fUHyQXNteBzM+chXeVXW3ipCIIZedfBJ/1k2fXicP4WuIJC8VudwaDuZMmHoYc27E/R2Z2XRy8wM+LNatumdpKgUynU3tuoxxzaAGdU+yFJrW1GrKFDACk2WxoS0SU/oTysVa7FUprL7B8GAcwcmJPZP2CltLJOA6nq3uQx7sstpCED/8cgOh6QZK/3etx8oWcEX7JJdgYxUIvc2qCMU9NxQAuul6OsZ0T2fd8ZvKMmuEsBY9L3EPL+aein4rF5goW0NmQ50LiOxtiIvSX/cWBXppEHtTdJ+aiZuEA25MQRaqIQMAUlYVag5FZe2hYOEL0r+GFvY5dMIqn8R8KSleDX+7LwICyiE/KJr9M64u9H2MOMXvPzGCg50c2aAwwJSVO8JcIgWdpktUTiw2OTs/rxZt39vaURmpaNn8b1uAVry1cYcCbtwarSeWc+ztwSOHVoBFlhieweH231VPBHD/oNlFl+8FoaxoG/3PzwzRWaht1GP7wVdObRWz9xjYVN9Oy5T5QvLINjtE5UkLi49uZbSH21AYTlhU1HYo/XZ7k30fjDsrLZJF+Wc/0O1UGOX2lJ7oEVHbUZkXsvhLrJ+2hVe5dRNGfOCICPxHDNVSRJXifwuEFG5eduXi7efNwrlpY0ZIF X-Bogosity: Ham, tests=bogofilter, spamicity=0.092493, 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 adds a type called VmaRef which is used when referencing a vma that you have read access to. Here, read access means that you hold either the mmap read lock or the vma read lock (or stronger). Additionally, a vma_lookup method is added to the mmap read guard, which enables you to obtain a &VmaRef in safe Rust code. This patch only provides a way to lock the mmap read lock, but a follow-up patch also provides a way to just lock the vma read lock. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Jann Horn Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/helpers/mm.c | 6 ++ rust/kernel/mm.rs | 23 ++++++ rust/kernel/mm/virt.rs | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+) diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c index 7201747a5d314b2b120b30c0b906715c04ca77a5..7b72eb065a3e1173c920f02a440053cf6e93814e 100644 --- a/rust/helpers/mm.c +++ b/rust/helpers/mm.c @@ -37,3 +37,9 @@ void rust_helper_mmap_read_unlock(struct mm_struct *mm) { mmap_read_unlock(mm); } + +struct vm_area_struct *rust_helper_vma_lookup(struct mm_struct *mm, + unsigned long addr) +{ + return vma_lookup(mm, addr); +} diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index eda7a479cff7e79760bb49eb4bb16209bbfc6147..f1689ccb374078a3141489e487fc32cd97c9c232 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -18,6 +18,8 @@ }; use core::{ops::Deref, ptr::NonNull}; +pub mod virt; + /// A wrapper for the kernel's `struct mm_struct`. /// /// This represents the address space of a userspace process, so each process has one `Mm` @@ -201,6 +203,27 @@ pub struct MmapReadGuard<'a> { _nts: NotThreadSafe, } +impl<'a> MmapReadGuard<'a> { + /// Look up a vma at the given address. + #[inline] + pub fn vma_lookup(&self, vma_addr: usize) -> Option<&virt::VmaRef> { + // SAFETY: By the type invariants we hold the mmap read guard, so we can safely call this + // method. Any value is okay for `vma_addr`. + let vma = unsafe { bindings::vma_lookup(self.mm.as_raw(), vma_addr) }; + + if vma.is_null() { + None + } else { + // SAFETY: We just checked that a vma was found, so the pointer references a valid vma. + // + // Furthermore, the returned vma is still under the protection of the read lock guard + // and can be used while the mmap read lock is still held. That the vma is not used + // after the MmapReadGuard gets dropped is enforced by the borrow-checker. + unsafe { Some(virt::VmaRef::from_raw(vma)) } + } + } +} + impl Drop for MmapReadGuard<'_> { #[inline] fn drop(&mut self) { diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs new file mode 100644 index 0000000000000000000000000000000000000000..a66be649f0b8d3dfae8ce2d18b70cb2b283fb7fe --- /dev/null +++ b/rust/kernel/mm/virt.rs @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Virtual memory. +//! +//! This module deals with managing a single VMA in the address space of a userspace process. Each +//! VMA corresponds to a region of memory that the userspace process can access, and the VMA lets +//! you control what happens when userspace reads or writes to that region of memory. +//! +//! The module has several different Rust types that all correspond to the C type called +//! `vm_area_struct`. The different structs represent what kind of access you have to the VMA, e.g. +//! [`VmaRef`] is used when you hold the mmap or vma read lock. Using the appropriate struct +//! ensures that you can't, for example, accidentally call a function that requires holding the +//! write lock when you only hold the read lock. + +use crate::{bindings, mm::MmWithUser, types::Opaque}; + +/// A wrapper for the kernel's `struct vm_area_struct` with read access. +/// +/// It represents an area of virtual memory. +/// +/// # Invariants +/// +/// The caller must hold the mmap read lock or the vma read lock. +#[repr(transparent)] +pub struct VmaRef { + vma: Opaque, +} + +// Methods you can call when holding the mmap or vma read lock (or stronger). They must be usable +// no matter what the vma flags are. +impl VmaRef { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is valid for the duration of 'a, and that the mmap or vma + /// read lock (or stronger) is held for at least the duration of 'a. + #[inline] + pub unsafe fn from_raw<'a>(vma: *const bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Returns a raw pointer to this area. + #[inline] + pub fn as_ptr(&self) -> *mut bindings::vm_area_struct { + self.vma.get() + } + + /// Access the underlying `mm_struct`. + #[inline] + pub fn mm(&self) -> &MmWithUser { + // SAFETY: By the type invariants, this `vm_area_struct` is valid and we hold the mmap/vma + // read lock or stronger. This implies that the underlying mm has a non-zero value of + // `mm_users`. + unsafe { MmWithUser::from_raw((*self.as_ptr()).vm_mm) } + } + + /// Returns the flags associated with the virtual memory area. + /// + /// The possible flags are a combination of the constants in [`flags`]. + #[inline] + pub fn flags(&self) -> vm_flags_t { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_2.vm_flags } + } + + /// Returns the (inclusive) start address of the virtual memory area. + #[inline] + pub fn start(&self) -> usize { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_start } + } + + /// Returns the (exclusive) end address of the virtual memory area. + #[inline] + pub fn end(&self) -> usize { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_end } + } + + /// Zap pages in the given page range. + /// + /// This clears page table mappings for the range at the leaf level, leaving all other page + /// tables intact, and freeing any memory referenced by the VMA in this range. That is, + /// anonymous memory is completely freed, file-backed memory has its reference count on page + /// cache folio's dropped, any dirty data will still be written back to disk as usual. + /// + /// It may seem odd that we clear at the leaf level, this is however a product of the page + /// table structure used to map physical memory into a virtual address space - each virtual + /// address actually consists of a bitmap of array indices into page tables, which form a + /// hierarchical page table level structure. + /// + /// As a result, each page table level maps a multiple of page table levels below, and thus + /// span ever increasing ranges of pages. At the leaf or PTE level, we map the actual physical + /// memory. + /// + /// It is here where a zap operates, as it the only place we can be certain of clearing without + /// impacting any other virtual mappings. It is an implementation detail as to whether the + /// kernel goes further in freeing unused page tables, but for the purposes of this operation + /// we must only assume that the leaf level is cleared. + #[inline] + pub fn zap_page_range_single(&self, address: usize, size: usize) { + let (end, did_overflow) = address.overflowing_add(size); + if did_overflow || address < self.start() || self.end() < end { + // TODO: call WARN_ONCE once Rust version of it is added + return; + } + + // SAFETY: By the type invariants, the caller has read access to this VMA, which is + // sufficient for this method call. This method has no requirements on the vma flags. The + // address range is checked to be within the vma. + unsafe { + bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) + }; + } +} + +/// The integer type used for vma flags. +#[doc(inline)] +pub use bindings::vm_flags_t; + +/// All possible flags for [`VmaRef`]. +pub mod flags { + use super::vm_flags_t; + use crate::bindings; + + /// No flags are set. + pub const NONE: vm_flags_t = bindings::VM_NONE as _; + + /// Mapping allows reads. + pub const READ: vm_flags_t = bindings::VM_READ as _; + + /// Mapping allows writes. + pub const WRITE: vm_flags_t = bindings::VM_WRITE as _; + + /// Mapping allows execution. + pub const EXEC: vm_flags_t = bindings::VM_EXEC as _; + + /// Mapping is shared. + pub const SHARED: vm_flags_t = bindings::VM_SHARED as _; + + /// Mapping may be updated to allow reads. + pub const MAYREAD: vm_flags_t = bindings::VM_MAYREAD as _; + + /// Mapping may be updated to allow writes. + pub const MAYWRITE: vm_flags_t = bindings::VM_MAYWRITE as _; + + /// Mapping may be updated to allow execution. + pub const MAYEXEC: vm_flags_t = bindings::VM_MAYEXEC as _; + + /// Mapping may be updated to be shared. + pub const MAYSHARE: vm_flags_t = bindings::VM_MAYSHARE as _; + + /// Page-ranges managed without `struct page`, just pure PFN. + pub const PFNMAP: vm_flags_t = bindings::VM_PFNMAP as _; + + /// Memory mapped I/O or similar. + pub const IO: vm_flags_t = bindings::VM_IO as _; + + /// Do not copy this vma on fork. + pub const DONTCOPY: vm_flags_t = bindings::VM_DONTCOPY as _; + + /// Cannot expand with mremap(). + pub const DONTEXPAND: vm_flags_t = bindings::VM_DONTEXPAND as _; + + /// Lock the pages covered when they are faulted in. + pub const LOCKONFAULT: vm_flags_t = bindings::VM_LOCKONFAULT as _; + + /// Is a VM accounted object. + pub const ACCOUNT: vm_flags_t = bindings::VM_ACCOUNT as _; + + /// Should the VM suppress accounting. + pub const NORESERVE: vm_flags_t = bindings::VM_NORESERVE as _; + + /// Huge TLB Page VM. + pub const HUGETLB: vm_flags_t = bindings::VM_HUGETLB as _; + + /// Synchronous page faults. (DAX-specific) + pub const SYNC: vm_flags_t = bindings::VM_SYNC as _; + + /// Architecture-specific flag. + pub const ARCH_1: vm_flags_t = bindings::VM_ARCH_1 as _; + + /// Wipe VMA contents in child on fork. + pub const WIPEONFORK: vm_flags_t = bindings::VM_WIPEONFORK as _; + + /// Do not include in the core dump. + pub const DONTDUMP: vm_flags_t = bindings::VM_DONTDUMP as _; + + /// Not soft dirty clean area. + pub const SOFTDIRTY: vm_flags_t = bindings::VM_SOFTDIRTY as _; + + /// Can contain `struct page` and pure PFN pages. + pub const MIXEDMAP: vm_flags_t = bindings::VM_MIXEDMAP as _; + + /// MADV_HUGEPAGE marked this vma. + pub const HUGEPAGE: vm_flags_t = bindings::VM_HUGEPAGE as _; + + /// MADV_NOHUGEPAGE marked this vma. + pub const NOHUGEPAGE: vm_flags_t = bindings::VM_NOHUGEPAGE as _; + + /// KSM may merge identical pages. + pub const MERGEABLE: vm_flags_t = bindings::VM_MERGEABLE as _; +} From patchwork Tue Apr 8 09:22:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042482 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 F2531C369A4 for ; Tue, 8 Apr 2025 09:24:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BE9CF6B000E; Tue, 8 Apr 2025 05:24:07 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id AFB1E6B0010; Tue, 8 Apr 2025 05:24:07 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8A7106B0011; Tue, 8 Apr 2025 05:24:07 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 5A48B6B000E for ; Tue, 8 Apr 2025 05:24:07 -0400 (EDT) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 1E853160989 for ; Tue, 8 Apr 2025 09:24:08 +0000 (UTC) X-FDA: 83310340176.29.AA0D480 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf15.hostedemail.com (Postfix) with ESMTP id 596AAA000C for ; Tue, 8 Apr 2025 09:24:06 +0000 (UTC) Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="RZ/784Ri"; spf=pass (imf15.hostedemail.com: domain of 3NOv0ZwkKCCUBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3NOv0ZwkKCCUBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104246; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=s5w8I1p3Tb9DO8JsnIo9VM8qLIkaDI8pOQrbVUWT6uI=; b=UZiqoufvAksLWbe5JxxsaZ/RVa3CC4/vKoO716n86WXDLrJCC8UAUi7haOg8kMYQIDJuoj GxDHd25C31tJr12KYYqurxK1UJprd+QbD2C+4Vwvm0xaORXtED1LYFrs8ooZxL7ZYC04rk Fj+zSbeDHHnU+3Eqo2+3bIj+j8gAtwk= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104246; a=rsa-sha256; cv=none; b=TQTUJbP8AWI/aDdWUxZLfRe8+2ldsNp3x7wyju7laq4ncxW1X4kbmEQw6lC+Y3RF4QM87Y c56jho2awwqt+ZLySCLia9hLEP55Xb17OUeJM7XlDsJA+7OL2hQD08ZLS3oN96ENzyycpN gMVcrJE1GTZu/QdyxI7Z8MK3p1D7jQc= ARC-Authentication-Results: i=1; imf15.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="RZ/784Ri"; spf=pass (imf15.hostedemail.com: domain of 3NOv0ZwkKCCUBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3NOv0ZwkKCCUBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43ceeaf1524so29979925e9.1 for ; Tue, 08 Apr 2025 02:24:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104245; x=1744709045; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=s5w8I1p3Tb9DO8JsnIo9VM8qLIkaDI8pOQrbVUWT6uI=; b=RZ/784RiAFbxf9D2Avq42ekRWLuLlGJcsEYqudS9w6D80akSJLfeKQrEp2dzlN063t CTR+gKrUOL85TzZmoHP0fGGzPGp3i70edhsnZuDd0BafYtiQ6NLPlbrHWu42uTSM8ljT jnp69FCS8WGCHxAFD1wdDNxslMB+uxC66zyu2ZdOMqW/Td7PlBrW/x0Od0PksipGvMg+ 4/UB0CMCbc+wc2wd7FB7H/XUCUFBoxqU9byPpR2HEFfxQmtKcdBuvpizHdYSvOlDF46b xoIblpU94ZjM2ZnyDFPimtHMrExYzZwnC09qTCAZDicGMrV32hzhoML07PCr0hZkXirr dP7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104245; x=1744709045; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=s5w8I1p3Tb9DO8JsnIo9VM8qLIkaDI8pOQrbVUWT6uI=; b=oNGf4pYgiTJ64FrARWD/ksv1QTsddV+6bwhFqexIGnsYp5wbsqN74uAFhrN3qTCHED 69sAjzt2APrkFK6MbpPHKhhaqLrom01YpQzpiT06y29vH+7j58Y11Nqrfss99fc06q9h SCcsRGcD+q2rT6RjcjgnNstyN6U6p/WkMUSBNxaotG4rQlnVXVfke1n5qBm9yA3EV6lU uWH9211GcD00VExv/yzU+EWc0qHW8wpOIsFdPX4TG1Ytqi8sO7nxu8ORV9qz7VqWhG1R yRNztdz/ZnGcsZrIF0bP/q9tP9HF4rV7JU4HZFmdoaZGdSiIFhaew4B+Bb4jNdm78Kgi NErA== X-Forwarded-Encrypted: i=1; AJvYcCWnIFvxFtvxXgTsCUICcWMfgTZp1J7F/xTWT+zYE7Yyl2brPgmtzqL+j/+8P9U7lr3hp2ZN+wEgWQ==@kvack.org X-Gm-Message-State: AOJu0YyYvkoYFFhXqfXdU8Ye03BrzqqYiyRUqdxh9f8aXLtAub0NoqRS Lo8k5DZSw2iPu4LHh4m8Se5d9+7ZhKjWtBiWv9V60uH5j7416WwgOr5Q3JywElXLIQuziQkde4T tzYrKWkZuBW6JzQ== X-Google-Smtp-Source: AGHT+IHpYdwjp62GC42TgJRjq1KuRmzOAAEOqv7lAljye6ysUkygRaxUq/uM+rb+EggvJF0qu6sb2cFi0FK4uNE= X-Received: from wmbh6.prod.google.com ([2002:a05:600c:a106:b0:43c:eb09:3790]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:5845:b0:439:4c1e:d810 with SMTP id 5b1f17b1804b1-43f0e59c566mr15047995e9.9.1744104244985; Tue, 08 Apr 2025 02:24:04 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:40 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=4393; i=aliceryhl@google.com; h=from:subject:message-id; bh=6cK8H0f1bjkfbBZECW+oXwSFALiwF8hLaYj708yZ9Vs=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OsnO6hmFHtTeBdUk9KFgbrB2QrDLVOl+CpTX d6JGe8HUuKJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrJwAKCRAEWL7uWMY5 RldLEACSoWh10crAZ99JPh2xNve1MWXfeXmmLSD1NzqPq91mZuyNyd7KxvS8MCgtkDxjI4lf/EK yl3m+I12OBvL54nMiHw6/jwjv8z/14XNQeRQx0aDtU2N66XpXG1O+tQ3Ow12J7cTrqmQaPNRBry lEjdcqaKJCly/EPPyJjRdLHd42EKtbyJN/OCoXQu1p/a/GvwLVbOVhGRTzC/i9XHCIzn0Tl5G2F kIAi6g93MU6TMnO3GGvKqDdS5exJQllY+P5pd9MxDU/4O/mMoxbfVxHtIbw3zavFNbI7ifI2w+g hc65G3O7tEkNtCwmy19QiNF/BkS/dnDnqKgco1rsL1enCAJSxUK87DZHaQ4cfvO08iABgGfa8tA fEQFM0ry4n1mDKBHHr34ICS9Tmrrj+zqh8ydMudFmwBYAVGu4A6YDBYs3whhMDeDxFT5gOb6IwW fTcdaAwIvwLNDqd/5iXGY8t/zcdrngDyChZB6VbZCwln/MEEyh1mhh0sCKs3oVO+ixfj4JrBG8E E3NaAjrWqbNzifbv+AII4tSHJFmW3ExuWdgRDNxSkrBhGFPjNDw4/VRsFlMnXVUUjhZsEpDjyjJ CO4gGUAFnizx/292hDoxB8xe9gzUaUycfj4uGObs+4NHG6wkZiS4K7YrktZkNEw7AcV0CdW5Yip h29xzmoJxJ6uJMg== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-3-d8b446e885d9@google.com> Subject: [PATCH v16 3/9] mm: rust: add vm_insert_page From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspam-User: X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 596AAA000C X-Stat-Signature: acngupkoyrguisms6yf51swx6cy35ipi X-HE-Tag: 1744104246-598346 X-HE-Meta: U2FsdGVkX18SnqHIngzvkc2fq0hJ8Xa2ldFANcmj7tC7Doxc4nfrHv884FvlB2zzwMri8jrw85TFhcTPJNUv6cuGpvjLfqUTn8NhGrvgMByiy+cobIW54BwkD2U5a8h12wSbwWMjJYANie8Yry7OmGAADJeeB/4DmpNZwZYwArMs6Ts5wmeHTmCwIvmxvyqwJYHXikFe0KAPvTnjON26Vhf7XreZFDtUZvVYYO062PwDkD+bLfI5VgKkedFY1N1SMe/f3NXpUXpulKgIMbRKGNthRT6UIftPEQHy2yfG9GMVvWXvWHmo4u4Swj6TVAz2LDTMXiwFfiKnqiOmfzrN+5w5sohLGOnOyT50FI7ALSZKI8D6iC2vYwEXv8PgJW5GUbH+d4idAT0oj+4/BdEJHnltETcEysil5kGtFZ685IqxSNTROTeLH93NN17cAZ+ujFlGDlV/f8Nm2re5fXjkDK7YPaiAM1AN9AnkTMANpYDS7D9S+R47znG3m0aSWCRgVw3wJbkEw1DqXt6gt+Jo7JEOj4TJqV03wavwnmEdRQVXdK77Ydh7xgb8jm7j6kloGjS2IhGgpiUthgR6jVtLuf5j7UQbOUOj3mGIL5qlbrwKr42O6gRuFa7OzflDTWGX2873YeuU1dxjuIfBUhW4jO5S3QL8pfWDv08L6+N7HEOqa9DmmO7TBU9RI0lX0TKtyRO0ucsJemxk2KjZeH5c2vcZPg7FSbISy0UKMzHDgr1MmIpEf8za/KoC8179si8agZ9Txd+owvjAvcLkZqxwkmVG+R7tcWUzqlkj1lWSf6I66h4RLzDr0dKudnGbEvKGjkpXV98RptVYYDtK0Qsoqehj+Pwz5znF5fWEufyRT1rAKh8k8PJwzYlglxCuTlfJ6enc5uZKGkJIRG/orT+9KApDvUwcuUY3gHkUN5310i8FXQMUaqNuDq8C6e+tByh9VmTOAb5bj8GUmcHrqnc rDqfF7I3 gRF4cHqGSnx5WSYojfRuQoyOZcPIRF41ZsZwtu1nzRnHFekenTfPIZN9g8PBKnNX4gghjvDiJmSx2LUD6ceyrOcgpshpF7azJ9vjxHcL5aWYasr3hI+rCkiJ0gkxFlvciorInCzTWQBIyXurBGtDlRd4mJW1Rh9D+6ohZVZ68kvVcXl4G9VsPKSPCXMt5hOqzVJXup3kIkHULMgaUR2lkFOsgMcsaa85jbzyy51habruTPr3Gs23ZSOo/rNlrpF6Ac5LtenMCqZSC5lpL2fuEq+vjyRACBWY2f3T3BrhFxABj2mtUL/RnndHpbGWoVLwtKD0uXDbktVKo42L7neqx9K2dRM+leUyu2BsRznp8DejkN09IuHaQFyQI1XOYjOuG0qIQr/a86wPyv1PJ/YFVMBn6Bg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.414524, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The vm_insert_page method is only usable on vmas with the VM_MIXEDMAP flag, so we introduce a new type to keep track of such vmas. The approach used in this patch assumes that we will not need to encode many flag combinations in the type. I don't think we need to encode more than VM_MIXEDMAP and VM_PFNMAP as things are now. However, if that becomes necessary, using generic parameters in a single type would scale better as the number of flags increases. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/kernel/mm/virt.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index a66be649f0b8d3dfae8ce2d18b70cb2b283fb7fe..3e2eabcc21450497a02ffa1ed1f31f3e7e7e1b6b 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -14,7 +14,15 @@ //! ensures that you can't, for example, accidentally call a function that requires holding the //! write lock when you only hold the read lock. -use crate::{bindings, mm::MmWithUser, types::Opaque}; +use crate::{ + bindings, + error::{to_result, Result}, + mm::MmWithUser, + page::Page, + types::Opaque, +}; + +use core::ops::Deref; /// A wrapper for the kernel's `struct vm_area_struct` with read access. /// @@ -119,6 +127,75 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) }; } + + /// If the [`VM_MIXEDMAP`] flag is set, returns a [`VmaMixedMap`] to this VMA, otherwise + /// returns `None`. + /// + /// This can be used to access methods that require [`VM_MIXEDMAP`] to be set. + /// + /// [`VM_MIXEDMAP`]: flags::MIXEDMAP + #[inline] + pub fn as_mixedmap_vma(&self) -> Option<&VmaMixedMap> { + if self.flags() & flags::MIXEDMAP != 0 { + // SAFETY: We just checked that `VM_MIXEDMAP` is set. All other requirements are + // satisfied by the type invariants of `VmaRef`. + Some(unsafe { VmaMixedMap::from_raw(self.as_ptr()) }) + } else { + None + } + } +} + +/// A wrapper for the kernel's `struct vm_area_struct` with read access and [`VM_MIXEDMAP`] set. +/// +/// It represents an area of virtual memory. +/// +/// This struct is identical to [`VmaRef`] except that it must only be used when the +/// [`VM_MIXEDMAP`] flag is set on the vma. +/// +/// # Invariants +/// +/// The caller must hold the mmap read lock or the vma read lock. The `VM_MIXEDMAP` flag must be +/// set. +/// +/// [`VM_MIXEDMAP`]: flags::MIXEDMAP +#[repr(transparent)] +pub struct VmaMixedMap { + vma: VmaRef, +} + +// Make all `VmaRef` methods available on `VmaMixedMap`. +impl Deref for VmaMixedMap { + type Target = VmaRef; + + #[inline] + fn deref(&self) -> &VmaRef { + &self.vma + } +} + +impl VmaMixedMap { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is valid for the duration of 'a, and that the mmap read lock + /// (or stronger) is held for at least the duration of 'a. The `VM_MIXEDMAP` flag must be set. + #[inline] + pub unsafe fn from_raw<'a>(vma: *const bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Maps a single page at the given address within the virtual memory area. + /// + /// This operation does not take ownership of the page. + #[inline] + pub fn vm_insert_page(&self, address: usize, page: &Page) -> Result { + // SAFETY: By the type invariant of `Self` caller has read access and has verified that + // `VM_MIXEDMAP` is set. By invariant on `Page` the page has order 0. + to_result(unsafe { bindings::vm_insert_page(self.as_ptr(), address, page.as_ptr()) }) + } } /// The integer type used for vma flags. From patchwork Tue Apr 8 09:22:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042483 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 6A220C369A1 for ; Tue, 8 Apr 2025 09:24:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BBEE26B0010; Tue, 8 Apr 2025 05:24:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B4A636B0011; Tue, 8 Apr 2025 05:24:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 94BAB6B0012; Tue, 8 Apr 2025 05:24:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 740ED6B0010 for ; Tue, 8 Apr 2025 05:24:09 -0400 (EDT) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 404B21408E7 for ; Tue, 8 Apr 2025 09:24:10 +0000 (UTC) X-FDA: 83310340260.04.70B74BC Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf08.hostedemail.com (Postfix) with ESMTP id 4B045160009 for ; Tue, 8 Apr 2025 09:24:08 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=guU8JrnC; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 3N-v0ZwkKCCgEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3N-v0ZwkKCCgEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104248; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=fSV463Hzq4lcGHaBMKwzfTcjqbOdgyFN9gtovsbYOqc=; b=Vxn95RQsNcD8s6FOULzgKsHlFWvm5ZYVGwwUAbb4RRp1ubpKZh6Doc7itjNZd/wl8++1Hj +Gs2k+ztYVkYLwatf0hNmjRtQmmaQRzd2YdKAfJkQiBOv+x0ac7KXWTISV/Bo1zgX0rMOz fZ1ZnUZ0RD1kGKyhIUGUaqx9UFWfK3M= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=guU8JrnC; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 3N-v0ZwkKCCgEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3N-v0ZwkKCCgEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104248; a=rsa-sha256; cv=none; b=JkP8NX1XWIi9zG/wLZBw1PS1TcjvrsJ/ZZnIZsTF3Soi6Z2n1FLP6GqE0in0qlJH4tC09r GvTlZDTeHcrWUn71k+iKElNcBrXngi0jlr5bjuwBiMhM2KZC2ZOv/MdOEsHdNJaoxe9Mo3 fjYDAcGfjB0pzqNkbqzyi+UrFJ+BjqU= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d51bd9b45so36714325e9.1 for ; Tue, 08 Apr 2025 02:24:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104247; x=1744709047; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=fSV463Hzq4lcGHaBMKwzfTcjqbOdgyFN9gtovsbYOqc=; b=guU8JrnCbKc2OuhW4iKL1wdLIkq/hWtsFg7F0NsIm+Vo4fa63kXUzq+Op5fruMred7 FL5FCLnwQR43OF/h5kKkbGPCJFkeNlXmJbTIx+blklR0bNI5B9rjLbSuVczGkB8HPqkj vSpRDbkk1BOofiN/DxoizLNr9pDDUsmnCt1HcotoLBJE3iOHFAZQQ8SSMtWXdYGN91ZJ BymCLhXH7Bub6cY0QvQ2wqFJchmqf0xKSCO2KuKqawA1ZKEFh/HRuE77DimZQ8IxcnAY A5qOqPsGlTzJZZLT+bSObT2jYx+921HkMIqyTinzJGdBN4Jrfok6gYwQa0YHzm34s1OZ 2vVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104247; x=1744709047; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fSV463Hzq4lcGHaBMKwzfTcjqbOdgyFN9gtovsbYOqc=; b=BNAC3ffvm7U7XLUW0o9jdFdbWAXjmocRFGMFeK2oTqueVSfCe1VTNL+AdeSyawS9eg ew0zWr3Jdyui0X+nGaC5ZiXKvlny1nLMAaIf5Ms9xetHEIQ9pzBmLL0zwugMeF0TvNKt SLLg8oceVQ9CPUF7yj5It2J+AGZuZsEcs6sFtUAY8mOBO+fQak+ET9ffIr2rLiCmonZU BbKt6bGizaxL2prk4JCZFp/lQtxnnMejG/mYC75mvY8SQPtmeneK3EUH4W6wnTynmhxr u2ANc7ipdkwffmVgJn6SigQjLfsmaRk3YdBr5PT26BKw51sqXGiDrjqeEMu9fT9IU0go 2tow== X-Forwarded-Encrypted: i=1; AJvYcCW7XicbHGMUP1g5uZJr5RVKc4YO+UpKVsH6Sh8B8GjZj69eQoEnTZl3OKf+dNOWwl5usGSEqAumnQ==@kvack.org X-Gm-Message-State: AOJu0YxryZ1UWj3IFLWAmmhqcadtcTPXq0oI8zNM/wnNScC9b/MxX+2K 7E55YeZJXy/Oy8b3SU9CpQCzSoTHPMva6yKMjegLeWXR3CMutUcwJTIteF5c2N3ug4AJekb1ayn KEc6/3LPGN2W+ig== X-Google-Smtp-Source: AGHT+IGpYx8GY+CcPqdjvQeTUdadbSh+V6DOVo+9tIk10BZYKUulfM4YzPVOn2JdHxlRFKSX0lPoXYX9f1ZU4sI= X-Received: from wmbgx9.prod.google.com ([2002:a05:600c:8589:b0:43d:5264:3cf8]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1f07:b0:43c:f8fc:f687 with SMTP id 5b1f17b1804b1-43ecfa04a8emr120987995e9.27.1744104247078; Tue, 08 Apr 2025 02:24:07 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:41 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=4299; i=aliceryhl@google.com; h=from:subject:message-id; bh=gF1ckMqCWHCjQXFknkNdHEiUzDYS1Ku+dCA1Sq6IckY=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9Osn3jxbpIs+xoCWpCoObHsxRS9D60krCSnYT liiyaW/aLiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrJwAKCRAEWL7uWMY5 RoLCEACYidsumhaA9miV4nPn5brjSwUFAg1VPkCXuULdVYpR98jJerXgW0o+C/JgnKudQsmOGPJ B7MEnQur02LcSgPW71ukNXp86bWc9dSnuMZIJRiK/wCi4UEJeVVaxOUu+id75fPxyCMPS+TzNWQ QuuKW3KOwpcwFr3fW601D3P4jKIJnca7mC8wuMxunrbFpz5pkVJ/bLGhrasFOUH70F1VjBussqq ZvnZWyn9z0Ij1HBgqvzUwNNtUVq27ul92aCNCiSMf7GTLqNV9EM6W1fIKAOC4s9bA9/usTrp02V T5BEZ5zGhMzQ1uOoAUgyH1229eWh5Un0A65JrF0XHe2ZJKS2Gsbv6iVSX5CCL4m+BtcRszMLJ5z wndBdwWT2DDDJyyshSoi3FOe9bfUFnCdoZ5cNTQxrD+Rz32PN9kJ5qiPBsQp+jS2HcqTFZ/mCKe xIpYVQcyhcnRstMU/N81m1h8c/SYGx2U46nPiQXpN3Pqb4wrIDQQpMxwsnh9ON7ewaaoYEI8/2C VBeETIom53ABUiJaI7b5R/ysuayAGNljta5PvwhvI94/KVaxcg5Ys2grjswEly5jp8O/36vVuE1 LstY/UxTleVJNGEycPlzy9gTvstP2u79n1tNOhKrVQ7IKwH84lR60sVjU1jArF8+cp9zjjBb4FL LkKtiYSl9CTjJ7w== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-4-d8b446e885d9@google.com> Subject: [PATCH v16 4/9] mm: rust: add lock_vma_under_rcu From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspamd-Server: rspam01 X-Stat-Signature: xi15wwydwww5gan85m1nznq4o1ariwb8 X-Rspam-User: X-Rspamd-Queue-Id: 4B045160009 X-HE-Tag: 1744104248-424702 X-HE-Meta: U2FsdGVkX1/eNvHTXnntVYIzKNkpOpRNtexyXpjOY5bsAlUHjBOOXwwiuckUk48T9rzDs2hJnoi986/l5gIWBIqkym3N6iuAdXpIRIPa36nQu9VR/U7DlCBwWOrP6zG6SYwOPtAUssFL8tuiP4T7No46bdZFk5YkIxbyGfcjNATQynlcKceN9fPkeCnMPdwNlZteRsE8w5cpQkUv1AJvDaS38PyTAWd2PlphVKnlGSxgnBIOzIxieqZclD5n8KEMsQKzLEUlKp16UD9lhu0kTerVrSPE2t9cUfGh+2RIM8wQJ35ooHU3Vo4wKUfQ8rQ8/jD5ex73koi+cVcKT8AwrL/M6tg5gum/V39Q6DxPU+oTuxdWDoRLj9fRiV5/6nmXrptUDaOUfl7Gig7MT06c4qY/fej9u83KhgtWaVBrs0XLhThwBrP3yAd1qAd26EcYoBXMwRkpG2M7nFtYVOYoe+Wn79flWoeVG70a4uVtxIrVHOGUxofVEEA7AlI6D3q5C5f/r1banUK7EtT+7Ntk44M2GRd5spSMbKKUHxIAs6rNt5dqch0yTXhjopRA7POBLTa/AVqLcQvnHsp7YwhHELB5Q8cue//W1MMnABbwltWVTeaD+B9QMpRkrBYl2iB1PbjEmmHxepGp/5dB8WnXaEu/Cn+5yBoZO4GwiHLPeEKWKHbPeny+DsIDWIC7wPuLBV5RZQ1nZ9jQj1E4L9Lr+jl1HL+G2hQQ9m1rVGKNny1upJW4pMPlQWVoUEZqw5kz3yJJMCyCnwMd39F09m51uL+P1YChcBzI6qW2hTjVeGgRovWP4+kemdqAKVP+BhKE2CFCIuKASzvt03qRzWyZWEd3P/ty7G3zF7ro/XYcaA8ktrT33Of5f9b3XhhcdDCqWlxmYRoqqkzACqNOmGFU6V98tZvxY/c3/35ciNw6rWiBd8WqzYellKWENM38ecqzQTGnzEhxSJmdrRaIZXg tgPLd81X BJ5MFJ2xKDP7UvYGJHi8AJddfjIbzhUtXL4b5EZEDBzNvg//F2S9nwHOzSK6gKb5bhid2qi6krOOJN9NwyMlR/V3ZReejU+IgwSaX8hO0d47CF4Fh/v+uFMrVNIvVzcRGV2yP12hL+TQkkkEkpeUIKe+KNfuh38dJeEi3BuY1QlYjUEpMwS+G/AcVZmKSprrAzSAN4NCt17oon7GOrtg93o8pIaFahXPtEVkfeSq0JPVkZQvH+5HS/KxvrpYbqHJxNU0vIAm4G8KzToqlMgbsdTA56pEVIip+qiwjWCnRVymwQQ43IpVxLSjm6xG+1MU3+KGsGtT4MpNDBh74zzPVME93xYE2Vs3R+TORT/EVIAWPW9s77SH1p83ib+hg/gYH4FfZ0AbMl6f3ghl/a0Vsw3AN90G63MCfhHsYjbM90k1E19PwLmnAj13qw25LQ/SACs8ngAy0ZOfpE5cnHNEbcVYmvqOai6CJsi+r3C+0PvstZKCUIYjSpPQ+mwE6UvtZfb9MgQ+QnDZ2FBBJPOCFgPz4i3RdPxfBDvfxfrfivntXP46L5BfzOWlGW0Oc+SLdIgj2t09XRgvUy6GgFvdvBD+KS2Ljfu4mj+0HZAtbeMZs+qesxYVMWgpHFZEQ2nKxIWe+KmBUnH4TDvuCvidxkrIacgydboaf39HJieET/kNC36K36KMbqaf+AgVNE6Sm55oeAUEKc5NjhlVg5oWrWb4IpIeLB2vZNu0PfHtWRGmX/Ys709l+O39Nb+99Yix6yb4pPKPSt+bI+1uyA/M84lyatE/MhzwYhHX5 X-Bogosity: Ham, tests=bogofilter, spamicity=0.393526, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Currently, the binder driver always uses the mmap lock to make changes to its vma. Because the mmap lock is global to the process, this can involve significant contention. However, the kernel has a feature called per-vma locks, which can significantly reduce contention. For example, you can take a vma lock in parallel with an mmap write lock. This is important because contention on the mmap lock has been a long-term recurring challenge for the Binder driver. This patch introduces support for using `lock_vma_under_rcu` from Rust. The Rust Binder driver will be able to use this to reduce contention on the mmap lock. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Jann Horn Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/helpers/mm.c | 5 +++++ rust/kernel/mm.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c index 7b72eb065a3e1173c920f02a440053cf6e93814e..81b510c96fd2692dcb7ab4705f790bd3a41a630e 100644 --- a/rust/helpers/mm.c +++ b/rust/helpers/mm.c @@ -43,3 +43,8 @@ struct vm_area_struct *rust_helper_vma_lookup(struct mm_struct *mm, { return vma_lookup(mm, addr); } + +void rust_helper_vma_end_read(struct vm_area_struct *vma) +{ + vma_end_read(vma); +} diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index f1689ccb374078a3141489e487fc32cd97c9c232..c160fb52603f8d4b349000451e2200fb477d98a6 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -19,6 +19,7 @@ use core::{ops::Deref, ptr::NonNull}; pub mod virt; +use virt::VmaRef; /// A wrapper for the kernel's `struct mm_struct`. /// @@ -161,6 +162,36 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { unsafe { &*ptr.cast() } } + /// Attempt to access a vma using the vma read lock. + /// + /// This is an optimistic trylock operation, so it may fail if there is contention. In that + /// case, you should fall back to taking the mmap read lock. + /// + /// When per-vma locks are disabled, this always returns `None`. + #[inline] + pub fn lock_vma_under_rcu(&self, vma_addr: usize) -> Option> { + #[cfg(CONFIG_PER_VMA_LOCK)] + { + // SAFETY: Calling `bindings::lock_vma_under_rcu` is always okay given an mm where + // `mm_users` is non-zero. + let vma = unsafe { bindings::lock_vma_under_rcu(self.as_raw(), vma_addr) }; + if !vma.is_null() { + return Some(VmaReadGuard { + // SAFETY: If `lock_vma_under_rcu` returns a non-null ptr, then it points at a + // valid vma. The vma is stable for as long as the vma read lock is held. + vma: unsafe { VmaRef::from_raw(vma) }, + _nts: NotThreadSafe, + }); + } + } + + // Silence warnings about unused variables. + #[cfg(not(CONFIG_PER_VMA_LOCK))] + let _ = vma_addr; + + None + } + /// Lock the mmap read lock. #[inline] pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> { @@ -231,3 +262,32 @@ fn drop(&mut self) { unsafe { bindings::mmap_read_unlock(self.mm.as_raw()) }; } } + +/// A guard for the vma read lock. +/// +/// # Invariants +/// +/// This `VmaReadGuard` guard owns the vma read lock. +pub struct VmaReadGuard<'a> { + vma: &'a VmaRef, + // `vma_end_read` must be called on the same thread as where the lock was taken + _nts: NotThreadSafe, +} + +// Make all `VmaRef` methods available on `VmaReadGuard`. +impl Deref for VmaReadGuard<'_> { + type Target = VmaRef; + + #[inline] + fn deref(&self) -> &VmaRef { + self.vma + } +} + +impl Drop for VmaReadGuard<'_> { + #[inline] + fn drop(&mut self) { + // SAFETY: We hold the read lock by the type invariants. + unsafe { bindings::vma_end_read(self.vma.as_ptr()) }; + } +} From patchwork Tue Apr 8 09:22:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042484 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 D6490C3600C for ; Tue, 8 Apr 2025 09:24:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A45DD6B0011; Tue, 8 Apr 2025 05:24:11 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9C5EE6B0022; Tue, 8 Apr 2025 05:24:11 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7CC6B6B0023; Tue, 8 Apr 2025 05:24:11 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 520FF6B0011 for ; Tue, 8 Apr 2025 05:24:11 -0400 (EDT) Received: from smtpin18.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 1A9371209D7 for ; Tue, 8 Apr 2025 09:24:12 +0000 (UTC) X-FDA: 83310340344.18.E0525D5 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf08.hostedemail.com (Postfix) with ESMTP id 5D198160007 for ; Tue, 8 Apr 2025 09:24:10 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=U2adQ5Tc; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 3Oev0ZwkKCCoGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3Oev0ZwkKCCoGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104250; a=rsa-sha256; cv=none; b=hmdMpnwxELh6w6WprOqHs2hQjjINX4rH1bB1cr/8Fnz0ayBRtJux8zAt8K+khXOLavWpik cy4AP4wsQaWnSJVKvDyhSgzHdNKXNnx/WgFCa1DN6pAG2s2WI8Q263L6Dn3DvLQyIGfzl/ DSgRVJ/y15+PHZ86fl+IP+yCWYVrObw= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=U2adQ5Tc; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf08.hostedemail.com: domain of 3Oev0ZwkKCCoGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3Oev0ZwkKCCoGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104250; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=bACckoQSwDfUzBFoYMbXvpmJP89UDR/iGZngv5w49FI=; b=0wg+joD6qXPV9FdaNkCJFuFMm+BXU0wT/zysENjnSJdOl47Hkn27FOsscZ2iL9m5v66iuJ Qgoa3t1LGzmZf8vNDVWXBZGx4xR2UY+QuFkj3qJ621KizQoRGzgZ6z984GYPwGiwnHMH/W y6pm8QdjjcrP0pffHdI340QZcxhD8FE= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cf172ffe1so44215385e9.3 for ; Tue, 08 Apr 2025 02:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104249; x=1744709049; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=bACckoQSwDfUzBFoYMbXvpmJP89UDR/iGZngv5w49FI=; b=U2adQ5TcGT0pSPLFxfhkjaPesXhv2F+n9264GquHtYNDKrvwXW7E2P/rKb+Qa6PLFE nICPQvSp94ZL/pZ95eUBQktQLf7egV7W4vBieDgfK+taB1nYXKbnsD7Mh+7LZ82vU4E3 NUE7J3bHR1qGbXBDoF01GPI4/sKGM4p+K7KGaSg8XM9kvlnZvgAFQ77X8cUXFOsTxhp9 XfC7QyWnqiAZsZBcReXCNKYikCdiMZKY+IKV/h9KGo6J7ubwxt3/G6K7hBYU1r6Xv8r/ S+bYj16b/rKxVPRTa7kY+R6nIAVc2qyumIsGggBIRrOT6/hPNRrxauUVHFy2YY0XwC8k 2BNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104249; x=1744709049; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bACckoQSwDfUzBFoYMbXvpmJP89UDR/iGZngv5w49FI=; b=QhsEqa8HYpSO3brx0z+H79vqEHWIwkMuDs2HiQnbFOOUXywI8mpnwQvfqPKOW4c+CH 111KRhbDYTsKKSD0PvZKKipAcuH26KDr1xq4MwlKPBmUMaN9af90JKcd4RysF14mv+7I YF12zDsbn4hLgnsL02y3TPj7ALn9hSH8J5HFpIWEylZGk5cLWYlPFwqoP62dvQXmL9wl G5KMUhRPjCpdZBIxIPo/RNFbDn90Rk+rZjmAhB7eEHW5A/C4cJ7TnHnzjIwH1UWAfQ2j r3AJO4Zu65LepPCUJ/vMwkFpkGuWowk6erRf2ybefaNaLQTzTzf074o/NE2cWIWn+ZuA tzNw== X-Forwarded-Encrypted: i=1; AJvYcCWtgbVrUAZVX27z6LRgesujgsb7RnMWHhhMHqcUp36r5Td8crR+G3GxRzKK0/nzab0DXrkBJZRHFQ==@kvack.org X-Gm-Message-State: AOJu0YxX0CKY4Qhgto4UGbU2jTG0nAGPXM2tHCH6TDP1LMvuAFhdIE1r +1A0STe761goyj+aevB/kuTBLbnOvqJaDDPmr2TQ+VqCvJa3VL6q/h4ZTV7cXvEUo18mkABXCxk b1ZO5UKIYe7DhYA== X-Google-Smtp-Source: AGHT+IHDWCtsJ/5jduSfjKCiGsbR920yirUwpI0CePyKkQEEcAeAv5QDUW+I6X/+MdTEL+UPb7oTVguYSXBKpx8= X-Received: from wmqe6.prod.google.com ([2002:a05:600c:4e46:b0:43b:c914:a2d9]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:35c7:b0:43c:e7ae:4bc9 with SMTP id 5b1f17b1804b1-43ecf842969mr131465855e9.1.1744104249155; Tue, 08 Apr 2025 02:24:09 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:42 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=3335; i=aliceryhl@google.com; h=from:subject:message-id; bh=LmtcKlgkxP20LxSNq37k/eXJOg5jI9B+op34oo2QYlU=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OsoxyVRA9K3PlCKr3B/V+eq1q3gOWsdM/eiZ X6K6ZfFYLyJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrKAAKCRAEWL7uWMY5 RhEYD/4kfuPcMl/0QAODznj6Z6rJZ5GbQA6paTos+nodEsXLiY5K7KF8sXZ9m9HJTOXfxUpr35t 9d3MYoHUG8X+nN+7y27bmoEl4iX4gIiMayP3g7ZdhstImQd7F066cNJcFBH1sNAOrVXuJxIyEY9 SoBJu8KFCx5vYsInFWNcy/zUY8h+JQTgNr1Vl9IBy1zSCjtNFHjUje+j4ntKN94ibZED5FQ2j8z kWu3QLhK5v4A0XpD8yt/ukwfDgKuUXwSs53w3MzZOgJtBy3eRmPapqXBfACVrKQz0PbKyzWPs2x i0f5UPpqZbWu9zmyRHmd0HqUUJnZvcUe38eNlOS241KVxKtb7eZSqiASAOGSK1DMV+XyFxM2WRN txmkDEKuYUrNMqeQi9yYhnknTvQbllMTtDzr0KeWmeP5shXPPOmfJETUe+qKjzKhNlfjZeLVu1e QdG51nh4dJk61DNeXYIq7gzxCMNk7bFLWJbezGnGlLYV2Gf0q6raYCAtwOI1iMn/qZeRJTm4J0f zLvHzfkLprVn689x4BVJ7PD5SNMmxS4BJVqiYhlfxLF/AVPW2LLg6y52gXb/ZckUu9csL3tZV2y XTi1fsOmVPx1sq7h/Cvwhfoomv9yQzJlgkzUgg0hUN9+m40owcDN8CNsW8duOTqJ68tXwJ/GwXT PGfD3DtHd9SDcgg== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-5-d8b446e885d9@google.com> Subject: [PATCH v16 5/9] mm: rust: add mmput_async support From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspamd-Queue-Id: 5D198160007 X-Stat-Signature: 58y8pzx9r4xghtfycetygcxiu6buj3as X-Rspam-User: X-Rspamd-Server: rspam06 X-HE-Tag: 1744104250-849253 X-HE-Meta: U2FsdGVkX1+mMXR7G1VaUuyOi7JF3V8CHvhzj0f9Pod4gBbloz5Zc47bKGlRCEym80zmSypksoI92+CNIIQyaiVWzcerG0xEO0yHUYnDNHjtWsXP+qe3Wf5JgWFMqaI9ilgB4ZJBuqjmh0NUFMRztpdNWTYov37BqD4eV8qX4oq0iJ7tsJngAsH8gNazAJBN9/CvfppGrc0kJ9yuGq80ldscze3LsaF2oLzLRZnAse74TfxmKk6kbT8vOmLAhsuMONsOv1DPk+lBrmCkNHtin2LVJXxFpGlHJz+3ic4nerfu1EsajxLNHeDYa0nEZT7HbPAgzARhFPlnDy/gBARfsbqjJqnbHSQ1m2I0ByUrV2HVufKpJEhY9Tx3SXvMj1SZieWkMy8gqP6JAf2aWYaYUtQgS0YRPFM3mQmU6AlT7RNJ1eDJMs4qGGKkDY5ovHrrPSUYlcuaGfhjlPA0lVOWxpn2wvVPekUG4Da0VZedRs/MMfs51jIU14D/+/YEh+Ztasr6kTMu2d+lfLfsPztfbQXMAH+IlLXzWlC+R/eUToUm+V4oV7AM35ZdLCxDHX4NY9pGQNfXFWhYE07m/uMzyEMX6zlrBkVM1JHJwMZ8W4aXkm/PFpdYA/TDOGBBNqJoiP+0cg07/uKsdFscFmEmQfaUUy5G1peZgcYNf+0Iue3XLK4WOE1mIRI7at30g5ZbzSQ5StgBdGASoncwH3ViQWC16LkIdiZ2pxPaF64PBVyRzSI84l2VdcrtsO1mvdE4AIpFt68lINqWHleuiOgTBuNfbLFSY6jSGcE8aRu107qW9ObkaslB+w4JscCv1yPrNdGAU9jdsbbe0QA8RUKpfxJnYPtlrZSVhDmmWAAEcRqQChHvea893PuFjcExKqOJJbEW/3WTqw3/AC0udKNfMCFVJT1b9vunuC5cZpXuuTXD+cctyxFsd+Q+BS8oqSEM6oRk2+THobRrfC2iniQ ueLSxOqv Seo95FA3iX3v522oGuB33rOs6J9ifNeGUDxh3Wl9DBh5g+E1r/fi9m4n1imXPhkTmUn2amBx0LiprRs0tOSqDjwM4Jy5Fw7+B6KAUvrgy6oGm+LVUYMcXRPOJgjoG5FVpPANfOALFhUMUPxkhnFpX0KbgemohbznK7L2OqNCIUDSjmoNeVrchkTdZZbeeIOfPuJmDNYh+0vlWFtGwR1HpFMBAIqFdeQUX8WqzrL1hZtOn8cdrB/TquBaf65ILbAeNAQtDfG1lXFBlaO5CNv61yy8htoMO3jFvKPUfMbMTO16vRU8jzjKd2M+VtYP2cRRzj8ux039yDuqk1Ipd+x1qzTcPJgEBUNm0thmi6u7mO3NSlurGkScVlMEy16c0I3rzOZAoiyVx7cqqD3d0Pr7bet9KlA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.294846, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Adds an MmWithUserAsync type that uses mmput_async when dropped but is otherwise identical to MmWithUser. This has to be done using a separate type because the thing we are changing is the destructor. Rust Binder needs this to avoid a certain deadlock. See commit 9a9ab0d96362 ("binder: fix race between mmput() and do_exit()") for details. It's also needed in the shrinker to avoid cleaning up the mm in the shrinker's context. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/kernel/mm.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index c160fb52603f8d4b349000451e2200fb477d98a6..615907a0f3b487996ddc066083c4984a443f7146 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -111,6 +111,50 @@ fn deref(&self) -> &Mm { } } +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// This type is identical to `MmWithUser` except that it uses `mmput_async` when dropping a +/// refcount. This means that the destructor of `ARef` is safe to call in atomic +/// context. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. +#[repr(transparent)] +pub struct MmWithUserAsync { + mm: MmWithUser, +} + +// SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called. +unsafe impl Send for MmWithUserAsync {} +// SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads. +unsafe impl Sync for MmWithUserAsync {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for MmWithUserAsync { + #[inline] + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmget(self.as_raw()) }; + } + + #[inline] + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmput_async(obj.cast().as_ptr()) }; + } +} + +// Make all `MmWithUser` methods available on `MmWithUserAsync`. +impl Deref for MmWithUserAsync { + type Target = MmWithUser; + + #[inline] + fn deref(&self) -> &MmWithUser { + &self.mm + } +} + // These methods are safe to call even if `mm_users` is zero. impl Mm { /// Returns a raw pointer to the inner `mm_struct`. @@ -162,6 +206,13 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { unsafe { &*ptr.cast() } } + /// Use `mmput_async` when dropping this refcount. + #[inline] + pub fn into_mmput_async(me: ARef) -> ARef { + // SAFETY: The layouts and invariants are compatible. + unsafe { ARef::from_raw(ARef::into_raw(me).cast()) } + } + /// Attempt to access a vma using the vma read lock. /// /// This is an optimistic trylock operation, so it may fail if there is contention. In that From patchwork Tue Apr 8 09:22:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042485 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 65500C369A1 for ; Tue, 8 Apr 2025 09:24:17 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F02326B0023; Tue, 8 Apr 2025 05:24:13 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E379A6B0024; Tue, 8 Apr 2025 05:24:13 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C4DA46B0025; Tue, 8 Apr 2025 05:24:13 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id A2BD86B0023 for ; Tue, 8 Apr 2025 05:24:13 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 8256F120943 for ; Tue, 8 Apr 2025 09:24:14 +0000 (UTC) X-FDA: 83310340428.05.F10C059 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf04.hostedemail.com (Postfix) with ESMTP id 8CC584000E for ; Tue, 8 Apr 2025 09:24:12 +0000 (UTC) Authentication-Results: imf04.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=nWxkdUxl; spf=pass (imf04.hostedemail.com: domain of 3O-v0ZwkKCCwITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3O-v0ZwkKCCwITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104252; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=NbS7MAhMYKAe1fvQnX5I031aFw3fZNHXs82c8Rh/ZM8=; b=Xpu7UriPxKQPn7KnOnQVgjt5fuIJiftb9OPRSqnmQxHqBM+2QtZLoyzQLYQA6DstLUh/7W CLstyopEiE9t5cV5/ZTzV9pnyGxLMlc0gnIBpCoH9GfxmC8p0DWUByxEYcNLtX0I+sf9nH m0MV6191zi895k/hLzZ7ihS0qz5ZFZc= ARC-Authentication-Results: i=1; imf04.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=nWxkdUxl; spf=pass (imf04.hostedemail.com: domain of 3O-v0ZwkKCCwITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3O-v0ZwkKCCwITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104252; a=rsa-sha256; cv=none; b=akPak6SjINL5OcjM+pWVQU4d4MkY0poJK0CDH3Nv88pAFE87TiBhDZdhZLUzr7x//8ST+8 URYBNz8+wuURl6QlAlM1s2SRreqIXDSgAIRF/F9MQkRIAD6Jo/UCCwkUitzI406VE60ukX mBjGxZHyOpFzDVFz2xj6QqQIsz1qRvc= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cfda30a3cso31647405e9.3 for ; Tue, 08 Apr 2025 02:24:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104251; x=1744709051; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=NbS7MAhMYKAe1fvQnX5I031aFw3fZNHXs82c8Rh/ZM8=; b=nWxkdUxlauEzSG2MV+yUPFKi3r1MiNzXDLx06KMHHV7do9pA/rlnSzCnrfGjbOdMJw vMNProLjtI5bSv98MfP1ECZD7+ebDwzFkmP+q0ioeDxbsujGSTDjEJXmM7V58RRBixhV 55ELGsvORKdGmwcHz2nog1h8STKUYXglJ2G+ksjOdZFI2YN3i012rJKnXEu2b+PKOWza 9kLiOjGpwkzPTsJ4Z3WgllODNmsYcBLd0rvvphNiWtSNeRYoCJ9DxSnpqy4Cpnc/Uj4o UT6kOplwi7QbnLB/+CQ1L0wk6Gi6C7orGNzkA5rmilqs2IcDSDRygQOJJCBrRx1blwUo nTkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104251; x=1744709051; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NbS7MAhMYKAe1fvQnX5I031aFw3fZNHXs82c8Rh/ZM8=; b=Obbro+lgRtkE4btXy6wHM5JJAh4L2VzXhQgKYieFmUXSf9r/mh/KoZGqf/btyB3XfJ qZTV5qZVqojevgVh+V+FZv3NlTpuekSSs3ruJawFVegQy8aPP5EbjUvAMfQWigqhQrrk I7xk6M5moO9JAfwPCUxL/1WHKIIu1GWUHEuNOABKfAl+W68WB3Hoe+mVHlQHVBzWamkt MsrBjZKjMjwMHgMaEr84WMXT75JNaViRB1ji304Jwh2Dn/R5MUyCO2rjry7pYXGzJfxF Ho/tV5yJL04uzZ0hM/etGCd3TNNUDSKjhagGA525yTDJ6EUXSg68yPEEDlBtJYapZYgh M74g== X-Forwarded-Encrypted: i=1; AJvYcCVfqGeAZh8cQVa9sGVzL5Z1ARqTfwe4ZTqX7DOWyy6V6amJnvoqSJAC/WIP+pd37RXFZcMpprhThg==@kvack.org X-Gm-Message-State: AOJu0YxzGnmwCJLqysWNzaVAJ1WjUyknrqw+teOFGW/mFHRYd03rj5T4 3m9ysx0VJ3G/1aSvZi5MUNY4ttw5I/vebxdF20RBM4qDIsEgkeaakWZIKIPo15cQcrsn1AJZ57K hNFkgjc9jsx2NCA== X-Google-Smtp-Source: AGHT+IE4W/KsQEJrmEgz9IsoTLynGVEAhAHKzspx/nbrSFmIxb6oHbD2e0Mgj+efPoxDwU0BvGGyyufB1Mi07JA= X-Received: from wma7.prod.google.com ([2002:a05:600c:8907:b0:43d:4038:9229]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a0a:b0:43c:f689:dd with SMTP id 5b1f17b1804b1-43ecf8d0a37mr135840695e9.19.1744104251264; Tue, 08 Apr 2025 02:24:11 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:43 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=8695; i=aliceryhl@google.com; h=from:subject:message-id; bh=y7o7ZyQ2dPEky50Ue+6FuWOqrOt6CBr0m5lqB46eSLI=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OspqQy5WgY/Qd+8dWuqTUfQ3HnCwBb8dVD05 EA6Kry80NiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrKQAKCRAEWL7uWMY5 RgG+D/4imuYCLk7UElHu8hBZPmO6nTzNlNaQKt0LiTcGYywxsrABM/WJ8sMq5nF56+zZSR06nuc 56Kmkc7+8F2O1qfjff8l3mHCzT0J9cf6wAYYALBXOkz5KvBs7hWsjNTdnJzWZn++ZEjrRbTdrvq yg+RSfCLjZlIhNX6Qd/XZpMrLipc6MkzjLWxzEujf6AnkG17xmf4E8Kg02holVGJXsTKo+qM766 seqiZkbFJzPBajPN6woE0fyAqN8+JidK+UJmAYYNB/Xdfl4yGudLtE7gjgbrHNhlS1anVWwuFZC FdSApqsObE8OK9MNeI6RuiAjuro8QX9Qw/jocbWr0aBk1+Pn7TnOFobEil62TNdBYyA+8peUYAG jh93VskPs3P8of4BOr051oLK5kwcG25LOWkkStYuiYb3Emdi6ep3U/6tAcPb5MGnFCl5lBjr++/ UDPMjSqUQdpDlqWBx7rNRwDmCe2sMGlf7qo5K8Oly0cNdX+wmfJZ7/sKVg9sVXfAmH5RoKej18i LgUdXmjLd8L1exfbJ5E35i+jFmbusUl3F1xK+8ontqpt4uMc17eaMyDYaBc4ao+gqBIk2U3Nzgj LLd9Y59W9MRwdX2jJf8mifll5w1o9piYo9LgxbM7KFZHEPIIHAOfsvTSGIK/N3PmMbd89l33pKn WLK3RhVfl1Zx/4g== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-6-d8b446e885d9@google.com> Subject: [PATCH v16 6/9] mm: rust: add VmaNew for f_ops->mmap() From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspam-User: X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 8CC584000E X-Stat-Signature: 78cimxmzg49cp7o4w6ewsp9cjoq1dieq X-HE-Tag: 1744104252-822847 X-HE-Meta: U2FsdGVkX18K6KdkZB0nqoT5spKvb+saaVCBRgsUvIn6gqRA+ZeavKxn5vLWvPKEJNXmr1HOv2VU51cMrYvyJCcD+py/2sUS+bX7zj8/E9pN4/3nZGDcTGLKkdNXx8BmckY29fUSaqo/kB+t5ilpPGNC9WdKHGDmypJYlAQdwBPRsMGKYblxS5fKDxQtLSCFknafbyjHHrFSsS1s1mF1u+b688Z54p3J1psilPmkrso0rVkDn5GtZvOjJe7zMkCCEg15YoxtI7Z7Y0G47hT5/Qzb6S7VhNs1mbQrzzzS1+nhMiJCR/phkdzojPYaiwtSnZsQeujaVws0iXplQQVBWNUbQQnYrgVJIn7clyHs+owwNWePbDTZ990eWC3L8NI69xN4ZYX759FJyA2ZpHM6ODgUqbv+kP+F9AcAE1zKcDP8ZWLSTJNgqXx8imji/oF0IElJYZVaDf2lzW3vysECLQUf6wbZ7b7fO6o/v3wF33VETZdEueW7QJwWYMqUvcdaJkcUfGftLED4T87aAAkxNznMb+muB3ZoAE/1dKqL8tAlEvSlk4D2sLInP/mPFscVOmTy7+qWsvG1/JMDngBOmyX8hY5r7dprjq8bPguYKNk1sEUj098zos3PgJzpA+B3sOA4YkKxj/EktP8vYKPBc+tLCGRYleNhh8sSAw3k3cDZiubkPzFLpXDFrnQTw1/sYHA0pkaYyBbRzhFhaaaWu1/zeN4xrwGLIPS8MlLjipIxHc4+fGq0CO0Y3l8QK6vMQyTdU34yUmuqirIqR1ZmyrTg5DjxRghbTpf/FmqZ47qwxCcT0GkRApNxX+liX1dyvnMZe+a8r528hW/enZxTa8tvXNYPeW9AzldkRoYl5T9/M+NmILrWO791E6gQNy8CJco6BPkdZ8Ya8+7ahvLt5W2CeRc+WEdzvtnUbZkghmM4zj8Q52i5fbaHT02fXNypYDwZ7aQz33Bf9zzvkDX 54JZHyhy OuP+hXjTVbZDxmtO4B2R/4knlm9QI+WX++kEFsMtGEp4sknchG4Safm2U0Juz8oHHQRXRJP89yAgubeWfNefLbHwOYBrhHy/tf6+HrK4SAS7wU2m2liPA2GBMXsvUaXKfOTrDyqN5KYtziyRyDzR0KhyIZnjjNfD66nGpZ1NYvmGbUmRhrKeqm5fwopomSyyy3rLV5uB1AFZIsosOvGTW/XywZrXVEapoWXjyaMGSNy1MQAy8NKpteaCZQB9CDJMQiKDVWnkWtnotBla6UEPqD7szWDLukg7xUz39s1M7bsulJGUZ5iN8B/PC7tOLQIFAwtiOeHppHygT3kLy9uxQNotdLzX6mL6FTLvud/iSWuT8hxCDvasRwlbr96fDYbfTq0EA5RG/jtcRvMSflyJoTCRlve0NLVqWbzsxcRqVFrzkD1tURgS+W1IyQ9kFwJG6Z+hASpyaDLSc3uYuZgoZYAQlWHJTdZ7zUWmeyPzv3stDm2bvjqZtSKhoVIUWXCZPjkjPNxEDLJ/6K4NdaOPEH9jb5DxrSwH+QefHjuVk+GBXyGoUSSDWuypjOhevgGSjq7YUvbmrZQYaOahYl9D1z1E7BRui0HCezrZtqePwe4XE3Uy0of7QBPNs/dwyxhiMmjdJlM78nS3d9f59waBOBtzr++cw60+QlAfTnKngCf/CqkGK83nKq8V9yL57sG9BlXalYEYO85IPl4Mg0mWMQIys2MkCeCZfj+6n X-Bogosity: Ham, tests=bogofilter, spamicity=0.130391, 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 type will be used when setting up a new vma in an f_ops->mmap() hook. Using a separate type from VmaRef allows us to have a separate set of operations that you are only able to use during the mmap() hook. For example, the VM_MIXEDMAP flag must not be changed after the initial setup that happens during the f_ops->mmap() hook. To avoid setting invalid flag values, the methods for clearing VM_MAYWRITE and similar involve a check of VM_WRITE, and return an error if VM_WRITE is set. Trying to use `try_clear_maywrite` without checking the return value results in a compilation error because the `Result` type is marked #[must_use]. For now, there's only a method for VM_MIXEDMAP and not VM_PFNMAP. When we add a VM_PFNMAP method, we will need some way to prevent you from setting both VM_MIXEDMAP and VM_PFNMAP on the same vma. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Jann Horn Reviewed-by: Andreas Hindborg Signed-off-by: Alice Ryhl --- rust/kernel/mm/virt.rs | 186 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 1 deletion(-) diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index 3e2eabcc21450497a02ffa1ed1f31f3e7e7e1b6b..31803674aecc57408df7960def17cfdc2cebcd6c 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -16,7 +16,7 @@ use crate::{ bindings, - error::{to_result, Result}, + error::{code::EINVAL, to_result, Result}, mm::MmWithUser, page::Page, types::Opaque, @@ -198,6 +198,190 @@ pub fn vm_insert_page(&self, address: usize, page: &Page) -> Result { } } +/// A configuration object for setting up a VMA in an `f_ops->mmap()` hook. +/// +/// The `f_ops->mmap()` hook is called when a new VMA is being created, and the hook is able to +/// configure the VMA in various ways to fit the driver that owns it. Using `VmaNew` indicates that +/// you are allowed to perform operations on the VMA that can only be performed before the VMA is +/// fully initialized. +/// +/// # Invariants +/// +/// For the duration of 'a, the referenced vma must be undergoing initialization in an +/// `f_ops->mmap()` hook. +pub struct VmaNew { + vma: VmaRef, +} + +// Make all `VmaRef` methods available on `VmaNew`. +impl Deref for VmaNew { + type Target = VmaRef; + + #[inline] + fn deref(&self) -> &VmaRef { + &self.vma + } +} + +impl VmaNew { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is undergoing initial vma setup for the duration of 'a. + #[inline] + pub unsafe fn from_raw<'a>(vma: *mut bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Internal method for updating the vma flags. + /// + /// # Safety + /// + /// This must not be used to set the flags to an invalid value. + #[inline] + unsafe fn update_flags(&self, set: vm_flags_t, unset: vm_flags_t) { + let mut flags = self.flags(); + flags |= set; + flags &= !unset; + + // SAFETY: This is not a data race: the vma is undergoing initial setup, so it's not yet + // shared. Additionally, `VmaNew` is `!Sync`, so it cannot be used to write in parallel. + // The caller promises that this does not set the flags to an invalid value. + unsafe { (*self.as_ptr()).__bindgen_anon_2.__vm_flags = flags }; + } + + /// Set the `VM_MIXEDMAP` flag on this vma. + /// + /// This enables the vma to contain both `struct page` and pure PFN pages. Returns a reference + /// that can be used to call `vm_insert_page` on the vma. + #[inline] + pub fn set_mixedmap(&self) -> &VmaMixedMap { + // SAFETY: We don't yet provide a way to set VM_PFNMAP, so this cannot put the flags in an + // invalid state. + unsafe { self.update_flags(flags::MIXEDMAP, 0) }; + + // SAFETY: We just set `VM_MIXEDMAP` on the vma. + unsafe { VmaMixedMap::from_raw(self.vma.as_ptr()) } + } + + /// Set the `VM_IO` flag on this vma. + /// + /// This is used for memory mapped IO and similar. The flag tells other parts of the kernel to + /// avoid looking at the pages. For memory mapped IO this is useful as accesses to the pages + /// could have side effects. + #[inline] + pub fn set_io(&self) { + // SAFETY: Setting the VM_IO flag is always okay. + unsafe { self.update_flags(flags::IO, 0) }; + } + + /// Set the `VM_DONTEXPAND` flag on this vma. + /// + /// This prevents the vma from being expanded with `mremap()`. + #[inline] + pub fn set_dontexpand(&self) { + // SAFETY: Setting the VM_DONTEXPAND flag is always okay. + unsafe { self.update_flags(flags::DONTEXPAND, 0) }; + } + + /// Set the `VM_DONTCOPY` flag on this vma. + /// + /// This prevents the vma from being copied on fork. This option is only permanent if `VM_IO` + /// is set. + #[inline] + pub fn set_dontcopy(&self) { + // SAFETY: Setting the VM_DONTCOPY flag is always okay. + unsafe { self.update_flags(flags::DONTCOPY, 0) }; + } + + /// Set the `VM_DONTDUMP` flag on this vma. + /// + /// This prevents the vma from being included in core dumps. This option is only permanent if + /// `VM_IO` is set. + #[inline] + pub fn set_dontdump(&self) { + // SAFETY: Setting the VM_DONTDUMP flag is always okay. + unsafe { self.update_flags(flags::DONTDUMP, 0) }; + } + + /// Returns whether `VM_READ` is set. + /// + /// This flag indicates whether userspace is mapping this vma as readable. + #[inline] + pub fn readable(&self) -> bool { + (self.flags() & flags::READ) != 0 + } + + /// Try to clear the `VM_MAYREAD` flag, failing if `VM_READ` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma readable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYREAD` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_mayread(&self) -> Result { + if self.readable() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYREAD` is okay when `VM_READ` is not set. + unsafe { self.update_flags(0, flags::MAYREAD) }; + Ok(()) + } + + /// Returns whether `VM_WRITE` is set. + /// + /// This flag indicates whether userspace is mapping this vma as writable. + #[inline] + pub fn writable(&self) -> bool { + (self.flags() & flags::WRITE) != 0 + } + + /// Try to clear the `VM_MAYWRITE` flag, failing if `VM_WRITE` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma writable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYWRITE` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_maywrite(&self) -> Result { + if self.writable() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYWRITE` is okay when `VM_WRITE` is not set. + unsafe { self.update_flags(0, flags::MAYWRITE) }; + Ok(()) + } + + /// Returns whether `VM_EXEC` is set. + /// + /// This flag indicates whether userspace is mapping this vma as executable. + #[inline] + pub fn executable(&self) -> bool { + (self.flags() & flags::EXEC) != 0 + } + + /// Try to clear the `VM_MAYEXEC` flag, failing if `VM_EXEC` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma executable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYEXEC` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_mayexec(&self) -> Result { + if self.executable() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYEXEC` is okay when `VM_EXEC` is not set. + unsafe { self.update_flags(0, flags::MAYEXEC) }; + Ok(()) + } +} + /// The integer type used for vma flags. #[doc(inline)] pub use bindings::vm_flags_t; From patchwork Tue Apr 8 09:22:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042486 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 1BF35C369A4 for ; Tue, 8 Apr 2025 09:24:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 899FC6B0025; Tue, 8 Apr 2025 05:24:16 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 870776B0026; Tue, 8 Apr 2025 05:24:16 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6EAD76B0027; Tue, 8 Apr 2025 05:24:16 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 418E86B0025 for ; Tue, 8 Apr 2025 05:24:16 -0400 (EDT) Received: from smtpin25.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id C2801B7152 for ; Tue, 8 Apr 2025 09:24:16 +0000 (UTC) X-FDA: 83310340512.25.142C132 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf25.hostedemail.com (Postfix) with ESMTP id D4A30A0010 for ; Tue, 8 Apr 2025 09:24:14 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=cs0igio+; spf=pass (imf25.hostedemail.com: domain of 3Pev0ZwkKCC4KVSMObiRVQYYQVO.MYWVSXeh-WWUfKMU.YbQ@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3Pev0ZwkKCC4KVSMObiRVQYYQVO.MYWVSXeh-WWUfKMU.YbQ@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104254; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=BKgSHP0UtGt+oV0m7wKF/tLoW5odDMj8vC7ZBIsrjgA=; b=af8SiCSgsuHs2XK5GlV2w6HsagxQbh/MvQM5domh0MJDKTJLHNlpCTL8PfMxV06dXSYTpI k7ht9b/32rMYCqWua97xHOtWqkLO9ukSm00Qdx2liymJKf8fXDxcwfxVRCaTdpt35sFQ+Z dfdOdyMLRKgMhw1FouoXr0rsC9eaUDY= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104254; a=rsa-sha256; cv=none; b=jck+ArSsQAFOzkNJp/+4yR+T1tEYUQyHvMZnSTYQZUYe4UrkgBxEA1tgomJLnrxiUffgDo mYlhePxWq3e10BS3uKx6Netg0kvrXYrr3W/TSfleXD3HX29xVojBe8Wh9HIpwyzd1cyFNw N8AwSFKg8efSgIWmmoAYw9n/bhO4+CQ= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=cs0igio+; spf=pass (imf25.hostedemail.com: domain of 3Pev0ZwkKCC4KVSMObiRVQYYQVO.MYWVSXeh-WWUfKMU.YbQ@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3Pev0ZwkKCC4KVSMObiRVQYYQVO.MYWVSXeh-WWUfKMU.YbQ@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d5ca7c86aso35454605e9.0 for ; Tue, 08 Apr 2025 02:24:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104253; x=1744709053; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=BKgSHP0UtGt+oV0m7wKF/tLoW5odDMj8vC7ZBIsrjgA=; b=cs0igio+GFXiSqzZTeRBxAhdjxCi/DMplPmNWinxH/IdFWJ+8bve+kaJZdDmKplf7U Su2g4+MiOVMPwDBSTokmTmliFqsL5I05SzVqs3oUkaJqI/Ff9S0os2FDaiPAPlTblvFY azs5UoxstnP9+nlGkwq5zBurtJ89X1U80dsE2QqPgf5DufXC+sGfpcNA94GI9ij2AceE OZSTMGxJsbYZ4jjdxaLT1Qr6V6TYNQxnCrtRsdVfPx15yzmbtbOFVOV+qtC9g0wMylsR hwlBZtk+X3UoHmfC3aTA8ZyxpD/WRGh5qr9OYpHgi2gU2McDylhr5IKAZNuRPlD7GZP4 s4Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104253; x=1744709053; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BKgSHP0UtGt+oV0m7wKF/tLoW5odDMj8vC7ZBIsrjgA=; b=gRmR8JxqE4rm48hIP/HZKJs4YN6RMoerK5Vs6nIzxwx7YjdKwS6upPP2JiDzd8CyD4 mlVtNgxTXcgWjX+NwX52rnsKiDgksx4Zp7xqgRxhOgjCrbHBH/Udg1e9c2erBuKkh1mj 2kCVZX653BWib1ulSsG2RKV+n5lQ2cDgO1r+F3du/88ozZiEqbROB0l3iNbwguQkIsk/ 0D3uxg0xbIRSiThdvXQ9cuMfYtzFRmkZCx319M141wskOAGceMIv6SZzolLfT5Qe/aa8 a5SMEw358ASJBQ1JgaV3YJXGeGm5YLO5wamvDASscBDMIQUQ9k+BembCPz5Or3bCeHUE bCbQ== X-Forwarded-Encrypted: i=1; AJvYcCWp1+VZwu6CgBTRfK9mVOAD85MAiT+XwreB7P83F+LOfbKcqna1nMUhFw3d7vHfwRos1Z+zackJ6A==@kvack.org X-Gm-Message-State: AOJu0Ywf5CRZIJuJuExJ1QCZDWbMTuvmlX8P7QFgZUhtKuop/x/C1YJQ h2n8mXhbNjkVazaoEs5iMyvypFoOd95dcMloY6cdyKER6A2sSdVCdcAld3dRlejc1u8QtqhMQA7 zZfpoQytqDlK4hg== X-Google-Smtp-Source: AGHT+IGKxxFnPnuYQhaMn/C1VHYnvMuiIufsTL+sO+MIIaikeAKJnyM61wTXLBWoQ3PMLnGlIdAs32Q49e1duTw= X-Received: from wmbbg30.prod.google.com ([2002:a05:600c:3c9e:b0:43d:44cf:11f8]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3c8d:b0:43b:cc42:c54f with SMTP id 5b1f17b1804b1-43ecf85f20amr127759175e9.14.1744104253433; Tue, 08 Apr 2025 02:24:13 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:44 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=4043; i=aliceryhl@google.com; h=from:subject:message-id; bh=Sfgq//T2QbdbqoMqrWL7BQLUnjSkh+kpgtWBCSQivcU=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9Osphtn+zBbO8bZFvj7pkZhABnr8VbaFiFEa8 vSFFXvSY0CJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrKQAKCRAEWL7uWMY5 RuB5D/9RA7H3cjo5/vuxD/VzZyAqYJY0YR+6BZctDljbIzIBs0tHYjQGyX3i9/lx7Z7I24HZgG3 GYQdZnhqBnxIJeK+aTd3+I6/0Kxt/6IQR6Q12dP9St1jrQR8QY0NbbDlJIpZsh4EnSERgXH4VR2 Iv/dWP2koycKPHA53sb047tk00stSC8FBUFUrjU+fXIPEprHdC2O05Nn5ARdWJUF/teV+/VTF6O MjPU9y7a0TfFX9kS24LGjGguBGUuk04TbeSD3AJ4zI5ttYztwe4rDoy0G5JK0WAdqdOzGvUzjyA AqLPw3Ciycje/cSkNmjIHN4NgE5iCyRh6m6L/7vT4aE+XlSlK/fFXROSRYWDwRSP/MQc0QPPXCm NN3I1c3hL62W/8E3tveIBF+7V6kp8O8061h//5D2SScR/0OuE8ZVF+UvtYcgqS+ZHSWbog/rDqb LvsWYiaW8W+F501INqaTk2CdldRz8wUlYQ2xCRWzFZTlkuXChlDP4Zf8Uhv25SGDKHNwfGiWyoC cw7vMFfyvtUFsM0wxwdFhrB6PlXfugS1gsYCk4jrqO7Oq1WipRemsXxl5MPxVF9hjTQSISjPoT4 mlt0NTtEaoXDAUWMGbFJyHdFpelBc1wv8qCvZZmccvdR9ztCb6uhqJ185K2TK0waNVyj8MsR5Cz nJaPeEL8PTxVTAw== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-7-d8b446e885d9@google.com> Subject: [PATCH v16 7/9] rust: miscdevice: add mmap support From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Stat-Signature: qarcw6rnqyeta78g44oyr769ry3etjs9 X-Rspam-User: X-Rspamd-Queue-Id: D4A30A0010 X-Rspamd-Server: rspam08 X-HE-Tag: 1744104254-496159 X-HE-Meta: U2FsdGVkX1+z+YJPxlRrPQxsBVlK12IgPdnxAwG1Q2A+ErwWykeaNOpOojy3CesmF491VyuWv7i39zdKeLLGSYTPLENXZsByLAHVfZE/kt6652YKepbo76ILrHO0IJPzC+qxf7KRMRbxVHG7juVR4v7tSwQHsmSUxa7G2Dk22M2UqnqFI8pnbl1CyU7x881wnKNRID+UNtFYHFdeSSoax61U/eTsS+0CcdceZ29PG/fOF/u/iRMMUMENJgD4VmgMoB9dR/r0+LLi0rC7mfxRuD2OKYtkVO/YolDZvKMoj+n71JS/aSz2sENVzS35cVKsXX/dlGCiBW2DfZW3ADHjw5XHNEFnL7KWN2v9SAfjD6Nb86383R+GZtrY8C1RpXCwhTjLyP53tZKPY8AQN8n4+J7ms3/xwANYv0XmVv0ubINu0oSvBQ6YyNwWxvZhrcMTyXb79uypcBnkcSBkrFWGWQlYrR10Hft+nS3+5giKaAKElgkyKHgQC30pQE2kAYbbDx6N/qOIJK7E1wyz0HIz/dl7CkcwkiSa/AHWhacOSXADqhiIhx+vE+amYkecuJSBqGicYLTdApvRB5Fn7GqPlLdjSIFG9bCYg1hw8n2gYBD829hHD8NPnxLUQCPR9Ocq6pzQCiz3WJXTn9VCal4gKVQYYVy/h/L64He7WSw2PQJiLXx/4B/F4k9bO1GoapWbbUmrhV/j4X9g1hlxjHxjwISo8wDpNUQ4zevOcs0487vEp8cIeFGzkpCc1X+xei6tUsDfG/5qOVqbptfn6Vp+fBHCC+dqZLfjKeu9EkoUd9goyMifxzybFqOvZBPdQ9LYc3rX+ZlA9ZmAFqGuFAQYLDw8VTtuETbWNSZESITPMD9SywOQ2aIWmEMSDMGy1GLlfarB5a8/4ddd2ek2L/DYD3xwsJJdy7HdnTWfd5hbLqQtDZ8Mb6PjRR6ByZh7VffPnPmxdH8PpjdqCR3ZwbN Qy/JEsLB Ygs46fpO+ciWZuoNDO8WgQBpbu9QJXu9c/l0TNwWuAp0H9bXjZejU06PaZ46oYXhd4dhCAVlcZBJjsEMhN8Ud61F/CZw+n42xRjkuTR7HtEDS6BlJXFbve47+rMfaQg4fyZ4tWdz8mLBtVsp12YDm9bHVn0UjRM9p2SaqGkbR4S7j5ZCGyINOTy1adYr0PRXFAvRZeROH0sMp79iI5+5wlPuCuU4B0txmMeahf1d3D+0wsAI6EB8NHfn/uMdxYkHO59EjwDJvx07AWfXNW2pfwDxPIIUf3OW2aVkwQiFUqq662RgzscsV77VgtqdDFJYtLYkSsITB5K+KSoUQ//sWgMG+jMGMxJ3UniIcYg+z+utXWyVNEQE8DSjuK/ekBVSCt0pzghx8uM/hD24AHg+jTcCD1Tl3KSrxFzPQ6kA9j45e+QBj5gZVcTNa/SdQxFe+rBVj+SgjAxUdwyWW+kzVBZ4/gbpzZbV35SAy3UJ5I6APmU7x7jV79oZ9yejY1iOvWF7W1ePznFsNx2D35u+MBTq4nGkq3aWJQLoQxWPYSnnen4lcmzdvUIVDycDpQvcMOqLoxLP4+pukDQezxuzZXUQ6D7LtIRmnRs/P4RyLQbQ6npwMky0mcNANLXh1h76E6wSnN/64zWy6PkCOMpJwhgbFDrQE9pdXVOKPL4AcgNeaaJHV458n7nQmlR1iITS/dEjcVOiw+fT224BxcAxEeuUAXPTK0445T121OshGg9nznj9uLsWFWJ45QT9TW670ErdPkF+xcJhUMNdIamqjVvamUwQHtTcxJfFikum1PBqs/XY= X-Bogosity: Ham, tests=bogofilter, spamicity=0.361210, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add the ability to write a file_operations->mmap hook in Rust when using the miscdevice abstraction. The `vma` argument to the `mmap` hook uses the `VmaNew` type from the previous commit; this type provides the correct set of operations for a file_operations->mmap hook. Acked-by: Greg Kroah-Hartman Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/kernel/miscdevice.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index fa9ecc42602a477328a25b5d357db90b59dc72ae..9d9771247c3865761c4387467de3f1d1a82691b7 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -14,6 +14,7 @@ error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, ffi::{c_int, c_long, c_uint, c_ulong}, fs::File, + mm::virt::VmaNew, prelude::*, seq_file::SeqFile, str::CStr, @@ -119,6 +120,22 @@ fn release(device: Self::Ptr, _file: &File) { drop(device); } + /// Handle for mmap. + /// + /// This function is invoked when a user space process invokes the `mmap` system call on + /// `file`. The function is a callback that is part of the VMA initializer. The kernel will do + /// initial setup of the VMA before calling this function. The function can then interact with + /// the VMA initialization by calling methods of `vma`. If the function does not return an + /// error, the kernel will complete initialization of the VMA according to the properties of + /// `vma`. + fn mmap( + _device: ::Borrowed<'_>, + _file: &File, + _vma: &VmaNew, + ) -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + /// Handler for ioctls. /// /// The `cmd` argument is usually manipulated using the utilties in [`kernel::ioctl`]. @@ -223,6 +240,33 @@ impl MiscdeviceVTable { 0 } + /// # Safety + /// + /// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. + /// `vma` must be a vma that is currently being mmap'ed with this file. + unsafe extern "C" fn mmap( + file: *mut bindings::file, + vma: *mut bindings::vm_area_struct, + ) -> c_int { + // SAFETY: The mmap call of a file can access the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: This is a Rust Miscdevice, so we call `into_foreign` in `open` and + // `from_foreign` in `release`, and `fops_mmap` is guaranteed to be called between those + // two operations. + let device = unsafe { ::borrow(private) }; + // SAFETY: The caller provides a vma that is undergoing initial VMA setup. + let area = unsafe { VmaNew::from_raw(vma) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + + match T::mmap(device, file, area) { + Ok(()) => 0, + Err(err) => err.to_errno(), + } + } + /// # Safety /// /// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. @@ -291,6 +335,7 @@ impl MiscdeviceVTable { const VTABLE: bindings::file_operations = bindings::file_operations { open: Some(Self::open), release: Some(Self::release), + mmap: if T::HAS_MMAP { Some(Self::mmap) } else { None }, unlocked_ioctl: if T::HAS_IOCTL { Some(Self::ioctl) } else { From patchwork Tue Apr 8 09:22:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042487 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 BEDF9C369A1 for ; Tue, 8 Apr 2025 09:24:22 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CC5E66B0027; Tue, 8 Apr 2025 05:24:18 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B83226B0028; Tue, 8 Apr 2025 05:24:18 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 988166B0029; Tue, 8 Apr 2025 05:24:18 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 6FBC96B0027 for ; Tue, 8 Apr 2025 05:24:18 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 39608140891 for ; Tue, 8 Apr 2025 09:24:19 +0000 (UTC) X-FDA: 83310340638.21.9454834 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf23.hostedemail.com (Postfix) with ESMTP id 379BC14000C for ; Tue, 8 Apr 2025 09:24:17 +0000 (UTC) Authentication-Results: imf23.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=a7gcMRnb; spf=pass (imf23.hostedemail.com: domain of 3P-v0ZwkKCDAMXUOQdkTXSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3P-v0ZwkKCDAMXUOQdkTXSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104257; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=i/iS6j8sog2gWlkO8N4e9GnomGOnzRdojkcd1mY5y4s=; b=jOmOFT0C0heapcsbGP4p/On3uAKFX9DRkiedZYMw4bQU3EIj6sQF+MPMCwjpSWRRrt42PC zVXYb4sx5fxZgRgVXQ9rbryF350f9PXueQTPF1CwnmIm7UgXWeHss44x5CStaQSSIOKkEU qMEXnEuNLNCcK4EsEp0PqhGz6vQG/Pk= ARC-Authentication-Results: i=1; imf23.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=a7gcMRnb; spf=pass (imf23.hostedemail.com: domain of 3P-v0ZwkKCDAMXUOQdkTXSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3P-v0ZwkKCDAMXUOQdkTXSaaSXQ.OaYXUZgj-YYWhMOW.adS@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104257; a=rsa-sha256; cv=none; b=qi2PkYZ6L5vy8IXgbQMD5eD/KIt4fLDrT5InCQeBh7uOCw672Q6jPiYKXTvM2j0k9PzGBp 37IQ/SH1YuP+EbNpx2sluPOcB8DCIcFI1PvN/Th35ZuuiQE1TCSy+HDdxQdtgzrNebEcj6 T1JTtXlf0DTwUQR8wEX74xoxp6sWNKA= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43941ad86d4so29805205e9.2 for ; Tue, 08 Apr 2025 02:24:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104256; x=1744709056; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=i/iS6j8sog2gWlkO8N4e9GnomGOnzRdojkcd1mY5y4s=; b=a7gcMRnbOg0QI4JNMy0lv2teNB26dVMcGPynuPzPqGXyEjE6r9wGG2MDfJSgZ+Az1w EgKOhzf7DwbVQ+k5n1fC1FCe02TEees3Mnp0H/KzyXpEMUDV5mlEZ2z6bePx0O91hIBm oBGoeNc1FI304iv+pPC4Mc1+Al5SnDOZjCeXT84ZwARivTTJQpHQ9czKiqeiuZaN8rDd 3jDNN8xHPB49mcVdjjzm6uXZk31GWfsDCeTzRn7jr8U8/6WTSNtSbAArPl014OcTRdnv 80hxo2Dp3FzBQ32tJT/uVyY3EEGpoACcSMj7s9HoW6PWfSGz+P8vVpeYs1sqXTdgE5OY euRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104256; x=1744709056; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=i/iS6j8sog2gWlkO8N4e9GnomGOnzRdojkcd1mY5y4s=; b=xJ460t5u4fZ0SXCVrwOzmI5snhKYL/BExlpp1bO9iyyTOPt2NCBB+FfOeI+MKhCLPy Kg3KM44TthPH/QLqO7m6skl6VYSPuO0CHwasgUZvI9fMqhSv2lZ+Phc7RlHFY6aZ53us TobdO159xhZqj3zgQe3TrDLOqSvf4OKBKFYYQZMmFcr3NLKOgnCkAwM5M6mSEs3Ln+sW 5Cxka5sKBbe6euZhFj4MOFJ/lDfYNTBfCyz233V4+JO8ZG1fC127wMHqlCp/eeFvoi8i daBWPj8HwOGufijDFP/kGNv0duzjrK9eMi+/ZvIg3VpFzHXHMi/d9DvIVz1NPbmJ/9f1 ykcw== X-Forwarded-Encrypted: i=1; AJvYcCVMDyaZyMihDaALNidVcOcxZhJQs6r6ms1G3TsEPZzHmR1Wwt6z7NzUdJHHlduqA3SUJ3DcpyGlqQ==@kvack.org X-Gm-Message-State: AOJu0YxjlqKg0e5hLdJ/IU0PH49Xv7tDcBN/f3kcPqxhU6O53ixamlCK qo1Cej29Xl4uA1vQMvhoVGMg4p2Eoq4O3VKCdGcDN4hRORf+XeAPh26cmcJU0XXAcJS299trbmq W4kiCiUV3j6nByA== X-Google-Smtp-Source: AGHT+IHF4NMSTY3mUG2B1pvCnIHlh681e95gNltNsfVVp4JefLhrym0jFmpHMw8kUvRQBBTjs304yWhH2X14FoA= X-Received: from wmbbh5.prod.google.com ([2002:a05:600c:3d05:b0:43c:eba5:f9b3]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:350b:b0:43c:e2dd:98ea with SMTP id 5b1f17b1804b1-43ee076d4e9mr86042425e9.22.1744104255877; Tue, 08 Apr 2025 02:24:15 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:45 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=18345; i=aliceryhl@google.com; h=from:subject:message-id; bh=ZfEObmQkj1K3PKRhCEzycp7JYCVP4InOSHhkkaYW3MA=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9OsqEqNPldGcWxjAzols5gVQJsu4f41mtvuD3 Zwy4ljmPVyJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrKgAKCRAEWL7uWMY5 RvBKD/9IFiNL5Ku7pGR+940xcFVTxVcQDOAb53+tx67czlPjUE2rZLyOy1w76quLKPBNzGhtoVE E9vBpKlcqUewiXeKHaJ7zzL6FMyqufbec3labawGa2/VCTb8OSXvunWYeiw9Kk6YqTPVUPE1JeV +/0XqN2MndSJ6DVtm2brRxpaI6Jol5s2kEllSTSe7josC+mZoagHh/hg2Vc+xkL4DqQmcECeFBb Z4LuobiDd2WRCLzxa7R9A5dlSP42//gJPGIWPWb++K4x1JXR+RJrFyLiEcB/XpPl9yU1G3PgupE bEatbY++29jb+VWV3Rb5fch6IXOhlARKcsfvOCetvcbUYwC2Fv8yOdYYTyIUgMeJqQxHIgJ9R3J D3gqTKpjvfYcWpAbjBJJMLQ2AtV672K+04hiFkMIRIXNNf60cetT3bTeURh2mq3+D9ciixsiQHq cpei/QOqXlc/v7+5Ac3Tsu2mtOAclC66hWSOV7QQaBoDG44hQe014DJ2SHz7bNgWInjudyMpw1G 1c7X4X4FCF8dHUUx9wlCe2RjIKJvixKkiJegIUcLmd2qgUcJog/fhqJf1yHAbJQ2nsi2I1bXChy +rwuCzJn8S6tXSEic8/UYTd6w+9D0tfJc5edsiDdL1mkBU3JshxzaH+RGxhkJ3DbwNyQ9Q5s9CF /iKw/aVIiNXmjgA== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-8-d8b446e885d9@google.com> Subject: [PATCH v16 8/9] task: rust: rework how current is accessed From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspamd-Queue-Id: 379BC14000C X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: ygq4d7d9xyhmf8qs65ogcfzaz7k83bks X-HE-Tag: 1744104257-275938 X-HE-Meta: U2FsdGVkX185pmhBnLV+HpDVDTly5iG74LOH4t70QOjIEtQd1cZUTMdfgH0Gz/hEHakWarXKp5ugYuZvuF6jfKW8EDSRfY7zC8RUTdklW5lzWa96MJkUB4mmmTuDSmzqP8abGA91x9R6vxhzYc9MN3nBotwgsUfgkfP70D2gKn3cCG3Jhxpj7U3H6GGOaZv/w3v4rCPQcOogx+7Nph1Xza55L0xH9fxe5pzdc/g0sQXoUs4JZLozB6WwPAFWnSMhNeh+pReYXzzR8V2/eksj/ecvR9GvwIucV2Sy2kg8CGtgt2NdrPlCTeQ/enmg30IayjemWdGygTo6k6vF8UIauz0l1uqrh4Vxe0eEEJ4c60BSqeclbmxvVBdhXafqm4a2yv+0k6Xa5t3kHrzWOM3Bc07+1GAgq/NeQ6+KmRgSOib4Ph7yYvZKJ+XMsAWhuwlpUTEK2lONQAh7nbfXjfgnIALmh5ztJ8rgxM0+SkY1XL/sSp0EnQRGcWoerFqn5iQv1nOWsOuGhHW+6FZHsEh+FGumX0IOIvTMQB79NBtNayiHyXzO8Ffbzw9FfdeSVR0+7AmtEqabQjAfx3vvSo6jvr/9KZL83Rpi/wOTR98acvzaijY23kWi6I+ZGQ+Al2D/7p767cQRMgzW1B0tHStZoD063qpx6V88BnM/c0HU784/U6q+HI7iaWeBDqasyWHTR8wZlAQYnPw2QD+qQfyUjxFEaFRbUqtm3Q+7LjoG0kctmNiU9iuo3xOdt3z2V5Z6ZorGKU+qnRPiIizlQmInSmdjrX99kiYf6PN53MLfNVE3PglIkbILocxLMkIhUshmoSfBmYoyNEVOLNUpe8AjQ5vspd97YCswUzDP8iPPezLa6qnh5Nqud4tQgelYD7NDwxLGHJl9TDz9treCtfo8mf4IKnQNJaq9aop75NsdYwDDgUMCl0d+VJNZyCWS07M4WIJ9Rv62AiVXf6R60hy KBlCLp5N epeQfnnRCIvASnCGjyxenBcBi9tkuYOJUS0EYvb0Mn/4oUPeEVlg7rOC+t4fKP5uMDYCRMQwXOBwstjeZlXYcAnYLN5DHLeH2bEB4+Z1jJ+OEJ1zi1ejGqpjODetaxEEu24c8Vgu+pUeUvJYUQ4S9G4Ej/6JvzkAO9Vz+1lKuSmpjANcVqyhclRn6ad7P506kXX4lyHnZlgkdlXeVpZU4yICxMz+ig0CshadAsdroYFsiidxR6J5gC/jtJMEsXBZk5lmZg9ZG0kU5ksaZiFbHvqQ1AtH22tzyd8DtDx+Q2E1il0HvUnA/bItQ1ndUKAH0aHbGES7dlC1hZBYuy9dsSRFjgPPI+DbIJVRJkGpAG1EHTMDwuNvtyzj8RId475CmLRNqSdeFfvP2P0HGvkK2aRpuYRn1GQ685TFcZXJSYH3dc4gqz3Q3TyaQPOm526MGsRdsrB7zCRE3727Xq2cvIJAQMGfXLgsK34cN6rd/Y3PmKzxxWG4Z08s6gmEXgQTvD8Hw/BZcsr/Fh7CHH9Gh3+KPryoCo42Cq1irQKMYV+CbtyG0QPwxznn6qZJLeWZoYwPQBAOhSrkDJuP/lfm0oEYAho7YOCENdwTTu5YYIhlR5qFsQqeSvZcLesfslWX1hsFYp9vXqRFdjW54eQB+vWNjoYuP2ukrmfMQT88P6y92wJePZn6Yv26x37eQbK5EgKuIUjAZhbbbdsImhUl1R5OMivpVqlHOBAsSTb6jpDGTRnbb5AI1jEff9ztcAeValZyK22yyPUr6fzM= X-Bogosity: Ham, tests=bogofilter, spamicity=0.280792, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Introduce a new type called `CurrentTask` that lets you perform various operations that are only safe on the `current` task. Use the new type to provide a way to access the current mm without incrementing its refcount. With this change, you can write stuff such as let vma = current!().mm().lock_vma_under_rcu(addr); without incrementing any refcounts. This replaces the existing abstractions for accessing the current pid namespace. With the old approach, every field access to current involves both a macro and a unsafe helper function. The new approach simplifies that to a single safe function on the `CurrentTask` type. This makes it less heavy-weight to add additional current accessors in the future. That said, creating a `CurrentTask` type like the one in this patch requires that we are careful to ensure that it cannot escape the current task or otherwise access things after they are freed. To do this, I declared that it cannot escape the current "task context" where I defined a "task context" as essentially the region in which `current` remains unchanged. So e.g., release_task() or begin_new_exec() would leave the task context. If a userspace thread returns to userspace and later makes another syscall, then I consider the two syscalls to be different task contexts. This allows values stored in that task to be modified between syscalls, even if they're guaranteed to be immutable during a syscall. Ensuring correctness of `CurrentTask` is slightly tricky if we also want the ability to have a safe `kthread_use_mm()` implementation in Rust. To support that safely, there are two patterns we need to ensure are safe: // Case 1: current!() called inside the scope. let mm; kthread_use_mm(some_mm, || { mm = current!().mm(); }); drop(some_mm); mm.do_something(); // UAF and: // Case 2: current!() called before the scope. let mm; let task = current!(); kthread_use_mm(some_mm, || { mm = task.mm(); }); drop(some_mm); mm.do_something(); // UAF The existing `current!()` abstraction already natively prevents the first case: The `&CurrentTask` would be tied to the inner scope, so the borrow-checker ensures that no reference derived from it can escape the scope. Fixing the second case is a bit more tricky. The solution is to essentially pretend that the contents of the scope execute on an different thread, which means that only thread-safe types can cross the boundary. Since `CurrentTask` is marked `NotThreadSafe`, attempts to move it to another thread will fail, and this includes our fake pretend thread boundary. This has the disadvantage that other types that aren't thread-safe for reasons unrelated to `current` also cannot be moved across the `kthread_use_mm()` boundary. I consider this an acceptable tradeoff. Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Reviewed-by: Boqun Feng Reviewed-by: Andreas Hindborg Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl --- rust/kernel/task.rs | 247 +++++++++++++++++++++++++++------------------------- 1 file changed, 129 insertions(+), 118 deletions(-) diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index 9e6f6854948d9ef9bb203a3548c9b082df8280e2..927413d854846477578cbaf06e27d1fc867d0682 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -7,6 +7,7 @@ use crate::{ bindings, ffi::{c_int, c_long, c_uint}, + mm::MmWithUser, pid_namespace::PidNamespace, types::{ARef, NotThreadSafe, Opaque}, }; @@ -33,22 +34,20 @@ #[macro_export] macro_rules! current { () => { - // SAFETY: Deref + addr-of below create a temporary `TaskRef` that cannot outlive the - // caller. + // SAFETY: This expression creates a temporary value that is dropped at the end of the + // caller's scope. The following mechanisms ensure that the resulting `&CurrentTask` cannot + // leave current task context: + // + // * To return to userspace, the caller must leave the current scope. + // * Operations such as `begin_new_exec()` are necessarily unsafe and the caller of + // `begin_new_exec()` is responsible for safety. + // * Rust abstractions for things such as a `kthread_use_mm()` scope must require the + // closure to be `Send`, so the `NotThreadSafe` field of `CurrentTask` ensures that the + // `&CurrentTask` cannot cross the scope in either direction. unsafe { &*$crate::task::Task::current() } }; } -/// Returns the currently running task's pid namespace. -#[macro_export] -macro_rules! current_pid_ns { - () => { - // SAFETY: Deref + addr-of below create a temporary `PidNamespaceRef` that cannot outlive - // the caller. - unsafe { &*$crate::task::Task::current_pid_ns() } - }; -} - /// Wraps the kernel's `struct task_struct`. /// /// # Invariants @@ -87,7 +86,7 @@ macro_rules! current_pid_ns { /// impl State { /// fn new() -> Self { /// Self { -/// creator: current!().into(), +/// creator: ARef::from(&**current!()), /// index: 0, /// } /// } @@ -107,6 +106,44 @@ unsafe impl Send for Task {} // synchronised by C code (e.g., `signal_pending`). unsafe impl Sync for Task {} +/// Represents the [`Task`] in the `current` global. +/// +/// This type exists to provide more efficient operations that are only valid on the current task. +/// For example, to retrieve the pid-namespace of a task, you must use rcu protection unless it is +/// the current task. +/// +/// # Invariants +/// +/// Each value of this type must only be accessed from the task context it was created within. +/// +/// Of course, every thread is in a different task context, but for the purposes of this invariant, +/// these operations also permanently leave the task context: +/// +/// * Returning to userspace from system call context. +/// * Calling `release_task()`. +/// * Calling `begin_new_exec()` in a binary format loader. +/// +/// Other operations temporarily create a new sub-context: +/// +/// * Calling `kthread_use_mm()` creates a new context, and `kthread_unuse_mm()` returns to the +/// old context. +/// +/// This means that a `CurrentTask` obtained before a `kthread_use_mm()` call may be used again +/// once `kthread_unuse_mm()` is called, but it must not be used between these two calls. +/// Conversely, a `CurrentTask` obtained between a `kthread_use_mm()`/`kthread_unuse_mm()` pair +/// must not be used after `kthread_unuse_mm()`. +#[repr(transparent)] +pub struct CurrentTask(Task, NotThreadSafe); + +// Make all `Task` methods available on `CurrentTask`. +impl Deref for CurrentTask { + type Target = Task; + #[inline] + fn deref(&self) -> &Task { + &self.0 + } +} + /// The type of process identifiers (PIDs). pub type Pid = bindings::pid_t; @@ -133,119 +170,29 @@ pub fn current_raw() -> *mut bindings::task_struct { /// /// # Safety /// - /// Callers must ensure that the returned object doesn't outlive the current task/thread. - pub unsafe fn current() -> impl Deref { - struct TaskRef<'a> { - task: &'a Task, - _not_send: NotThreadSafe, + /// Callers must ensure that the returned object is only used to access a [`CurrentTask`] + /// within the task context that was active when this function was called. For more details, + /// see the invariants section for [`CurrentTask`]. + pub unsafe fn current() -> impl Deref { + struct TaskRef { + task: *const CurrentTask, } - impl Deref for TaskRef<'_> { - type Target = Task; + impl Deref for TaskRef { + type Target = CurrentTask; fn deref(&self) -> &Self::Target { - self.task + // SAFETY: The returned reference borrows from this `TaskRef`, so it cannot outlive + // the `TaskRef`, which the caller of `Task::current()` has promised will not + // outlive the task/thread for which `self.task` is the `current` pointer. Thus, it + // is okay to return a `CurrentTask` reference here. + unsafe { &*self.task } } } - let current = Task::current_raw(); TaskRef { - // SAFETY: If the current thread is still running, the current task is valid. Given - // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread - // (where it could potentially outlive the caller). - task: unsafe { &*current.cast() }, - _not_send: NotThreadSafe, - } - } - - /// Returns a PidNamespace reference for the currently executing task's/thread's pid namespace. - /// - /// This function can be used to create an unbounded lifetime by e.g., storing the returned - /// PidNamespace in a global variable which would be a bug. So the recommended way to get the - /// current task's/thread's pid namespace is to use the [`current_pid_ns`] macro because it is - /// safe. - /// - /// # Safety - /// - /// Callers must ensure that the returned object doesn't outlive the current task/thread. - pub unsafe fn current_pid_ns() -> impl Deref { - struct PidNamespaceRef<'a> { - task: &'a PidNamespace, - _not_send: NotThreadSafe, - } - - impl Deref for PidNamespaceRef<'_> { - type Target = PidNamespace; - - fn deref(&self) -> &Self::Target { - self.task - } - } - - // The lifetime of `PidNamespace` is bound to `Task` and `struct pid`. - // - // The `PidNamespace` of a `Task` doesn't ever change once the `Task` is alive. A - // `unshare(CLONE_NEWPID)` or `setns(fd_pidns/pidfd, CLONE_NEWPID)` will not have an effect - // on the calling `Task`'s pid namespace. It will only effect the pid namespace of children - // created by the calling `Task`. This invariant guarantees that after having acquired a - // reference to a `Task`'s pid namespace it will remain unchanged. - // - // When a task has exited and been reaped `release_task()` will be called. This will set - // the `PidNamespace` of the task to `NULL`. So retrieving the `PidNamespace` of a task - // that is dead will return `NULL`. Note, that neither holding the RCU lock nor holding a - // referencing count to - // the `Task` will prevent `release_task()` being called. - // - // In order to retrieve the `PidNamespace` of a `Task` the `task_active_pid_ns()` function - // can be used. There are two cases to consider: - // - // (1) retrieving the `PidNamespace` of the `current` task - // (2) retrieving the `PidNamespace` of a non-`current` task - // - // From system call context retrieving the `PidNamespace` for case (1) is always safe and - // requires neither RCU locking nor a reference count to be held. Retrieving the - // `PidNamespace` after `release_task()` for current will return `NULL` but no codepath - // like that is exposed to Rust. - // - // Retrieving the `PidNamespace` from system call context for (2) requires RCU protection. - // Accessing `PidNamespace` outside of RCU protection requires a reference count that - // must've been acquired while holding the RCU lock. Note that accessing a non-`current` - // task means `NULL` can be returned as the non-`current` task could have already passed - // through `release_task()`. - // - // To retrieve (1) the `current_pid_ns!()` macro should be used which ensure that the - // returned `PidNamespace` cannot outlive the calling scope. The associated - // `current_pid_ns()` function should not be called directly as it could be abused to - // created an unbounded lifetime for `PidNamespace`. The `current_pid_ns!()` macro allows - // Rust to handle the common case of accessing `current`'s `PidNamespace` without RCU - // protection and without having to acquire a reference count. - // - // For (2) the `task_get_pid_ns()` method must be used. This will always acquire a - // reference on `PidNamespace` and will return an `Option` to force the caller to - // explicitly handle the case where `PidNamespace` is `None`, something that tends to be - // forgotten when doing the equivalent operation in `C`. Missing RCU primitives make it - // difficult to perform operations that are otherwise safe without holding a reference - // count as long as RCU protection is guaranteed. But it is not important currently. But we - // do want it in the future. - // - // Note for (2) the required RCU protection around calling `task_active_pid_ns()` - // synchronizes against putting the last reference of the associated `struct pid` of - // `task->thread_pid`. The `struct pid` stored in that field is used to retrieve the - // `PidNamespace` of the caller. When `release_task()` is called `task->thread_pid` will be - // `NULL`ed and `put_pid()` on said `struct pid` will be delayed in `free_pid()` via - // `call_rcu()` allowing everyone with an RCU protected access to the `struct pid` acquired - // from `task->thread_pid` to finish. - // - // SAFETY: The current task's pid namespace is valid as long as the current task is running. - let pidns = unsafe { bindings::task_active_pid_ns(Task::current_raw()) }; - PidNamespaceRef { - // SAFETY: If the current thread is still running, the current task and its associated - // pid namespace are valid. `PidNamespaceRef` is not `Send`, so we know it cannot be - // transferred to another thread (where it could potentially outlive the current - // `Task`). The caller needs to ensure that the PidNamespaceRef doesn't outlive the - // current task/thread. - task: unsafe { PidNamespace::from_ptr(pidns) }, - _not_send: NotThreadSafe, + // CAST: The layout of `struct task_struct` and `CurrentTask` is identical. + task: Task::current_raw().cast(), } } @@ -328,6 +275,70 @@ pub fn wake_up(&self) { } } +impl CurrentTask { + /// Access the address space of the current task. + /// + /// This function does not touch the refcount of the mm. + #[inline] + pub fn mm(&self) -> Option<&MmWithUser> { + // SAFETY: The `mm` field of `current` is not modified from other threads, so reading it is + // not a data race. + let mm = unsafe { (*self.as_ptr()).mm }; + + if mm.is_null() { + return None; + } + + // SAFETY: If `current->mm` is non-null, then it references a valid mm with a non-zero + // value of `mm_users`. Furthermore, the returned `&MmWithUser` borrows from this + // `CurrentTask`, so it cannot escape the scope in which the current pointer was obtained. + // + // This is safe even if `kthread_use_mm()`/`kthread_unuse_mm()` are used. There are two + // relevant cases: + // * If the `&CurrentTask` was created before `kthread_use_mm()`, then it cannot be + // accessed during the `kthread_use_mm()`/`kthread_unuse_mm()` scope due to the + // `NotThreadSafe` field of `CurrentTask`. + // * If the `&CurrentTask` was created within a `kthread_use_mm()`/`kthread_unuse_mm()` + // scope, then the `&CurrentTask` cannot escape that scope, so the returned `&MmWithUser` + // also cannot escape that scope. + // In either case, it's not possible to read `current->mm` and keep using it after the + // scope is ended with `kthread_unuse_mm()`. + Some(unsafe { MmWithUser::from_raw(mm) }) + } + + /// Access the pid namespace of the current task. + /// + /// This function does not touch the refcount of the namespace or use RCU protection. + /// + /// To access the pid namespace of another task, see [`Task::get_pid_ns`]. + #[doc(alias = "task_active_pid_ns")] + #[inline] + pub fn active_pid_ns(&self) -> Option<&PidNamespace> { + // SAFETY: It is safe to call `task_active_pid_ns` without RCU protection when calling it + // on the current task. + let active_ns = unsafe { bindings::task_active_pid_ns(self.as_ptr()) }; + + if active_ns.is_null() { + return None; + } + + // The lifetime of `PidNamespace` is bound to `Task` and `struct pid`. + // + // The `PidNamespace` of a `Task` doesn't ever change once the `Task` is alive. + // + // From system call context retrieving the `PidNamespace` for the current task is always + // safe and requires neither RCU locking nor a reference count to be held. Retrieving the + // `PidNamespace` after `release_task()` for current will return `NULL` but no codepath + // like that is exposed to Rust. + // + // SAFETY: If `current`'s pid ns is non-null, then it references a valid pid ns. + // Furthermore, the returned `&PidNamespace` borrows from this `CurrentTask`, so it cannot + // escape the scope in which the current pointer was obtained, e.g. it cannot live past a + // `release_task()` call. + Some(unsafe { PidNamespace::from_ptr(active_ns) }) + } +} + // SAFETY: The type invariants guarantee that `Task` is always refcounted. unsafe impl crate::types::AlwaysRefCounted for Task { fn inc_ref(&self) { From patchwork Tue Apr 8 09:22:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 14042488 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 B1FC6C369A4 for ; Tue, 8 Apr 2025 09:24:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 967256B0029; Tue, 8 Apr 2025 05:24:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 8F2B66B002A; Tue, 8 Apr 2025 05:24:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 71B9C6B002B; Tue, 8 Apr 2025 05:24:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 4EA8C6B0029 for ; Tue, 8 Apr 2025 05:24:20 -0400 (EDT) Received: from smtpin18.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 295CE1CA623 for ; Tue, 8 Apr 2025 09:24:21 +0000 (UTC) X-FDA: 83310340722.18.0E00F47 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf24.hostedemail.com (Postfix) with ESMTP id 428D718000C for ; Tue, 8 Apr 2025 09:24:19 +0000 (UTC) Authentication-Results: imf24.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=ni9ne4Qu; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf24.hostedemail.com: domain of 3Quv0ZwkKCDMPaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3Quv0ZwkKCDMPaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1744104259; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=iIuImScQv8Fi6Jr5gBxEmMobPhodk5GrITEtyDe/zuI=; b=RsZpNHwQdDWQt+i2TJORgUesenvxUiF5XHDYoBDrfI2T57XqWbOF2usxSDlXocyNd0q9s4 K/AhhZtxdSRz4wqkufNGdHp0wssYi/o1+RDoYBnOl2NRli6AFSITN7VwGmV1ABItk3+bTO DtckACxgaYt6rhahlhH9zpqamReuXpE= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1744104259; a=rsa-sha256; cv=none; b=eZKbnyON/arO9/vcKUezJ8QEpWjuPrTJI/L0Rdifrh27+HEaA01D51wCDytkWWdnXVnPRa UGeg7mwFTf70efJXMW+1lBHILiBTufox3SqPmqLahYOXLwUzYkCUFsyk4S3xAqIid4APbN pb26HnhonWIvAzDpZHPzNfA4PZLKU8g= ARC-Authentication-Results: i=1; imf24.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=ni9ne4Qu; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf24.hostedemail.com: domain of 3Quv0ZwkKCDMPaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3Quv0ZwkKCDMPaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43d51bd9b45so36715335e9.1 for ; Tue, 08 Apr 2025 02:24:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744104258; x=1744709058; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=iIuImScQv8Fi6Jr5gBxEmMobPhodk5GrITEtyDe/zuI=; b=ni9ne4QuFOwHQwwM7rFtBY8b3yRhAJulnJdBWWH5c37/9oUtZ9u5hC6761U0hlRqy1 vQ1dHxazoHpbQBOsQ9obuCbfR7GlQwHSoQdgM2qu5oEoLUn8fNFWmZb+8sVnANP0+lIK EYe0tdmitjPSFLc+ZNTq66YoEq4NnF0LGDIT1QEJCXoPWyBi+EtdP4RuNV3AQRVlennS PVCR4kVnfesNfqHaFLB+ReYm3tBfGHX2ku9YCRnLiMjXSGCF/scCd24J4qxnMfkhHWY6 ZcIfA864mkA8OfWtuAPVw+lLRmWLeviGrnSp+4fvJoPsgFBYIQwzSI9yVEpFBaW355Mn KCtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744104258; x=1744709058; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iIuImScQv8Fi6Jr5gBxEmMobPhodk5GrITEtyDe/zuI=; b=jLd1VrQwL9ihVpL1gKgP9e4D5S/sxduuHEFJwm9z1fRdIAJMO3t30JEUjrjANRcfXv klLCBBs8P739g/N6l5gvy3D4AOkhmDzMPT1AhJBdQAZnj2EOBCOSKcOPoBvqe2rR5WmK 49mldw7Asx3LjyqiBMlBdyU0GVvr6amPYvY+5bw9+Pp37xZf/qIFFnWzhnU4uAilmF4U VqGiIYRA4Ozg7I89WEeS2sp3dLh4V0LU86hXLzroJLzk0FmQYrSJocbqe6G3G31PrXcG 8KriCGB2l8t5mNahDQbLUvXRqF/y2gEdEo69f3bHoBJT4ffUT3VMgIXOT6an8nbVYhOu /Ytg== X-Forwarded-Encrypted: i=1; AJvYcCVyr2n+HCUT7oWmdOq4oHk/+opR3IOaIncLTWQa+wDeOe+0MDqQw/TdEcib6iQlnB+uBULkmdHzfA==@kvack.org X-Gm-Message-State: AOJu0YyN1Hn/qA+k2tgISQX9bPr9mY7thl6WMofLrRZodpy/SxABcRaY upQYFhXHCEoeeDs37hJXiF54yZrJrr0lJDQOZuegwRLRTp5Ay+Aig5pOdb67Jkvx2oYUi6RNBOp SuTP9w5qqKa8GcQ== X-Google-Smtp-Source: AGHT+IFWc1pMQ2RJ9ij6FdvJcqN5KNDRiADu9dL8SpaDl5jyOXZP0BgOscC21FHTrRxiw3z04BlYLCIylAI56hA= X-Received: from wmsd15.prod.google.com ([2002:a05:600c:3acf:b0:43b:c9fc:b269]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1f86:b0:43d:fa58:81d3 with SMTP id 5b1f17b1804b1-43ecfa06ab0mr117784265e9.32.1744104258002; Tue, 08 Apr 2025 02:24:18 -0700 (PDT) Date: Tue, 08 Apr 2025 09:22:46 +0000 In-Reply-To: <20250408-vma-v16-0-d8b446e885d9@google.com> Mime-Version: 1.0 References: <20250408-vma-v16-0-d8b446e885d9@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=1514; i=aliceryhl@google.com; h=from:subject:message-id; bh=m2/7sbOCWUMVifIeec7mgQC4DqxO7715a5mxnPiGobY=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn9Osrq11PicKCteCb0qlte1JemOCFeETkH6Ll/ cnSpgmrbU+JAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ/TrKwAKCRAEWL7uWMY5 RrTVEACTYV04bI/LPuLa9aALNkxEoDBC1dWns2op8JO02wLn1lwgfSVvYpy5ovBu+j7vTYD0Cfk KUPqzTfANnDnX6sBBckjHVgp/cP2bBFJFnVoad8EAP6vIWMqPkUSsNwI2la/g2vyhYzv7qnlWFM g2NZURTwzQq0Nti9cZ8V+IRWNHs8UqTxuf5exDhhF2CDeAj0ROwndmuSioqrSxy8knvimJ5HVrO dJUDn5oHKBvfmCsTMQtuhmuJId6JU53fD/sl2tZ539PAZ8jsfac57wvCxcrMs0HNtN4wdvqiJCn rTEU2gb91keNCTDfzqRHTRfPTlC5N6w8Op0vK/TtkdGOGV5llD4wjpDHc8i6ct7kvoTl1HD5yg4 JRfP8ZALtRQ0sOBWDRG4ixtU/Ura42hA39xatzz8eh1XTz93SRWIelsc/fVkNKShyNgkCyWPpvp gPdQsJhF53ztGLMGDq/if2wtl6qKgcRJPHLRWkkFoWjwb69a/OTOQ0mRopSVJxJxxoXVfwv6iFP oBVwj/tXju7f3HDpnlhvi3NZfB4/jTLdhRY+XEbAFM4OB7kLCDwocD78AylKcQGM4WLhCWURRSI f6/u0CZ1ihQ2vnm3wUGgHBg9TVIJH07635glB9apUJ3aiJZXV6QilE8pJDxsSnyO4NbSmdImtqn EsSKTX6/hCNw5oQ== X-Mailer: b4 0.14.2 Message-ID: <20250408-vma-v16-9-d8b446e885d9@google.com> Subject: [PATCH v16 9/9] mm: rust: add MEMORY MANAGEMENT [RUST] From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 428D718000C X-Stat-Signature: 54ohsfho9uu7p4d91krasfzbzqerpp13 X-Rspam-User: X-HE-Tag: 1744104259-471827 X-HE-Meta: U2FsdGVkX1/7qcoXMF3Ag1WVIP8Cot8WsZ7oCXa0mX8UjMAwDL14kWosvE/DRKZn8TKhau4QKDGEjMphhH05CoOp5rkPHwffPsI7tRC3xXveitRN19NlJwYPm7qXjyOsuukoTVg63VX/BT1BHHtlYgtD+J66Bc4fpnbl6WcjQ85mnuF+QM9PrvUqcwuQar+bhCD5Sc0ev19E1NfoiPf4dbiAyh7Sy3ziHnfA1HS3KdruDHwSBhhYF+zD00A2sY9ezJ31pOx3uoezDb5LAunDTcqSyee0UsBb71b0wl6YMWjL8NEACc0zsB20RHRS/L68VjTHKnY3yRhQkRHa9EXWREEaYf/W3qjMHQyba8Z8pJBGe8KE7cHPLqseaW0aSzPYiaGgw92zdtDLzpviP5IXEzRNdfrcYAz1Y5IbbulVhWj1F0yr0uT2Tko1xkWQRMOKIIU4qJM+Pdr1TfC7HhL+Yx6K6h5LUvdI/yVAJTz/CobiKeZASiwfMkdWBX3viNEvvpzwHgKQj/COWESR6qhvRRX3h/26w/J4kEVxDT4TEWKSb/rEjsJ8A4LHd0huOiAB34EaJujOse7lu3pp+geUuEdhCBx0gS4CFnXqJL7WChpZnZ1F1YTSUL5cG3nrOjJFp7cSL+Vgy5bnKEh/eHdMgQI5BFxTkUSBbXn9h+N/my+e890mCLscwvhiDmqq7GKqReUiPM2T1wNzlox4ChPeiyCrli6CBKf8rtDpwlJL0VM7bv1lVmcyuA5E30urORtLIzWDT6TmSin3ngFBYgSNb/PWD14FKC74imSNl89MGieKeTGpye0aSp/zCCHSkIGYrgvXE6tNZ6hliwjId6wxBrshG6OtMOPwbTCv9ncB7fqs6v5vc1m/bW/DD/brTAiwf/Bp97sslHWhFKjXqlAyblnxVrqNgVhstUQHz3CkkLtLd/ddeeaLdCqnfi4fGfSjTWAStGXXqoS1TkmrUBu Bf6YMdWE FRMOVpCrcxQ9VDIa7XwbuAXvzSFlSXGOfi5Mr0GP4DHUt1tLqybYoZ1vF7zKlBrlP4MzHeHxAfIXPcoyeR90DVHVxUjARH5fZrbGiikkdFS/Sk99FpJqKBHcLTorRvMSL4rrJXBiBRELzaCXn42MN6QkyGkxEKY2mWDPuw4Ix4g0DkLr/JHQnJIGcFwNPHmkzlBZW2+l+afXeGgQGDD+2UJx21bRhdUHRv8exXD1tZIG0ig2Im9lhdxv4NHAWRBa/q+yh9GXxm+87N4bzsY3d4ylevg7ku2qs5eWBQd8FcOUdq9qe1kcqDBAliqWAQFe/4vppt8XHJVRZnvVh3l36D9Vpg2bygETtCOApA+/EJ1Az6BNd4qleORGFyW/6vUbQRzb5kw+0ONCAjBUSyw6E1C3EdHLxtw4CHk6ZzfDoWBdqEl3xSD/OnngNM4d9gT5hmD+2a7YaJSmHTYQzUMTEhIll1Uvi8dKk6/X37hPvV9y12s/2kC1NlxOEGGKziF6AlKcqAWX3neoS2QUdlTWrQzMN3F4YlvIUUqXn7lbUTzO10JoVnxTtZ6D3UCW5a/cRs9QgEx0IV6+kY5MeyIhQb3SIDCU9pi60kqPzAC/BC5+UxwUdIK7nFHTVVezN2aTzm+R/b5mpXQtFXGGejbBp6rQsVoLxEasOxCSaVSnb+uhq/RtnaaJweVXL5rFbJl1cueCEgmYhneMAe0nCzuIqOn9v/GIiMDFoeaTZKoIORqEZgmF+0380M6gkoGD64wRxsi51Lm5uRQxgNSnZ71JW47HdM3/dEEcMCdl74acSMPqZBWHwVRRqe3m+mtU0wXjSNOTfa3QeYlc39zQSyrRfTWaggOYUvtaCFXWCEroyJXNmz9TM5zthvjODRCv244xD2Nv7IQh7nOrzIATzTScwIIgkidpJ4VU+JCN4cbdosHT5+yQ= X-Bogosity: Unsure, tests=bogofilter, spamicity=0.453728, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: We have introduced Rust bindings for core mm abstractions as part of this series, so add an entry in MAINTAINERS to be explicit about who maintains this. Patches are anticipated to be taken through the mm tree as usual with other mm code. Link: https://rust-for-linux.com/rust-kernel-policy#how-is-rust-introduced-in-a-subsystem Link: https://lore.kernel.org/all/33e64b12-aa07-4e78-933a-b07c37ff1d84@lucifer.local/ Acked-by: Lorenzo Stoakes Acked-by: Liam R. Howlett Signed-off-by: Alice Ryhl --- MAINTAINERS | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 96b82704950184bd71623ff41fc4df31e4c7fe87..9f661903723556a309434f83251caba9dd3e0699 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15529,6 +15529,19 @@ F: include/uapi/linux/userfaultfd.h F: mm/userfaultfd.c F: tools/testing/selftests/mm/uffd-*.[ch] +MEMORY MANAGEMENT - RUST +M: Alice Ryhl +R: Lorenzo Stoakes +R: Liam R. Howlett +L: linux-mm@kvack.org +L: rust-for-linux@vger.kernel.org +S: Maintained +W: http://www.linux-mm.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm +F: rust/helpers/mm.c +F: rust/kernel/mm.rs +F: rust/kernel/mm/ + MEMORY MAPPING M: Andrew Morton M: Liam R. Howlett