From nobody Mon Nov 25 02:56:23 2024 Received: from mail-qt1-f176.google.com (mail-qt1-f176.google.com [209.85.160.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1717B1E0E00; Wed, 30 Oct 2024 20:46:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321206; cv=none; b=VH/vZRQEWR7yQaxwME44Pe7WeM1bVQ+MAF6ELKhtjIRmkfR4RUNRGLOWyS4zXeRx6m8aMMgcfllcQi/5orYUP4yTXIrbgCht/fLIbgKY1RMVU17ZKlOPbJZrA5tbgbIE5YNEpQOw2xbEoBbNaZ8MesjxjzWxsBVKsXLnbjL8qtk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321206; c=relaxed/simple; bh=40p+/HOYoLdKJbIi3DVyqIKdZaL43t2+nJwCNcWYA4Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n13WGOD6vlImO7DyVIpCKTLlA6rXGio8WELPMGFwpP2yrHSULpvRUHYQlrKIIAJJ99ZYE/nVzU7+s2v+BR16gSZ6004gKere0zgGt55uiZZEZdjf/rt/YL8ajAl3kWpreEigXx57V3+9VIjYWqtxbLuIs2loYEv9RO270Dr6liM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lrOqaIKM; arc=none smtp.client-ip=209.85.160.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lrOqaIKM" Received: by mail-qt1-f176.google.com with SMTP id d75a77b69052e-460c0f9c13eso2747491cf.0; Wed, 30 Oct 2024 13:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730321203; x=1730926003; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=g9pxM7GSlQsnOFAYSPFhITHq3a0Hq6vT58aRnViDCJU=; b=lrOqaIKMqrkiQa3mL0m/Orrk6aDY+TDoNkw/PIbNyFwTrhoh4EcLyPoD13nKgPeHaK 7MGR082m2qVRlDoY321XXfpXcMwFQfXsi2zOFokB6LkmFv1I4sNoz87HKWWQw71EPhNh l3pvkWAajqCI4OTAKg+VpVd1Y7tZttNQ9hND2wVdklC36rYvtW2OaDizXP0NBRha3loc M0cJl0aMWfkORFv6znNlwK6WpUBranJ+b71y5RCpqfPyk7AHyibovykCDzczgG5mICi+ LlIBNndE5lQmNDGAYy9nfGBvguU4BVpXafo2xOTBpSrFXASX3sq0nJhUOS7Z28+RXg/D 4Y5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730321203; x=1730926003; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=g9pxM7GSlQsnOFAYSPFhITHq3a0Hq6vT58aRnViDCJU=; b=eoDnN6iCQi5pysdjnZnSh2a8XEj6aaR7mKCRgRMGmpmvuGcFcrscwYAxwPVkbySFIl Vf/2o3SF+8z62CFv2GQmxaJvv76cWJxGtaxGVri71B/+6Kt26Old7DNY32E9LWuL3NlH YMIHv2uiTZfIdP34vc7TmtlbrG7AYk1XuWrnlGgfSxn8leBJFT6qzd3sNxLJp3VNeVvZ SBR4cM/i5DB8ZwVxhl3MWgg7lUkdtVGm82jVS/dhxY8+glSmntCA/9ugwtAoTbRHhrzc 3P0q0wJA/sDoan53uRYYrY53fIOhpBEHSoihwvl0KwoVFj9BI1BmQFRXOSWAzXimDSIO 3EAw== X-Forwarded-Encrypted: i=1; AJvYcCUgiy/cwxJngmgtAsbLoZdLZXtr0TVh+XXJqZTrY04V2j6Cw33aZnYy/KYC3FO7jkqIqj6Gf1a9SRbYTGY=@vger.kernel.org X-Gm-Message-State: AOJu0YxpcjOeg+g0UvjKs8N34Mihg2LOjwaH1eAWzsB4iPD7boaBQGZT DS5K72xBa54mIo+wEWlIIq1Qq7ZxHMvjrmVtZliNs91aBklUcCb2 X-Google-Smtp-Source: AGHT+IGj3b90yotioykYulkfcN9+U/CaxZK8I1LzOjP3NRMbrgJPylhnsSkMQRNwMfL52FxzhI8gZg== X-Received: by 2002:a05:622a:54f:b0:460:59b1:d80 with SMTP id d75a77b69052e-462ad32d7cbmr866061cf.21.1730321203032; Wed, 30 Oct 2024 13:46:43 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([2620:10d:c091:600::1:89dc]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-462ad0c72efsm271271cf.50.2024.10.30.13.46.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Oct 2024 13:46:41 -0700 (PDT) From: Tamir Duberstein Date: Wed, 30 Oct 2024 16:46:38 -0400 Subject: [PATCH 1/5] rust: arc: use `NonNull::new_unchecked` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241030-borrow-mut-v1-1-8f0ceaf78eaf@gmail.com> References: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> In-Reply-To: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Tamir Duberstein X-Mailer: b4 0.15-dev There is no need to check (and panic on violations of) the safety requirements on `ForeignOwnable` functions. Avoiding the check is consistent with the implementation of `ForeignOwnable` for `Box`. Signed-off-by: Tamir Duberstein Reviewed-by: Alice Ryhl --- rust/kernel/sync/arc.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index db9da352d588f65348aa7a5204abbb165b70197f..4857230bd8d410bcca97b2081c3= ce2f617ee7921 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -337,9 +337,9 @@ fn into_foreign(self) -> *const core::ffi::c_void { } =20 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T= > { - // By the safety requirement of this function, we know that `ptr` = came from - // a previous call to `Arc::into_foreign`. - let inner =3D NonNull::new(ptr as *mut ArcInner).unwrap(); + // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous + // call to `Self::into_foreign`. + let inner =3D unsafe { NonNull::new_unchecked(ptr as _) }; =20 // SAFETY: The safety requirements of `from_foreign` ensure that t= he object remains alive // for the lifetime of the returned value. @@ -347,10 +347,14 @@ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -= > ArcBorrow<'a, T> { } =20 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { + // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous + // call to `Self::into_foreign`. + let inner =3D unsafe { NonNull::new_unchecked(ptr as _) }; + // SAFETY: By the safety requirement of this function, we know tha= t `ptr` came from // a previous call to `Arc::into_foreign`, which guarantees that `= ptr` is valid and // holds a reference count increment that is transferrable to us. - unsafe { Self::from_inner(NonNull::new(ptr as _).unwrap()) } + unsafe { Self::from_inner(inner) } } } =20 --=20 2.47.0 From nobody Mon Nov 25 02:56:23 2024 Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0D871BD9E2; Wed, 30 Oct 2024 20:46:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321208; cv=none; b=lGWkUqnthYHRwNxdRF+TwdSqcXHOkLjUCxjWyD1eWoewWfm2pEOcd/lTOOVumrKlhhR58xS9CC3m7+bYmKN1AGje3by3VJRIDQT1O/ub3jpwsjz3kz2gG+mbc7T4iHsAS1RgX0MV3X+HrDBmuWneu/L4rMu63ebSzP+5tzmC/jk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321208; c=relaxed/simple; bh=s+JOsokl8HTzsLJu0YwhoCbFGKiWcJDGG6609M+g3TU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eiW0bmMF5MII7HIsqBLuH9AX3Es0HTN9FJ6R4aK5aGJZ8blyk1AKZ3CZ5zHnB9Zp+2i4274kheCMUh/S1V4jPFCRjgDNaGjXdAzOjolc4/zhEikaJt5LQGFiGO7legibKCkRp8jaPjvsmNQNPJVepq0Eewp/0wykLBBJ3ljgVNA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A5jl6PzN; arc=none smtp.client-ip=209.85.161.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A5jl6PzN" Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-5ebc22e6362so177140eaf.2; Wed, 30 Oct 2024 13:46:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730321204; x=1730926004; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=OW45e7gx4fvje5qEi3cakB/2Tqj9cnWab4H35fyWZ0I=; b=A5jl6PzNrHVmrXgKcPMvwa9J5KYDxB6HJR7Vk1VyGpvrlcDPsiHHBGqUiB8fbuMYcn j6FRaJEGJ5GCxrSxnFBUpabl5r6pN7mR7KswSDkbzG3UQ8lHiiHmop4JTls2MBAPSbYp D8QMje78Zd4RCPEOVOop8y6uOovVTiLllMqLcCY+bAhn0SjVSrMs+fcjNvl0tPPGXfsV g5TwphyRyIQL6sUyYOw318nq8OBuvyHh6Z53ohXWF+TFK1nW7Bt+cId1n6jEiv49+FGC U0FSwYHwaJyGXRZwIn1cL7xg8ULTq9q5WwrO+WBhh8MsPS79ukv7jApEBILhc666HEQl +W6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730321204; x=1730926004; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OW45e7gx4fvje5qEi3cakB/2Tqj9cnWab4H35fyWZ0I=; b=aDSdqrtXFZ7LbtVXWxTtMldlFBjrTuknVRwIas+3jTc3F8uqNohglvpI6zSt84OuES /dC61LueMUyIU9qXj+Iq3KTus1YTOUHgv/AF6j+hAgE1Zssu9nQQKhpiYJ9jAbZCYVIm ymzroy1aM6xV4NKAgVioTmSpC3aymMWPyE2PouhGSLgv+bC9LxPlKJj5tnYM4F9MBnC1 0QYVqb2642VIMWn8hSepHa4i13MFwJMVphNWXpPVdB1fpuqKjEqQWGx+DTOyQNaLSTe7 X7UwrCM9Gquik0j7I2MUaHpqkLmtiMMyhEqkz7DoCzaUJ8Ajuw1yKfpxqcoWBe1FAjyj HoZQ== X-Forwarded-Encrypted: i=1; AJvYcCUu07Nwyvm0MurhYLAif+Dlvf1qE15bGa2qXHcRz7HWN3Je0RwlLRLKn+YU9r2wqQdvRZdNwiaImhw+CmU=@vger.kernel.org X-Gm-Message-State: AOJu0YzCFaFOJjGpbuOB2Yr2WJZZzjyPTtxXdEWTVcsKF93td4SwSgbm HnrUDu00tkk9mWJXc8057AWnVkEYD4oOUgegIhq+RvCxhj7li2We X-Google-Smtp-Source: AGHT+IEdneqM5xabBYVFBPR9NlxPfCAAwq2JkQfVv3RZABU0fxOGjJbduxuNWiZU/u66i4/TE9lO6A== X-Received: by 2002:a05:6358:7e06:b0:1c5:e2ea:8993 with SMTP id e5c5f4694b2df-1c5ee958a69mr97166155d.11.1730321204360; Wed, 30 Oct 2024 13:46:44 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([2620:10d:c091:600::1:89dc]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-462ad0c72efsm271271cf.50.2024.10.30.13.46.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Oct 2024 13:46:43 -0700 (PDT) From: Tamir Duberstein Date: Wed, 30 Oct 2024 16:46:39 -0400 Subject: [PATCH 2/5] rust: types: avoid `as` casts, narrow unsafe scope Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241030-borrow-mut-v1-2-8f0ceaf78eaf@gmail.com> References: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> In-Reply-To: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Tamir Duberstein X-Mailer: b4 0.15-dev Replace `as` casts with `cast{,_const,_mut}` which are a bit safer. Reduce the scope of unsafe blocks and add missing safety comments where an unsafe block has been split into several unsafe blocks. Signed-off-by: Tamir Duberstein --- rust/kernel/alloc/kbox.rs | 32 +++++++++++++++---------- rust/kernel/sync/arc.rs | 59 +++++++++++++++++++++++++++++--------------= ---- rust/kernel/types.rs | 5 ++-- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index d69c32496b86a2315f81cafc8e6771ebb0cf10d1..7a5fdf7b660fb91ca2a8e5023d6= 9d629b0d66062 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -182,12 +182,12 @@ impl Box, A> /// /// Callers must ensure that the value inside of `b` is in an initiali= zed state. pub unsafe fn assume_init(self) -> Box { - let raw =3D Self::into_raw(self); + let raw =3D Self::into_raw(self).cast(); =20 // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By= the safety requirements // of this function, the value inside the `Box` is in an initializ= ed state. Hence, it is // safe to reconstruct the `Box` as `Box`. - unsafe { Box::from_raw(raw.cast()) } + unsafe { Box::from_raw(raw) } } =20 /// Writes the value and converts to `Box`. @@ -247,10 +247,10 @@ pub fn pin(x: T, flags: Flags) -> Result>, AllocError> =20 /// Forgets the contents (does not run the destructor), but keeps the = allocation. fn forget_contents(this: Self) -> Box, A> { - let ptr =3D Self::into_raw(this); + let ptr =3D Self::into_raw(this).cast(); =20 // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. - unsafe { Box::from_raw(ptr.cast()) } + unsafe { Box::from_raw(ptr) } } =20 /// Drops the contents, but keeps the allocation. @@ -356,19 +356,21 @@ impl ForeignOwnable for Box type Borrowed<'a> =3D &'a T; =20 fn into_foreign(self) -> *const core::ffi::c_void { - Box::into_raw(self) as _ + Box::into_raw(self).cast_const().cast() } =20 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { + let ptr =3D ptr.cast_mut().cast(); // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. - unsafe { Box::from_raw(ptr as _) } + unsafe { Box::from_raw(ptr) } } =20 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { + let ptr =3D ptr.cast(); // SAFETY: The safety requirements of this method ensure that the = object remains alive and // immutable for the duration of 'a. - unsafe { &*ptr.cast() } + unsafe { &*ptr } } } =20 @@ -380,21 +382,25 @@ impl ForeignOwnable for Pin> =20 fn into_foreign(self) -> *const core::ffi::c_void { // SAFETY: We are still treating the box as pinned. - Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) + .cast_const() + .cast() } =20 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { + let ptr =3D ptr.cast_mut().cast(); // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. - unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } + unsafe { Pin::new_unchecked(Box::from_raw(ptr)) } } =20 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { + let ptr =3D ptr.cast(); // SAFETY: The safety requirements for this function ensure that t= he object is still alive, // so it is safe to dereference the raw pointer. // The safety requirements of `from_foreign` also ensure that the = object remains alive for // the lifetime of the returned value. - let r =3D unsafe { &*ptr.cast() }; + let r =3D unsafe { &*ptr }; =20 // SAFETY: This pointer originates from a `Pin>`. unsafe { Pin::new_unchecked(r) } @@ -445,12 +451,14 @@ impl Drop for Box fn drop(&mut self) { let layout =3D Layout::for_value::(self); =20 + let ptr =3D self.0.as_ptr(); // SAFETY: The pointer in `self.0` is guaranteed to be valid by th= e type invariant. - unsafe { core::ptr::drop_in_place::(self.deref_mut()) }; + unsafe { core::ptr::drop_in_place(ptr) }; =20 + let addr =3D self.0.cast(); // SAFETY: // - `self.0` was previously allocated with `A`. // - `layout` is equal to the `Layout=C2=B4 `self.0` was allocated= with. - unsafe { A::free(self.0.cast(), layout) }; + unsafe { A::free(addr, layout) }; } } diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 4857230bd8d410bcca97b2081c3ce2f617ee7921..88e5208369e40bdeebc6f758e89= f836a97790d89 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -148,9 +148,10 @@ unsafe fn container_of(ptr: *const T) -> NonNull> { let refcount_layout =3D Layout::new::(); // SAFETY: The caller guarantees that the pointer is valid. let val_layout =3D Layout::for_value(unsafe { &*ptr }); + let val_offset =3D refcount_layout.extend(val_layout); // SAFETY: We're computing the layout of a real struct that existe= d when compiling this // binary, so its layout is not so large that it can trigger arith= metic overflow. - let val_offset =3D unsafe { refcount_layout.extend(val_layout).unw= rap_unchecked().1 }; + let (_, val_offset) =3D unsafe { val_offset.unwrap_unchecked() }; =20 // Pointer casts leave the metadata unchanged. This is okay becaus= e the metadata of `T` and // `ArcInner` is the same since `ArcInner` is a struct with `T`= as its last field. @@ -164,9 +165,10 @@ unsafe fn container_of(ptr: *const T) -> NonNull> { // still valid. let ptr =3D unsafe { ptr.byte_sub(val_offset) }; =20 + let ptr =3D ptr.cast_mut(); // SAFETY: The pointer can't be null since you can't have an `ArcI= nner` value at the null // address. - unsafe { NonNull::new_unchecked(ptr.cast_mut()) } + unsafe { NonNull::new_unchecked(ptr) } } } =20 @@ -201,10 +203,11 @@ pub fn new(contents: T, flags: Flags) -> Result { }; =20 let inner =3D KBox::new(value, flags)?; + let inner =3D KBox::leak(inner).into(); =20 // SAFETY: We just created `inner` with a reference count of 1, wh= ich is owned by the new // `Arc` object. - Ok(unsafe { Self::from_inner(KBox::leak(inner).into()) }) + Ok(unsafe { Self::from_inner(inner) }) } } =20 @@ -333,13 +336,15 @@ impl ForeignOwnable for Arc { type Borrowed<'a> =3D ArcBorrow<'a, T>; =20 fn into_foreign(self) -> *const core::ffi::c_void { - ManuallyDrop::new(self).ptr.as_ptr() as _ + ManuallyDrop::new(self).ptr.as_ptr().cast_const().cast() } =20 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T= > { + let ptr =3D ptr.cast_mut().cast(); + // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. - let inner =3D unsafe { NonNull::new_unchecked(ptr as _) }; + let inner =3D unsafe { NonNull::new_unchecked(ptr) }; =20 // SAFETY: The safety requirements of `from_foreign` ensure that t= he object remains alive // for the lifetime of the returned value. @@ -347,9 +352,11 @@ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) ->= ArcBorrow<'a, T> { } =20 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { + let ptr =3D ptr.cast_mut().cast(); + // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. - let inner =3D unsafe { NonNull::new_unchecked(ptr as _) }; + let inner =3D unsafe { NonNull::new_unchecked(ptr) }; =20 // SAFETY: By the safety requirement of this function, we know tha= t `ptr` came from // a previous call to `Arc::into_foreign`, which guarantees that `= ptr` is valid and @@ -376,10 +383,14 @@ fn as_ref(&self) -> &T { =20 impl Clone for Arc { fn clone(&self) -> Self { + // SAFETY: By the type invariant, there is necessarily a reference= to the object, so it is + // safe to dereference it. + let refcount =3D unsafe { self.ptr.as_ref() }.refcount.get(); + // INVARIANT: C `refcount_inc` saturates the refcount, so it canno= t overflow to zero. // SAFETY: By the type invariant, there is necessarily a reference= to the object, so it is // safe to increment the refcount. - unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) = }; + unsafe { bindings::refcount_inc(refcount) }; =20 // SAFETY: We just incremented the refcount. This increment is now= owned by the new `Arc`. unsafe { Self::from_inner(self.ptr) } @@ -399,10 +410,11 @@ fn drop(&mut self) { // SAFETY: Also by the type invariant, we are allowed to decrement= the refcount. let is_zero =3D unsafe { bindings::refcount_dec_and_test(refcount)= }; if is_zero { + let ptr =3D self.ptr.as_ptr(); // The count reached zero, we must free the memory. // // SAFETY: The pointer was initialised from the result of `KBo= x::leak`. - unsafe { drop(KBox::from_raw(self.ptr.as_ptr())) }; + unsafe { drop(KBox::from_raw(ptr)) }; } } } @@ -550,7 +562,7 @@ impl Deref for ArcBorrow<'_, T> { fn deref(&self) -> &Self::Target { // SAFETY: By the type invariant, the underlying object is still a= live with no mutable // references to it, so it is safe to create a shared reference. - unsafe { &self.inner.as_ref().data } + &unsafe { self.inner.as_ref() }.data } } =20 @@ -652,11 +664,11 @@ pub fn new_uninit(flags: Flags) -> Result>, AllocError> }? AllocError), flags, )?; - Ok(UniqueArc { - // INVARIANT: The newly-created object has a refcount of 1. - // SAFETY: The pointer from the `KBox` is valid. - inner: unsafe { Arc::from_inner(KBox::leak(inner).into()) }, - }) + let inner =3D KBox::leak(inner).into(); + // INVARIANT: The newly-created object has a refcount of 1. + // SAFETY: The pointer from the `KBox` is valid. + let inner =3D unsafe { Arc::from_inner(inner) }; + Ok(UniqueArc { inner }) } } =20 @@ -675,18 +687,18 @@ pub fn write(mut self, value: T) -> UniqueArc { /// The caller guarantees that the value behind this pointer has been = initialized. It is /// *immediate* UB to call this when the value is not initialized. pub unsafe fn assume_init(self) -> UniqueArc { - let inner =3D ManuallyDrop::new(self).inner.ptr; - UniqueArc { - // SAFETY: The new `Arc` is taking over `ptr` from `self.inner= ` (which won't be - // dropped). The types are compatible because `MaybeUninit`= is compatible with `T`. - inner: unsafe { Arc::from_inner(inner.cast()) }, - } + let inner =3D ManuallyDrop::new(self).inner.ptr.cast(); + // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (w= hich won't be + // dropped). The types are compatible because `MaybeUninit` is = compatible with `T`. + let inner =3D unsafe { Arc::from_inner(inner) }; + UniqueArc { inner } } =20 /// Initialize `self` using the given initializer. pub fn init_with(mut self, init: impl Init) -> core::result::= Result, E> { + let ptr =3D self.as_mut_ptr(); // SAFETY: The supplied pointer is valid for initialization. - match unsafe { init.__init(self.as_mut_ptr()) } { + match unsafe { init.__init(ptr) } { // SAFETY: Initialization completed successfully. Ok(()) =3D> Ok(unsafe { self.assume_init() }), Err(err) =3D> Err(err), @@ -698,9 +710,10 @@ pub fn pin_init_with( mut self, init: impl PinInit, ) -> core::result::Result>, E> { + let ptr =3D self.as_mut_ptr(); // SAFETY: The supplied pointer is valid for initialization and we= will later pin the value // to ensure it does not move. - match unsafe { init.__pinned_init(self.as_mut_ptr()) } { + match unsafe { init.__pinned_init(ptr) } { // SAFETY: Initialization completed successfully. Ok(()) =3D> Ok(unsafe { self.assume_init() }.into()), Err(err) =3D> Err(err), @@ -729,7 +742,7 @@ fn deref_mut(&mut self) -> &mut Self::Target { // SAFETY: By the `Arc` type invariant, there is necessarily a ref= erence to the object, so // it is safe to dereference it. Additionally, we know there is on= ly one reference when // it's inside a `UniqueArc`, so it is safe to get a mutable refer= ence. - unsafe { &mut self.inner.ptr.as_mut().data } + &mut unsafe { self.inner.ptr.as_mut() }.data } } =20 diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index fae80814fa1c5e0f11933f2f15e173f0e3a10fe0..e8b7ff1387381e50d7963978e57= b1d567113b035 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -418,7 +418,7 @@ pub unsafe fn from_raw(ptr: NonNull) -> Self { /// } /// /// let mut data =3D Empty {}; - /// let ptr =3D NonNull::::new(&mut data as *mut _).unwrap(); + /// let ptr =3D NonNull::new(&mut data).unwrap(); /// # // SAFETY: TODO. /// let data_ref: ARef =3D unsafe { ARef::from_raw(ptr) }; /// let raw_ptr: NonNull =3D ARef::into_raw(data_ref); @@ -450,8 +450,9 @@ fn deref(&self) -> &Self::Target { impl From<&T> for ARef { fn from(b: &T) -> Self { b.inc_ref(); + let b =3D b.into(); // SAFETY: We just incremented the refcount above. - unsafe { Self::from_raw(NonNull::from(b)) } + unsafe { Self::from_raw(b) } } } =20 --=20 2.47.0 From nobody Mon Nov 25 02:56:23 2024 Received: from mail-yb1-f178.google.com (mail-yb1-f178.google.com [209.85.219.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41A3C2144D2; Wed, 30 Oct 2024 20:46:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321209; cv=none; b=GrxNBZPE5lRN8As2vuwiuqaSKA051G/ILzXZSToeX1yVR+z543jYIaGBfd2dnDDg3dwjmKvNq/zXdmjNLiZ61pDGRddT4dj5lqMtDJbS18HelkQ+bFWm3gbCnVUz05ZznZGCweEtDeLMCUxBXvc+oKA4NVTPigRcNYW6L2wiLGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321209; c=relaxed/simple; bh=hvuWPVRqVlPtD8nPkq5Vb1LUrXDT7nZ05O5Oxu7e2Rc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qHIR6BskeVmK1ZLXXSxtImMLGMi603S+QBgr4KP3Cr9zxGOQAedtNDKvXM5G/0pl4/aA5rsHP+hjAHf06NAyI1Az2FLVKJ5Q8GHh2rqzDTqdnWy03oEoWduitLRwhgeCC6gbTfbFCiFNW3zWoZVYLn2EB9tElwMFVyO79NdOxzQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Gwh2f+iA; arc=none smtp.client-ip=209.85.219.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Gwh2f+iA" Received: by mail-yb1-f178.google.com with SMTP id 3f1490d57ef6-e29327636f3so222877276.2; Wed, 30 Oct 2024 13:46:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730321206; x=1730926006; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=yLP3yKC2elkPQbresABA6wHHmwAcQqYBo0U0H5HudtA=; b=Gwh2f+iAVpXCwCdUQJzlF1bGYeS7T3gCuPOsAL3ZfkPtMvjTf7byz5Y1tjdRx6accG 3kHutHeda/DS91ssY5QZewFFofWoADazOSgNpGbSsDKgIM0G6gY+DPCh+rsok0uClEmZ nL3per8V92wECPNawXTOTaIH4U5YHECC9/vA16cyTyIyZjxtVbXpidRHZUj/I72FNvf8 pje+CHiTRb1FDqc+ZybAKJSwb42zs3NIKdRE17sXNyWbobAL72lrSMR3tDDcg6sysDSp JVUqRjnSwLY0e8c5Rcly0q//ZP9kcONNuGiBjrgIGPon5tHF55dDnEnlS2sj0jcH7ZaP nC1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730321206; x=1730926006; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yLP3yKC2elkPQbresABA6wHHmwAcQqYBo0U0H5HudtA=; b=KlF19RZrH5ChVwA7hWIUmUl99TTnbaP/5j4I/0dkq+wROL2h12hzAbtyCLF9maxIri iNRvsJUHtkTKIH5BRyTiZDFowg0Cs8H6mzQufoJ1n2y+Jp7SBMMevUReeJDK6pzpTjoG ZtzLIfq9ScWrJ8sxIMTu5gH2ew0/TMiHNApQbLzJB7xtJfB3JBAyDEJSpgev0sdnZP4a d7bhM9pyDN+Ip/rrPTf+ZrqflSUyh6T0THII0YbXG/ZxveZHuDwM0c5Dj27+tEYstA8L AB6x1AEdKBY7/t4m6HuVRds5e3Yd2lHh6p84KXWTU6u/ejCVkYjNo9AwBDYF7dfG+qOh by1g== X-Forwarded-Encrypted: i=1; AJvYcCVFd3JodfdLO5gyQj6uRQvVaAl69U1l3ImIaTnRUOgJeDF/YC94mwHyE1yo+z6pVszjtLbaBrk4PUn3d+s=@vger.kernel.org X-Gm-Message-State: AOJu0YyGZ2GJCMRNDvYh76tkjgYO39wxF1SGYPLHQWk3dsCQ64H6HenR AmGiuVzTnisZrR3igt79JKeYvf2UtbtNMZ0tJ6QqiiPn4gnDW9Ea X-Google-Smtp-Source: AGHT+IGJvG3gvz7B9T41YC2jyrLqjDlrmL2TjvZXL4lEoS2RA0zIvcRJ3ohTHjxivn0FR4KyK6kbkw== X-Received: by 2002:a05:6902:188c:b0:e30:df1f:8926 with SMTP id 3f1490d57ef6-e30df1f8ac1mr2407788276.12.1730321206083; Wed, 30 Oct 2024 13:46:46 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([2620:10d:c091:600::1:89dc]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-462ad0c72efsm271271cf.50.2024.10.30.13.46.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Oct 2024 13:46:44 -0700 (PDT) From: Tamir Duberstein Date: Wed, 30 Oct 2024 16:46:40 -0400 Subject: [PATCH 3/5] rust: change `ForeignOwnable` pointer to mut Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241030-borrow-mut-v1-3-8f0ceaf78eaf@gmail.com> References: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> In-Reply-To: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Tamir Duberstein X-Mailer: b4 0.15-dev It is slightly more convenient to operate on mut pointers, and this also properly conveys the desired ownership semantics of the trait. Signed-off-by: Tamir Duberstein Reviewed-by: Alice Ryhl Reviewed-by: Andreas Hindborg --- rust/kernel/alloc/kbox.rs | 22 ++++++++++------------ rust/kernel/sync/arc.rs | 12 ++++++------ rust/kernel/types.rs | 14 +++++++------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index 7a5fdf7b660fb91ca2a8e5023d69d629b0d66062..de7fadeb7fdf5cf6742c2e9749e= 959ac5f82359e 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -355,18 +355,18 @@ impl ForeignOwnable for Box { type Borrowed<'a> =3D &'a T; =20 - fn into_foreign(self) -> *const core::ffi::c_void { - Box::into_raw(self).cast_const().cast() + fn into_foreign(self) -> *mut core::ffi::c_void { + Box::into_raw(self).cast() } =20 - unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { - let ptr =3D ptr.cast_mut().cast(); + unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self { + let ptr =3D ptr.cast(); // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. unsafe { Box::from_raw(ptr) } } =20 - unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> &'a T { let ptr =3D ptr.cast(); // SAFETY: The safety requirements of this method ensure that the = object remains alive and // immutable for the duration of 'a. @@ -380,21 +380,19 @@ impl ForeignOwnable for Pin> { type Borrowed<'a> =3D Pin<&'a T>; =20 - fn into_foreign(self) -> *const core::ffi::c_void { + fn into_foreign(self) -> *mut core::ffi::c_void { // SAFETY: We are still treating the box as pinned. - Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) - .cast_const() - .cast() + Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() } =20 - unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { - let ptr =3D ptr.cast_mut().cast(); + unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self { + let ptr =3D ptr.cast(); // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. unsafe { Pin::new_unchecked(Box::from_raw(ptr)) } } =20 - unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> Pin<&'a T> { let ptr =3D ptr.cast(); // SAFETY: The safety requirements for this function ensure that t= he object is still alive, // so it is safe to dereference the raw pointer. diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 88e5208369e40bdeebc6f758e89f836a97790d89..26b7272424aafdd4847d9642456= cab837797ac33 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -335,12 +335,12 @@ pub fn into_unique_or_drop(self) -> Option>> { impl ForeignOwnable for Arc { type Borrowed<'a> =3D ArcBorrow<'a, T>; =20 - fn into_foreign(self) -> *const core::ffi::c_void { - ManuallyDrop::new(self).ptr.as_ptr().cast_const().cast() + fn into_foreign(self) -> *mut core::ffi::c_void { + ManuallyDrop::new(self).ptr.as_ptr().cast() } =20 - unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T= > { - let ptr =3D ptr.cast_mut().cast(); + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> { + let ptr =3D ptr.cast(); =20 // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. @@ -351,8 +351,8 @@ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> = ArcBorrow<'a, T> { unsafe { ArcBorrow::new(inner) } } =20 - unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { - let ptr =3D ptr.cast_mut().cast(); + unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self { + let ptr =3D ptr.cast(); =20 // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index e8b7ff1387381e50d7963978e57b1d567113b035..04358375794dc5ba7bfebbe3cfc= 5885cff531f15 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -29,7 +29,7 @@ pub trait ForeignOwnable: Sized { /// For example, it might be invalid, dangling or pointing to uninitia= lized memory. Using it in /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwna= ble::borrow`], /// [`ForeignOwnable::try_from_foreign`] can result in undefined behav= ior. - fn into_foreign(self) -> *const core::ffi::c_void; + fn into_foreign(self) -> *mut core::ffi::c_void; =20 /// Borrows a foreign-owned object. /// @@ -37,7 +37,7 @@ pub trait ForeignOwnable: Sized { /// /// `ptr` must have been returned by a previous call to [`ForeignOwnab= le::into_foreign`] for /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. - unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<= 'a>; + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> Self::Borrowed<'a= >; =20 /// Converts a foreign-owned object back to a Rust-owned one. /// @@ -47,7 +47,7 @@ pub trait ForeignOwnable: Sized { /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. /// Additionally, all instances (if any) of values returned by [`Forei= gnOwnable::borrow`] for /// this object must have been dropped. - unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; + unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self; =20 /// Tries to convert a foreign-owned object back to a Rust-owned one. /// @@ -58,7 +58,7 @@ pub trait ForeignOwnable: Sized { /// /// `ptr` must either be null or satisfy the safety requirements for /// [`ForeignOwnable::from_foreign`]. - unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option { + unsafe fn try_from_foreign(ptr: *mut core::ffi::c_void) -> Option { if ptr.is_null() { None } else { @@ -72,13 +72,13 @@ unsafe fn try_from_foreign(ptr: *const core::ffi::c_voi= d) -> Option { impl ForeignOwnable for () { type Borrowed<'a> =3D (); =20 - fn into_foreign(self) -> *const core::ffi::c_void { + fn into_foreign(self) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() } =20 - unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a= > {} + unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> = {} =20 - unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {} + unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {} } =20 /// Runs a cleanup function/closure when dropped. --=20 2.47.0 From nobody Mon Nov 25 02:56:23 2024 Received: from mail-qt1-f171.google.com (mail-qt1-f171.google.com [209.85.160.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07662216423; Wed, 30 Oct 2024 20:46:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321211; cv=none; b=NtqGt9Nx0Cg81l0KRYGSoqEHIwAd7/eMwsPArr+6EBE1nNkYjPIRsi1odQY2u6S5ViRa8RYcC+UftXqa0QKvSFYoX//5jq1NyVj6l0+JufEE73zPVczXKqldkyEbWsd7m4jLZ8U/rqEn0C1xXdcPifSSOLz7XbljTt7fH6akzHE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321211; c=relaxed/simple; bh=0Th+x2IDMOoiPCod6xdhQvrFDyU4PFyE5MtERCpSFyw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S44YLygd/tjdzeTcSDkptFGG4hNO2cD0jBlis6l/9WP9PdlQrZ6lXVqXfP8lmrcgYX8PHQJZqRlMlPstvi0TeR3P+UdbvV5zaDjxgwK/cs8TPHQBHH3yL8hgNosdNCLyOzUH7XI05f4/MRW7hXyM3wRWiYEcClHc0yLuN7/4ooc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PtGSH3HX; arc=none smtp.client-ip=209.85.160.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PtGSH3HX" Received: by mail-qt1-f171.google.com with SMTP id d75a77b69052e-4609c9b39d0so2029071cf.1; Wed, 30 Oct 2024 13:46:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730321208; x=1730926008; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ryl4oucJD5PPaNzWfafNblD5KtXW1k3WEIZKABqwt9Y=; b=PtGSH3HXMn+T2SeDwj/hlZxfTM/MI2YlLo4gekLQ51PRJfjc9pzvdB1tMKCS8Yw0V2 vG1Ak0qpqmKllnddmzB2BVqeMe+2RICbRih685eeBBRgkC1MBNMBgrh6Xz4tGTAXZXft A4FvtGftW6R8LQ3gA58LX40k46kKJZ+TjDQRHcUwhc7sg3I23l+as4Ymd/4KXY4ZUYhE PV0vb5/MPdTBt/enb1ou8Cd/SIZHAwlesXYHZ38ylnp7Ba6zrDV3EsQ/rswqAaIFKhAi M2yk62f5tqx+ibVknGe8YO3UCmBm15Aamh6ME6d246tdihaU7+DdLK+XSuLIJiTukKbT UH+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730321208; x=1730926008; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ryl4oucJD5PPaNzWfafNblD5KtXW1k3WEIZKABqwt9Y=; b=IdaLufrNvxtQNkfbjDGlDVOr+zYqFezQgbxBaL10Pqe56ZZisA6gYg2aXYYEh/JUAG kC4NXiTrbz5PomdPShxuEvcavecHJWB1X5/67fNZKiYEhTHCxVQbHZHdhNYsqpklnrrS hAYX+I4k2G3ICJ9vWplQvOKIVcFxPLA/j56o0uUrfKKSpXgE6qEM7SNZ55HBvTlfNDvE BktZjhW01iTInEICaNSoiXEj7XcHlX/U4yA868yz306KylYT33/y2nA4N68PTko4MEky pPIW0w1vhIi5VBk3P89sHlc+ys+PBTw0OTHAk6Fv4azSIcHY10uGN7BJiSb1dvo1yB3N KmxQ== X-Forwarded-Encrypted: i=1; AJvYcCXKjt1fdVIx0+hJv4rFrA+RGnd4G2Kya7AnDXm2wqYVR15h+bfVuVIorgf0kdX3Mly2KTePYMCOkQWe944=@vger.kernel.org X-Gm-Message-State: AOJu0Ywr0VyiKfnXbc0QSqjQr5rXEFiMLBUxF9KKQRPEWZ5B4I81ur5D tNwUuwEeik3JmKzWjm/BHZ8FnU2CSEGmW0VZqKY6n38SFtDKhRgX X-Google-Smtp-Source: AGHT+IHUvH2uFaNbT0sxzXsGMiq/mHK3axbbueOqnq52zss6gcSnP4GhuLOuojLLomDXgwLNU4P8Ng== X-Received: by 2002:ac8:5a11:0:b0:461:50a1:4e2 with SMTP id d75a77b69052e-462ab308c72mr12615821cf.55.1730321207830; Wed, 30 Oct 2024 13:46:47 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([2620:10d:c091:600::1:89dc]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-462ad0c72efsm271271cf.50.2024.10.30.13.46.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Oct 2024 13:46:47 -0700 (PDT) From: Tamir Duberstein Date: Wed, 30 Oct 2024 16:46:41 -0400 Subject: [PATCH 4/5] rust: reorder `ForeignOwnable` items Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241030-borrow-mut-v1-4-8f0ceaf78eaf@gmail.com> References: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> In-Reply-To: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Tamir Duberstein X-Mailer: b4 0.15-dev `{into,from}_foreign` before `borrow` is slightly more logical. Signed-off-by: Tamir Duberstein --- rust/kernel/sync/arc.rs | 18 +++++++++--------- rust/kernel/types.rs | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 26b7272424aafdd4847d9642456cab837797ac33..4552913c75f747d646bf408c1e8= a1a883afb4b6a 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -339,29 +339,29 @@ fn into_foreign(self) -> *mut core::ffi::c_void { ManuallyDrop::new(self).ptr.as_ptr().cast() } =20 - unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> { + unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self { let ptr =3D ptr.cast(); =20 // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. let inner =3D unsafe { NonNull::new_unchecked(ptr) }; =20 - // SAFETY: The safety requirements of `from_foreign` ensure that t= he object remains alive - // for the lifetime of the returned value. - unsafe { ArcBorrow::new(inner) } + // SAFETY: By the safety requirement of this function, we know tha= t `ptr` came from + // a previous call to `Arc::into_foreign`, which guarantees that `= ptr` is valid and + // holds a reference count increment that is transferrable to us. + unsafe { Self::from_inner(inner) } } =20 - unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self { + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a, T> { let ptr =3D ptr.cast(); =20 // SAFETY: The safety requirements of this function ensure that `p= tr` comes from a previous // call to `Self::into_foreign`. let inner =3D unsafe { NonNull::new_unchecked(ptr) }; =20 - // SAFETY: By the safety requirement of this function, we know tha= t `ptr` came from - // a previous call to `Arc::into_foreign`, which guarantees that `= ptr` is valid and - // holds a reference count increment that is transferrable to us. - unsafe { Self::from_inner(inner) } + // SAFETY: The safety requirements of `from_foreign` ensure that t= he object remains alive + // for the lifetime of the returned value. + unsafe { ArcBorrow::new(inner) } } } =20 diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 04358375794dc5ba7bfebbe3cfc5885cff531f15..b8a7b2ee96a17081ad31e1bb73c= b0513bcd05ef4 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -31,14 +31,6 @@ pub trait ForeignOwnable: Sized { /// [`ForeignOwnable::try_from_foreign`] can result in undefined behav= ior. fn into_foreign(self) -> *mut core::ffi::c_void; =20 - /// Borrows a foreign-owned object. - /// - /// # Safety - /// - /// `ptr` must have been returned by a previous call to [`ForeignOwnab= le::into_foreign`] for - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. - unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> Self::Borrowed<'a= >; - /// Converts a foreign-owned object back to a Rust-owned one. /// /// # Safety @@ -67,6 +59,14 @@ unsafe fn try_from_foreign(ptr: *mut core::ffi::c_void) = -> Option { unsafe { Some(Self::from_foreign(ptr)) } } } + + /// Borrows a foreign-owned object. + /// + /// # Safety + /// + /// `ptr` must have been returned by a previous call to [`ForeignOwnab= le::into_foreign`] for + /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. + unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> Self::Borrowed<'a= >; } =20 impl ForeignOwnable for () { @@ -76,9 +76,9 @@ fn into_foreign(self) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() } =20 - unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> = {} - unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {} + + unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> = {} } =20 /// Runs a cleanup function/closure when dropped. --=20 2.47.0 From nobody Mon Nov 25 02:56:23 2024 Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7FD921764F; Wed, 30 Oct 2024 20:46:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321214; cv=none; b=QtWnu8dmE9L0QK05RTnVGF3NP7/Z/4xjRkjCq8LtRiffGK6xZZBGv/p6nFp/YJWnFdbaMuZPVxJIBj+JiXgr6EJgXAci3pscjQaKIykSFhf3VZWGe+zUOMtU29ps+7W/7FcTcFiHESEkh/UpK7E/ZzWQtMguMKXBT6SvAY4fpgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730321214; c=relaxed/simple; bh=W4MnTSRZDNO9E61wQewB+RTJNY8Ad1FjU0v7XnbB2GA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JYb44oVrjQFKZq7enm0U3WWJ79bfbbVGORafj4OTQs4ENb5oNNSlFWRqu7UZGL5d3iZQL43q86T2f7DeDlYfYpx7Es3TOZylcuSCoNayJpcHYTIg9MNwhh71euRGPSHOJsYoIhmRNykTvOf6tcQFjHKhE28CJMPW3vfi9g8/SSs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YIewImVw; arc=none smtp.client-ip=209.85.160.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YIewImVw" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-4609beb631aso1971071cf.2; Wed, 30 Oct 2024 13:46:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730321211; x=1730926011; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=D7EQG/Q6VbC722wpvCuI4LW8lAPiBh2mzpjGaHeNXNA=; b=YIewImVwwMh48QcsWhAj2MxG3RBA7laoDyVeRZf2QtglobplOUM+WJn0AVq43lnqoA suRBseXnloCFxIC4Pv6S3OOD0RSYu7cSAf6SlN5vlCYjEUIBUDUxq4bYByj2hYN6nWqm Cb3XqebVZEoCq3CuJsJcVeSqVhIPzz/evD3kK8ceJJvK2XwsKNW4R2ICVTk0VkwCu46k jjQsYI1emV+JT8jNhDUhDf7H7f23wHShtOCVl4NlhEjnLHu56SDpVabX1zVjdS+pCMVJ xND6gRQts/be0lhr5T4TuwtH58gv8r6KsjKTofasqSc7Ihvao6KGF9t10bYjLBGkcX4r w4eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730321211; x=1730926011; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D7EQG/Q6VbC722wpvCuI4LW8lAPiBh2mzpjGaHeNXNA=; b=EVbvCfKIrVX68gUIlTRQtuUqqbdvhbuD8Z+OeP9eqV01w0p4byVS9X5+YNWwIce3H6 LxfJbI9ed6ZAdp5OTlqYkMj1ZYfXjKFELJYrcjuLQO9UqhQPPKzrpoxpBN3ec5xLVmuH 9/ecFVjNRwaGfT322sp/FiccrlAH4ZHa6zX2LTg0xE+8JKh/NXdYgXfxW8A3imMR9EJ1 QH0a833BwZ/JsrCZBTPKznEV7eVyoSCqJWHd4+lnpO5JOSVWnNA6RoUV2GoJi3LFj6jv mGoP1LZ7reA5GhjUDAi2Hm4b6gewZNsfiHqh/nRhcN9xRxp/TcN/I0XepL+5K6eceAXo ZoOg== X-Forwarded-Encrypted: i=1; AJvYcCXF/PQyuJrTh++qvZdU7/Ub8a1UadBQpg3fkK91y7WJqwbYBCy56Y+zsAm0cx+1Q1yMFyQbZjaVBCBgrwM=@vger.kernel.org X-Gm-Message-State: AOJu0YwnLd+Ic6iKHyD/xrS1Q9GbhINybaZDrlO4aFLzhLGudmUAMz3u xQUlMAOor+RHdg3LyZpF69amn7ZHFJIM1rCnteSRJjGfEPsc+sle X-Google-Smtp-Source: AGHT+IHmc4EhWRojtL4gb+xI0AsEzjyGtJ4Yf30hx5KKYzliFhLnMGO2r8R7H0l9WI0/7zYE5exRbg== X-Received: by 2002:ac8:584f:0:b0:460:a730:3176 with SMTP id d75a77b69052e-4613bfb6ce8mr260600811cf.11.1730321210672; Wed, 30 Oct 2024 13:46:50 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([2620:10d:c091:600::1:89dc]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-462ad0c72efsm271271cf.50.2024.10.30.13.46.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Oct 2024 13:46:49 -0700 (PDT) From: Tamir Duberstein Date: Wed, 30 Oct 2024 16:46:42 -0400 Subject: [PATCH 5/5] rust: add improved version of `ForeignOwnable::borrow_mut` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241030-borrow-mut-v1-5-8f0ceaf78eaf@gmail.com> References: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> In-Reply-To: <20241030-borrow-mut-v1-0-8f0ceaf78eaf@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Tamir Duberstein , Martin Rodriguez Reboredo X-Mailer: b4 0.15-dev From: Alice Ryhl Previously, the `ForeignOwnable` trait had a method called `borrow_mut` that was intended to provide mutable access to the inner value. However, the method accidentally made it possible to change the address of the object being modified, which usually isn't what we want. (And when we want that, it can be done by calling `from_foreign` and `into_foreign`, like how the old `borrow_mut` was implemented.) In this patch, we introduce an alternate definition of `borrow_mut` that solves the previous problem. Conceptually, given a pointer type `P` that implements `ForeignOwnable`, the `borrow_mut` method gives you the same kind of access as an `&mut P` would, except that it does not let you change the pointer `P` itself. This is analogous to how the existing `borrow` method provides the same kind of access to the inner value as an `&P`. Note that for types like `Arc`, having an `&mut Arc` only gives you immutable access to the inner `T`. This is because mutable references assume exclusive access, but there might be other handles to the same reference counted value, so the access isn't exclusive. The `Arc` type implements this by making `borrow_mut` return the same type as `borrow`. Signed-off-by: Alice Ryhl Reviewed-by: Boqun Feng Reviewed-by: Benno Lossin Reviewed-by: Martin Rodriguez Reboredo Reviewed-by: Andreas Hindborg --- Source: https://lore.kernel.org/all/20230710074642.683831-1-aliceryhl@googl= e.com/ --- rust/kernel/alloc/kbox.rs | 21 ++++++++++++++ rust/kernel/sync/arc.rs | 7 +++++ rust/kernel/types.rs | 71 ++++++++++++++++++++++++++++++++++++++-----= ---- 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs index de7fadeb7fdf5cf6742c2e9749e959ac5f82359e..6ae81d4f74e9f7cf228385490f3= a065082c1f4f6 100644 --- a/rust/kernel/alloc/kbox.rs +++ b/rust/kernel/alloc/kbox.rs @@ -354,6 +354,7 @@ impl ForeignOwnable for Box A: Allocator, { type Borrowed<'a> =3D &'a T; + type BorrowedMut<'a> =3D &'a mut T; =20 fn into_foreign(self) -> *mut core::ffi::c_void { Box::into_raw(self).cast() @@ -372,6 +373,13 @@ unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> &= 'a T { // immutable for the duration of 'a. unsafe { &*ptr } } + + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> &'a mut T { + let ptr =3D ptr.cast(); + // SAFETY: The safety requirements of this method ensure that the = pointer is valid and that + // nothing else will access the value for the duration of 'a. + unsafe { &mut *ptr } + } } =20 impl ForeignOwnable for Pin> @@ -379,6 +387,7 @@ impl ForeignOwnable for Pin> A: Allocator, { type Borrowed<'a> =3D Pin<&'a T>; + type BorrowedMut<'a> =3D Pin<&'a mut T>; =20 fn into_foreign(self) -> *mut core::ffi::c_void { // SAFETY: We are still treating the box as pinned. @@ -403,6 +412,18 @@ unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> P= in<&'a T> { // SAFETY: This pointer originates from a `Pin>`. unsafe { Pin::new_unchecked(r) } } + + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> Pin<&'a mut T= > { + let ptr =3D ptr.cast(); + // SAFETY: The safety requirements for this function ensure that t= he object is still alive, + // so it is safe to dereference the raw pointer. + // The safety requirements of `from_foreign` also ensure that the = object remains alive for + // the lifetime of the returned value. + let r =3D unsafe { &mut *ptr }; + + // SAFETY: This pointer originates from a `Pin>`. + unsafe { Pin::new_unchecked(r) } + } } =20 impl Deref for Box diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 4552913c75f747d646bf408c1e8a1a883afb4b6a..8b21197ceba3508bcac6f1b54d7= 3244d9bdfd5a7 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -334,6 +334,7 @@ pub fn into_unique_or_drop(self) -> Option>> { =20 impl ForeignOwnable for Arc { type Borrowed<'a> =3D ArcBorrow<'a, T>; + type BorrowedMut<'a> =3D Self::Borrowed<'a>; =20 fn into_foreign(self) -> *mut core::ffi::c_void { ManuallyDrop::new(self).ptr.as_ptr().cast() @@ -363,6 +364,12 @@ unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> A= rcBorrow<'a, T> { // for the lifetime of the returned value. unsafe { ArcBorrow::new(inner) } } + + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> ArcBorrow<'a,= T> { + // SAFETY: The safety requirements for `borrow_mut` are a superset= of the safety + // requirements for `borrow`. + unsafe { Self::borrow(ptr) } + } } =20 impl Deref for Arc { diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index b8a7b2ee96a17081ad31e1bb73cb0513bcd05ef4..d742544da793a08eaf342ba8872= 2dfb1319b93d6 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -19,26 +19,33 @@ /// This trait is meant to be used in cases when Rust objects are stored i= n C objects and /// eventually "freed" back to Rust. pub trait ForeignOwnable: Sized { - /// Type of values borrowed between calls to [`ForeignOwnable::into_fo= reign`] and - /// [`ForeignOwnable::from_foreign`]. + /// Type used to immutably borrow a value that is currently foreign-ow= ned. type Borrowed<'a>; =20 + /// Type used to mutably borrow a value that is currently foreign-owne= d. + type BorrowedMut<'a>; + /// Converts a Rust-owned object to a foreign-owned one. /// /// The foreign representation is a pointer to void. There are no guar= antees for this pointer. /// For example, it might be invalid, dangling or pointing to uninitia= lized memory. Using it in - /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwna= ble::borrow`], - /// [`ForeignOwnable::try_from_foreign`] can result in undefined behav= ior. + /// any way except for [`from_foreign`], [`try_from_foreign`], [`borro= w`], or [`borrow_mut`] can + /// result in undefined behavior. + /// + /// [`from_foreign`]: Self::from_foreign + /// [`try_from_foreign`]: Self::try_from_foreign + /// [`borrow`]: Self::borrow + /// [`borrow_mut`]: Self::borrow_mut fn into_foreign(self) -> *mut core::ffi::c_void; =20 /// Converts a foreign-owned object back to a Rust-owned one. /// /// # Safety /// - /// `ptr` must have been returned by a previous call to [`ForeignOwnab= le::into_foreign`] for - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. - /// Additionally, all instances (if any) of values returned by [`Forei= gnOwnable::borrow`] for - /// this object must have been dropped. + /// The provided pointer must have been returned by a previous call to= [`into_foreign`], and it + /// must not be passed to `from_foreign` more than once. + /// + /// [`into_foreign`]: Self::into_foreign unsafe fn from_foreign(ptr: *mut core::ffi::c_void) -> Self; =20 /// Tries to convert a foreign-owned object back to a Rust-owned one. @@ -48,8 +55,9 @@ pub trait ForeignOwnable: Sized { /// /// # Safety /// - /// `ptr` must either be null or satisfy the safety requirements for - /// [`ForeignOwnable::from_foreign`]. + /// `ptr` must either be null or satisfy the safety requirements for [= `from_foreign`]. + /// + /// [`from_foreign`]: Self::from_foreign unsafe fn try_from_foreign(ptr: *mut core::ffi::c_void) -> Option { if ptr.is_null() { None @@ -60,17 +68,53 @@ unsafe fn try_from_foreign(ptr: *mut core::ffi::c_void)= -> Option { } } =20 - /// Borrows a foreign-owned object. + /// Borrows a foreign-owned object immutably. + /// + /// This method provides a way to access a foreign-owned value from Ru= st immutably. It provides + /// you with exactly the same abilities as an `&Self` when the value i= s Rust-owned. /// /// # Safety /// - /// `ptr` must have been returned by a previous call to [`ForeignOwnab= le::into_foreign`] for - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't = been called yet. + /// The provided pointer must have been returned by a previous call to= [`into_foreign`], and if + /// the pointer is ever passed to [`from_foreign`], then that call mus= t happen after the end of + /// the lifetime 'a. + /// + /// [`into_foreign`]: Self::into_foreign + /// [`from_foreign`]: Self::from_foreign unsafe fn borrow<'a>(ptr: *mut core::ffi::c_void) -> Self::Borrowed<'a= >; + + /// Borrows a foreign-owned object mutably. + /// + /// This method provides a way to access a foreign-owned value from Ru= st mutably. It provides + /// you with exactly the same abilities as an `&mut Self` when the val= ue is Rust-owned, except + /// that the address of the object must not be changed. + /// + /// Note that for types like [`Arc`], an `&mut Arc` only gives you = immutable access to the + /// inner value, so this method also only provides immutable access in= that case. + /// + /// In the case of `Box`, this method gives you the ability to modi= fy the inner `T`, but it + /// does not let you change the box itself. That is, you cannot change= which allocation the box + /// points at. + /// + /// # Safety + /// + /// The provided pointer must have been returned by a previous call to= [`into_foreign`], and if + /// the pointer is ever passed to [`from_foreign`], then that call mus= t happen after the end of + /// the lifetime 'a. + /// + /// The lifetime 'a must not overlap with the lifetime of any other ca= ll to [`borrow`] or + /// `borrow_mut` on the same object. + /// + /// [`into_foreign`]: Self::into_foreign + /// [`from_foreign`]: Self::from_foreign + /// [`borrow`]: Self::borrow + /// [`Arc`]: crate::sync::Arc + unsafe fn borrow_mut<'a>(ptr: *mut core::ffi::c_void) -> Self::Borrowe= dMut<'a>; } =20 impl ForeignOwnable for () { type Borrowed<'a> =3D (); + type BorrowedMut<'a> =3D (); =20 fn into_foreign(self) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() @@ -79,6 +123,7 @@ fn into_foreign(self) -> *mut core::ffi::c_void { unsafe fn from_foreign(_: *mut core::ffi::c_void) -> Self {} =20 unsafe fn borrow<'a>(_: *mut core::ffi::c_void) -> Self::Borrowed<'a> = {} + unsafe fn borrow_mut<'a>(_: *mut core::ffi::c_void) -> Self::BorrowedM= ut<'a> {} } =20 /// Runs a cleanup function/closure when dropped. --=20 2.47.0