From nobody Tue Nov 26 01:32:47 2024 Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) (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 1E5431CDFCF; Tue, 22 Oct 2024 22:49:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637354; cv=none; b=ODrE9eQ7IK5Cl3TIFc+YMyQbVDU0VpCCpTb5zlDPS4kdSt+XwmVcL1HHFlXoKvOcRN/QUL6oC4uLM6nYAaMld5MsVuIqxJLvasTnfrnvYLp3OE9TOdy6RCS7X3a1r0Y1Eaw/kHv/EUemileaP1Yylfg0K0OjOITS6m7pFvASyPI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637354; c=relaxed/simple; bh=dhg9Ow1q/Pu067jCJtPo7EpABRZtIgMCRV8vgtJBB7U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TxCGz1C+4/Ku53yLKfFWnV8/3+n1ff8ywlfcTw8edU0zTui1R90yulToQc2MeWteRK4kjJHS6cmYOUstKxCIaqmgTzzJI+1iV76mylPXHdWhOZ+OPE/4t6vQcRBURaZI2J3OuGkmtfoPdmVii9X1sYi/KmtTYBCCqLldLxn0n8E= 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=Yyl/rWM/; arc=none smtp.client-ip=209.85.167.46 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="Yyl/rWM/" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-53b13ea6b78so2169424e87.2; Tue, 22 Oct 2024 15:49:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729637351; x=1730242151; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=z8Uz8SZaQ3TwhW3QvRSUwgmeCqFgrOwfQIdlwehb+ho=; b=Yyl/rWM/AE03J8uK2jKyPgdtnIAkKsgu/471f98TGZp1P50/Y0p/iwl16ExUz4v+CT aYewr47u5iqpc/mzN/UzFa1OLoM+1HcVQXqzQ8fDFGEi4lruG709oiHDiaMj2ZWvJaCh ZXWbCClTbYp0B/OZrdC2Dn6/APTxo+/AQgWnsUihEgr1aOKaXC6CM0S8rX548Bk76B/r tOM7J5D31GwVbEQwAkzVLxM4q6Axla5KUa3p4Jp5tqbA8Czj7/Lf55mNfmdriAz2owz9 0oz8Psa+OpRp6KacBHkSTpApDX2osqXcExVOOQp7i1NZfz100JH2EWf9PfArHE7XTAPE Bm8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729637351; x=1730242151; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=z8Uz8SZaQ3TwhW3QvRSUwgmeCqFgrOwfQIdlwehb+ho=; b=QQ0GZj260cE4wUgBF0hrhBogAkevZhI0UPbyAaX7nQ8pP3NT/Qj7J7qF8Dlk4D+Mg4 FE6U2v07JOrlWVBt6oyEYsNN3lrMyPtLWph5GQOfCN6qy2jMkKT0CC4WnINfDIma/Nl8 mVgw0sxvGpBH7iHORU9X3bkiRKUMMOBlIOX1SydSJkK+JZXy4byn8z7wrhFmEsaC1ibo xTmPKWgyv+NbBxB+MOl611ouFA9IToBkZfvUHO6Sdoh1HobjyZRUtK8HzwfAdGL0Lzvi 417sGlpiS6JuRCCknYgdiBNalmvLSBjJ1bV65GgOREdVygjHnwqxZBX38CtvteuuFyiw 17Vg== X-Forwarded-Encrypted: i=1; AJvYcCUVmb/wd+16Lqz0gfoEGZOBvp6gUgtifGJmeEad0pFZfK0K88Fog/s5iIhS1ReXHguOUlT0ICJOJf274QA=@vger.kernel.org X-Gm-Message-State: AOJu0Yx5ueqPC8GlhJjN/pURjS+60Z10eRd1yn6Zka2J1bc5bSICsR7d /R1DwBrlpkQieAQfkx6n1ndDHINV3UrGRTw7O2WjZaJvgZGiPBrrd3KXig== X-Google-Smtp-Source: AGHT+IGaAsE2puMxpOq6QjnrGfOr66sCudnSRqP0Ob/HSYOC5DnqO/Cugp5izgNkTM2hBviumT0CEA== X-Received: by 2002:a05:6512:23aa:b0:539:8cd1:848 with SMTP id 2adb3069b0e04-53b1a3bae89mr285858e87.61.1729637351019; Tue, 22 Oct 2024 15:49:11 -0700 (PDT) Received: from abj-NUC9VXQNX.. (87-94-132-183.rev.dnainternet.fi. [87.94.132.183]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53a223e595csm894881e87.14.2024.10.22.15.49.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2024 15:49:09 -0700 (PDT) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, aliceryhl@google.com Cc: dakr@redhat.com, linux-kernel@vger.kernel.org, airlied@redhat.com, miguel.ojeda.sandonis@gmail.com, boqun.feng@gmail.com, Abdiel Janulgue Subject: [PATCH v2 1/5] rust: types: add `Owned` type and `Ownable` trait Date: Wed, 23 Oct 2024 01:44:45 +0300 Message-ID: <20241022224832.1505432-2-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> References: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the 'Owned' type, a simple smart pointer type that owns the underlying data. An object implementing `Ownable' can constructed by wrapping it in `Owned`, which has the advantage of allowing fine-grained control over it's resource allocation and deallocation. Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Signed-off-by: Abdiel Janulgue --- rust/kernel/types.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index ced143600eb1..3f632916bd4d 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -429,3 +429,65 @@ pub enum Either { /// Constructs an instance of [`Either`] containing a value of type `R= `. Right(R), } + +/// A smart pointer that owns the underlying data `T`. +/// +/// This is a simple smart pointer that owns the underlying data. Typicall= y, this would be +/// returned as a wrapper for `T` in `T`'s constructor. +/// When an object adds an option of being constructed this way, in additi= on to implementing +/// `Drop`, it implements `Ownable` as well, thus having finer-grained con= trol in where +/// resource allocation and deallocation happens. +/// +/// # Invariants +/// +/// The pointer is always valid and owns the underlying data. +pub struct Owned { + ptr: NonNull, +} + +impl Owned { + /// Creates a new smart pointer that owns `T`. + /// + /// # Safety + /// `ptr` needs to be a valid pointer, and it should be the unique own= er to the object, + /// in other words, no other entity should free the underlying data. + pub unsafe fn to_owned(ptr: *mut T) -> Self { + // SAFETY: Per function safety requirement. + Self { ptr: unsafe { NonNull::new_unchecked(ptr) } } + } +} + +impl Deref for Owned { + type Target =3D T; + + fn deref(&self) -> &Self::Target { + // SAFETY: By the type invariant, there is necessarily a reference= to the object, so it is + // safe to dereference it. + unsafe { self.ptr.as_ref() } + } +} + +impl DerefMut for Owned { + fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: By the type invariant, there is necessarily a reference= to the object, so it is + // safe to dereference it. + unsafe { self.ptr.as_mut() } + } +} + +/// An Ownable type is a type that can be put into `Owned`, and when `O= wned` drops, +/// `ptr_drop` will be called. +pub unsafe trait Ownable { + /// # Safety + /// This could only be called in the `Owned::drop` function. + unsafe fn ptr_drop(ptr: *mut Self); +} + +impl Drop for Owned { + fn drop(&mut self) { + // SAFETY: In Owned::drop. + unsafe { + ::ptr_drop(self.ptr.as_mut()); + } + } +} --=20 2.43.0 From nobody Tue Nov 26 01:32:47 2024 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (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 C04B31CEAB9; Tue, 22 Oct 2024 22:49:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637356; cv=none; b=VdpxprsIIZ3tfqD5oAUgcQUFRcgDT6j5g1xkT1yZa4sOndg4V6060INGT4zzOpdXeAf83X3n2+ZVQ8YW5uHFJfIvzqZgzKzySdNxJuTg7hCs53aC/GTCjkUZAB1uE62x5g7PdWRjlN4isLUs0z68z72X/1IHLQ8UR8WuEpWEAr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637356; c=relaxed/simple; bh=GOdt4Fg8zcndsF4gcmOqq0KsfCak3FAOgAZuxoiRUSs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lCuo2aHnArcKUyDv1PwDxCnRTHSZerv39TTqscPBXFWhqLSIjw7G8d8fnGWPcOnd6cbIvXROuJ9SGT+RKKkVPtCQ2kGcxHZWRNmi2FRHiJSkIhAVHENeAqsbr4laTg2HFbnUr9+ZmNfVZlOxKZQXx/2omL9B7JLfV79hRoKMxkk= 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=ZNx9q/lD; arc=none smtp.client-ip=209.85.167.49 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="ZNx9q/lD" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-539fe76e802so7065597e87.1; Tue, 22 Oct 2024 15:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729637353; x=1730242153; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=x3xO+3hoV0kRMGQidVKysI0G/pl1l+DTd2rDU2KKnok=; b=ZNx9q/lDzCrLrPQCko8k6KLV3Ysigvm8FXMbHAEFUmiF6JwBWSSEl3huqW163HH66f 5lUISgojgGAhI3wiWT4Q2EEeTv0PcSrN/ZKaS6jxjM/M4U/T/B9VLVvUQ2Zl1JjWxyFT /lL9KI43tws5ObGA6JXzI3oSuWZwVnN0Twut2mdTlaO8LxVpF0Embf96EyOikpDfHuLi unN23YzUi4lrFrk2lwquzI6ps3w7Y7e0jOUZHypfSnYNuUkAClGKieKY0KiNo/KUJThn 2zjTAoj0nwI+/xIDcvGrQ6jdLE+elhvNkRZlo4gpUMZgEDpPsG8Z4oYaNDR647NARQ64 MQjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729637353; x=1730242153; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x3xO+3hoV0kRMGQidVKysI0G/pl1l+DTd2rDU2KKnok=; b=RPfnqq1+wauYZ16I/mPjmIw4xMdlghKZ9AmoaLLHjkGwBo5AGX/lVVV/fq6f27c4Sl T4L4PSuy+kHKmZtnYGeNJU4HBb9ej+XKufGtkkwqK797Vo3qAHTfTHqICMwBnvfxJxw2 +g0mRBu2/Mw3bRm7odEAqBhf0tt0THisXBr/K1VOu+Q/8KffbbEGnXmKJsfenKCn31dF b7i/FcrXCnieanrxQOAqgR8kQmpStkGmPrKUgUiw1aWxSXZw8nXvcnG8J5Hq7LU3LPgr 1OiBYBTjV9U9bgScp4aL501FXqk5H4tT0cmf0dnST3i7R6TRW8jmNatgUJG7Ji2XQE63 Yi8w== X-Forwarded-Encrypted: i=1; AJvYcCUe4LefRGfmjKpEvyxEWpg3HqpELba8Z+du7xhqPYpXqGckbt8/V+zz8MBLRS7tju09D9nHHHAZ11FaBu4=@vger.kernel.org X-Gm-Message-State: AOJu0YyhXIT5YhP+4jypmqWQ0Wj00eEuNXvrdsRVMO+XiEWlCuIp44A6 eIDczbJnmkbw4qlT543r+Hp71dAaDfQwgFJ96M5s0SUxEDtGzzOlt422zQ== X-Google-Smtp-Source: AGHT+IHipWqUs+P0StAmp65210yOtWYX9k5POWHdCFQbE7HLuZ5tIR/rV6i066dI5Ef/2FGJXjyq4w== X-Received: by 2002:a05:6512:ea2:b0:539:8fcd:510 with SMTP id 2adb3069b0e04-53b1a31115amr185048e87.20.1729637352760; Tue, 22 Oct 2024 15:49:12 -0700 (PDT) Received: from abj-NUC9VXQNX.. (87-94-132-183.rev.dnainternet.fi. [87.94.132.183]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53a223e595csm894881e87.14.2024.10.22.15.49.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2024 15:49:11 -0700 (PDT) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, aliceryhl@google.com Cc: dakr@redhat.com, linux-kernel@vger.kernel.org, airlied@redhat.com, miguel.ojeda.sandonis@gmail.com, boqun.feng@gmail.com, Abdiel Janulgue Subject: [PATCH v2 2/5] rust: page: Make ownership of the page pointer explicit. Date: Wed, 23 Oct 2024 01:44:46 +0300 Message-ID: <20241022224832.1505432-3-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> References: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Ensure only `Page::alloc_page` return pages that own the page allocation. This requires that we replace the page pointer wrapper with Opaque instead of NonNull to make it possible to cast to a Page pointer from a raw struct page pointer. Signed-off-by: Abdiel Janulgue --- rust/kernel/page.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/rust/kernel/page.rs b/rust/kernel/page.rs index fdac6c375fe4..a8288c15b860 100644 --- a/rust/kernel/page.rs +++ b/rust/kernel/page.rs @@ -8,8 +8,9 @@ error::code::*, error::Result, uaccess::UserSliceReader, + types::{Opaque, Owned, Ownable}, }; -use core::ptr::{self, NonNull}; +use core::ptr::{self}; =20 /// A bitwise shift for the page size. pub const PAGE_SHIFT: usize =3D bindings::PAGE_SHIFT as usize; @@ -35,8 +36,9 @@ pub const fn page_align(addr: usize) -> usize { /// # Invariants /// /// The pointer is valid, and has ownership over the page. +#[repr(transparent)] pub struct Page { - page: NonNull, + page: Opaque, } =20 // SAFETY: Pages have no logic that relies on them staying on a given thre= ad, so moving them across @@ -71,19 +73,24 @@ impl Page { /// let page =3D Page::alloc_page(GFP_KERNEL | __GFP_ZERO)?; /// # Ok(()) } /// ``` - pub fn alloc_page(flags: Flags) -> Result { + pub fn alloc_page(flags: Flags) -> Result, AllocError> { // SAFETY: Depending on the value of `gfp_flags`, this call may sl= eep. Other than that, it // is always safe to call this method. let page =3D unsafe { bindings::alloc_pages(flags.as_raw(), 0) }; - let page =3D NonNull::new(page).ok_or(AllocError)?; + if page.is_null() { + return Err(AllocError); + } + // CAST: Self` is a `repr(transparent)` wrapper around `bindings::= page`. + let ptr =3D page.cast::(); // INVARIANT: We just successfully allocated a page, so we now hav= e ownership of the newly // allocated page. We transfer that ownership to the new `Page` ob= ject. - Ok(Self { page }) + // SAFETY: According to invariant above ptr is valid. + Ok(unsafe { Owned::to_owned(ptr) }) } =20 /// Returns a raw pointer to the page. pub fn as_ptr(&self) -> *mut bindings::page { - self.page.as_ptr() + self.page.get() } =20 /// Runs a piece of code with this page mapped to an address. @@ -252,9 +259,9 @@ pub unsafe fn copy_from_user_slice_raw( } } =20 -impl Drop for Page { - fn drop(&mut self) { +unsafe impl Ownable for Page { + unsafe fn ptr_drop(ptr: *mut Self) { // SAFETY: By the type invariants, we have ownership of the page a= nd can free it. - unsafe { bindings::__free_pages(self.page.as_ptr(), 0) }; + unsafe { bindings::__free_pages(ptr.cast(), 0) }; } } --=20 2.43.0 From nobody Tue Nov 26 01:32:47 2024 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (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 9683D1CEE88; Tue, 22 Oct 2024 22:49:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637358; cv=none; b=F9oYLdx/vTbYeMfP4S1QrtrkXnBY8kucjzy2YRsqnTclRFULk/7jwb5bq1AMjTd5EQ3Wm19yRkQKphZKCZrhM9Nm5QHPOEA4o1apceRdSSTmWt0JWgz2ZhwqMmY6zzoPc0vNIEM9vZ7ePZXe10S4xWjT3Ysk4kG5nHrJx8nZUBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637358; c=relaxed/simple; bh=2blEUrbPphbcXN+vYkgtsyrUfkBWuzuL5fzuvWXdX+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZHguCF1sRgF5d/bAGMo6nW7pn9xaciYZmvY+Ys5yO2KXtXZyg2Eq969NxU0lEl3S7SCITiyGOCX++YwBfYcEv//JteKxsxwWEisMv3P63sO4nDv0jzxU0f9fZG8kOJJ1nzoHKo1FaWYbqYkqove2tt4k6MWjCcKWt7gFn6gOWE4= 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=FzJQyGET; arc=none smtp.client-ip=209.85.167.47 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="FzJQyGET" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-539f6e1f756so7185832e87.0; Tue, 22 Oct 2024 15:49:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729637355; x=1730242155; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UM4dLe8e61s60Agsxix4PCXEpP+oYP3bpG6M39q2Oxo=; b=FzJQyGETZyUJK2ISYuQ0eAdN51t9eBYK5ORWC8sExSAoRfQPUanj1LgHeYvGU9LI3I g6q69VQDR2QdX+mprg+wpW9V6sHDgR68TpyZXcBKyMLdxXoet4MZwohIByy4GMO256ae ir8kLg/QwXUlSNe83kNBqMQgYqEGWuaOg2Rvzh99paDm2rJ+Rs3pU7uvpLFDoyxupksT De+hCbuigcukv9h+LPwTzJDmaHgShhKloqxSQbY5wZY4xyWmdycsRrrI9QfWsIJRR5BN wRHAKZ3E6X3uVe/IB4wHCHn6SrLGHc7K+VZ9j//JbBlA5ncCDCPVzfWT5oYjdd1X+Ytb hlpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729637355; x=1730242155; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UM4dLe8e61s60Agsxix4PCXEpP+oYP3bpG6M39q2Oxo=; b=mI+M8bIGozsKDdD69EJQBk6juZqiRjTAjJiauoT0ptde6Gheii39WpOOb2EXWyEgee qzl+n2WK0au0Z4oOCTkZeeKt01NZWZRtdBhnFLh2AQ5IDHWMk336P7GUA/MN0Y93hz6v 2CG6E6je3Egcn6m8H28lu5hnM8eA0kC2PMO+IFCnTf+G8Gl/lAjzcLp5fYtg2xXuc9j6 wvREnEu4W4BXrhWp9Vu9TLnR3qjcqm5q1TRZqtn7P/pQPaQ9WCTD4jFUBM8b0/gkbMDw 36EbOCxqrvLcvKMWQIc7wOCS6iHsfjTpLwgxzCW3+mVj8a8rfyqD1Wz1IhjIw+acbX7P h1AA== X-Forwarded-Encrypted: i=1; AJvYcCVtvRoiZrYd7yuXW0HKgkdNXb5vx5m5bseSpk4XzimytkQu1vm4Ir+fY8LMrTJzNZiuvU2cZwyKWJ4Msbs=@vger.kernel.org X-Gm-Message-State: AOJu0YyrlO72FWcM3D37rlOVKHBvOVPrPQBEjvRimeZPsvlF5al5iJaP TEvr1jsbMmtTVHc7+RYpC8Sz7plmcP01PUTjb+GYwcZaimX+72JxpqaX/w== X-Google-Smtp-Source: AGHT+IHLvuf8jY8BmE3cg+RBqUo4+MvwviQpV5zot9y6cTI657ULmwLOcz+ypQk3AGCu9vZPjhQcTg== X-Received: by 2002:a05:6512:334e:b0:539:f754:ae15 with SMTP id 2adb3069b0e04-53b1a34e1f5mr135931e87.41.1729637354632; Tue, 22 Oct 2024 15:49:14 -0700 (PDT) Received: from abj-NUC9VXQNX.. (87-94-132-183.rev.dnainternet.fi. [87.94.132.183]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53a223e595csm894881e87.14.2024.10.22.15.49.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2024 15:49:14 -0700 (PDT) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, aliceryhl@google.com Cc: dakr@redhat.com, linux-kernel@vger.kernel.org, airlied@redhat.com, miguel.ojeda.sandonis@gmail.com, boqun.feng@gmail.com, Abdiel Janulgue Subject: [PATCH v2 3/5] rust: page: Extend support to vmalloc_to_page Date: Wed, 23 Oct 2024 01:44:47 +0300 Message-ID: <20241022224832.1505432-4-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> References: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend Page to support pages that are not allocated by the constructor, for example, those returned by vmalloc_to_page(). Since we don't own those pages we shouldn't Drop them either. Hence we take advantage of the switch to Opa= que so we can cast to a Page pointer from a struct page pointer and be able to retrieve the reference on an existing struct page mapping. In this case no destructor will be called since we are not instantiating a new Page inst= ance. Signed-off-by: Abdiel Janulgue --- rust/kernel/page.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/rust/kernel/page.rs b/rust/kernel/page.rs index a8288c15b860..465928986f4b 100644 --- a/rust/kernel/page.rs +++ b/rust/kernel/page.rs @@ -31,11 +31,12 @@ pub const fn page_align(addr: usize) -> usize { (addr + (PAGE_SIZE - 1)) & PAGE_MASK } =20 -/// A pointer to a page that owns the page allocation. +/// A pointer to a page that may own the page allocation. /// /// # Invariants /// -/// The pointer is valid, and has ownership over the page. +/// The pointer is valid, and has ownership over the page if the page is a= llocated by this +/// abstraction. #[repr(transparent)] pub struct Page { page: Opaque, @@ -88,6 +89,33 @@ pub fn alloc_page(flags: Flags) -> Result, A= llocError> { Ok(unsafe { Owned::to_owned(ptr) }) } =20 + /// This is just a wrapper to vmalloc_to_page which returns an existin= g page mapping, hence + /// we don't take ownership of the page. Returns an error if the point= er is null or if it + /// is not returned by vmalloc(). + pub fn vmalloc_to_page<'a>( + cpu_addr: *const core::ffi::c_void + ) -> Result<&'a Self, AllocError> + { + if cpu_addr.is_null() { + return Err(AllocError); + } + // SAFETY: We've checked that the pointer is not null, so it is sa= fe to call this method. + if unsafe { !bindings::is_vmalloc_addr(cpu_addr) } { + return Err(AllocError); + } + // SAFETY: We've initially ensured the pointer argument to this fu= nction is not null and + // checked for the requirement the the buffer passed to it should = be allocated by vmalloc, + // so it is safe to call this method. + let page =3D unsafe { bindings::vmalloc_to_page(cpu_addr) }; + if page.is_null() { + return Err(AllocError); + } + // CAST: `Self` is a `repr(transparent)` wrapper around `bindings:= :page`. + // SAFETY: We just successfully allocated a page, therefore derefe= rencing + // the page pointer is valid. + Ok(unsafe { &*page.cast() }) + } + /// Returns a raw pointer to the page. pub fn as_ptr(&self) -> *mut bindings::page { self.page.get() --=20 2.43.0 From nobody Tue Nov 26 01:32:47 2024 Received: from mail-lf1-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (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 B5B7C1CF28E; Tue, 22 Oct 2024 22:49:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637360; cv=none; b=UdIhvAAujfDqxWln+K0oKrzPcJGL6lp1u5DZXq0qujtPZPmC2tH/nca5XRqjJytvVx/fLOO4rErmGE8WdvumhrZ59i23xNrXnDsOMeGFtlRjb75I7g0sXvi0zMpR6a0e7JO+W/Jn38qfnWtsvFPwZeBxFKk46cHwxmh9WBv4RUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637360; c=relaxed/simple; bh=Rebdq/Bcdys6nlGdGi9ZhFfMw8VO8Z5FWhgnbMngNkk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GcfGOPBEVyoMoeDMtqyuGTmGaTxPtSZ/ykaTl8bk9F0r5xGLaNOR115RewPQqeWA/xJj4ebjK5rzFZktSOEpFDx9ELIdXvxFzXdPWl3Dx4K3Ra5OBPqOB9s6ShyoO0XuZLjErgSY3CC/ci5ErdgU4rsRxiaUP7froXTQ6wXR+r0= 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=DkB0WrkU; arc=none smtp.client-ip=209.85.167.42 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="DkB0WrkU" Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-539e690479cso6570155e87.3; Tue, 22 Oct 2024 15:49:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729637357; x=1730242157; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ftMwKMj+3AfzocPFKICIi9+9U9CUekGXM3KxUPtjkJM=; b=DkB0WrkUo9L986vi9bA1U1QV4flOG20uiKsYJWfwqhK1mSFze9HVUMlVZqbdH0pVp1 /fwx0ZB29HEcY7ncS9FuaBNphiIcHFbB9078Fld4K1ARKb5vBndiVlIoPYqamUQ2AOp6 kuhtA8o2C7POfUCD3FriUHSuvWmBFiDePxTRNo5QcpzfaOJePKTyxUKwbx+AElZtdGFh AFhwFTIzEtrHiZ0RGn5KSZ86NXLbfCjekOwuNQPdsnBUogkPrwc3ou/anZwKwi23YgSY j4SroOOH5qh2i919CqGnt5OwK+Zh59j+r0GfH4wBnugv/LjB3aoMnfddoJePYWXzvHou SgrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729637357; x=1730242157; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ftMwKMj+3AfzocPFKICIi9+9U9CUekGXM3KxUPtjkJM=; b=Pn2exBU/5XHI7PHtFADTUiIlYAqpEOERlGZu/LdwbHuKAziQ3eXP++THkhm4zBfKwj JpzJDGgo8YQc89jXirIul66nioEpYYyInlAYtoF0foYwYNtzRjaS6SKIlp1iG8rLkmtb c590tvKY6yaW9Vhh+as99/tocooOHSXDgfEUwIY+qiJyECCxM2tQSSlleimDLLbRKrb7 z8gn4ej1r9VI+N1QdtdUewZQmYGUDon7mty/44tUcK6gCPZe5A8WpcKQ3mrXiEaetfdA ctYNy87+rXq7kVtxl7d/vM+GAj+ZLvgNqD7tJRCLOfeH2mqVE1gbvow7aAl6x3FDLII8 1ufQ== X-Forwarded-Encrypted: i=1; AJvYcCXDYxPCejDJ0vVsPb9L0+TOHbiFoFpHYyDiF83aC/jp42lm4rZPx9TfO8H1KZRNDXmkrtVVP1ryabBx24Y=@vger.kernel.org X-Gm-Message-State: AOJu0Yye3QtBPkNBhnEkiC8cP1PHehfAiuITJwfWFI+CvcWZlSMIvK80 th6MGlc1WfboqXNncKLh/nemMXrU83jznb2hhfvxdBmYpGluBWyY6eP+dg== X-Google-Smtp-Source: AGHT+IEOveVVafqjig6zTJ5sYMApD3cGHz0tfMasspUykwwPfN+R6wOr9UnCKdmoBylEBQ+GxF7kNg== X-Received: by 2002:a05:6512:31d1:b0:539:8d2c:c01c with SMTP id 2adb3069b0e04-53b1a36b785mr210527e87.41.1729637356523; Tue, 22 Oct 2024 15:49:16 -0700 (PDT) Received: from abj-NUC9VXQNX.. (87-94-132-183.rev.dnainternet.fi. [87.94.132.183]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53a223e595csm894881e87.14.2024.10.22.15.49.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2024 15:49:15 -0700 (PDT) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, aliceryhl@google.com Cc: dakr@redhat.com, linux-kernel@vger.kernel.org, airlied@redhat.com, miguel.ojeda.sandonis@gmail.com, boqun.feng@gmail.com, Abdiel Janulgue Subject: [PATCH v2 4/5] rust: page: Add page_slice_to_page Date: Wed, 23 Oct 2024 01:44:48 +0300 Message-ID: <20241022224832.1505432-5-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> References: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make it convenient to convert buffers into page-sized vmalloc'd chunks which can then be used in vmalloc_to_page(). Signed-off-by: Abdiel Janulgue --- rust/kernel/page.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/rust/kernel/page.rs b/rust/kernel/page.rs index 465928986f4b..2f0507fac9f0 100644 --- a/rust/kernel/page.rs +++ b/rust/kernel/page.rs @@ -3,7 +3,7 @@ //! Kernel page allocation and management. =20 use crate::{ - alloc::{AllocError, Flags}, + alloc::{AllocError, Flags, VVec, flags::*}, bindings, error::code::*, error::Result, @@ -116,6 +116,26 @@ pub fn vmalloc_to_page<'a>( Ok(unsafe { &*page.cast() }) } =20 + /// A convenience wrapper to vmalloc_to_page which ensures it takes a = page-sized buffer + /// represented by `PageSlice`. + /// + /// # Examples + /// + /// ``` + /// use kernel::page::*; + /// + /// # fn dox() -> Result<(), kernel::alloc::AllocError> { + /// let somedata: [u8; PAGE_SIZE * 2] =3D [0; PAGE_SIZE * 2]; + /// let buf: &[u8] =3D &somedata; + /// let pages: VVec =3D buf.try_into()?; + /// let page =3D Page::page_slice_to_page(&pages[0])?; + /// # Ok(()) } + /// ``` + pub fn page_slice_to_page<'a>(page: &PageSlice) -> Result<&'a Self, Al= locError> + { + Self::vmalloc_to_page(page.0.as_ptr() as _) + } + /// Returns a raw pointer to the page. pub fn as_ptr(&self) -> *mut bindings::page { self.page.get() @@ -287,6 +307,43 @@ pub unsafe fn copy_from_user_slice_raw( } } =20 +/// A page-aligned, page-sized object. This is used for convenience to con= vert a large +/// buffer into an array of page-sized vmalloc'd chunks which can then be = used in +/// `Page::page_slice_to_page` wrapper. +/// +// FIXME: This should be `PAGE_SIZE`, but the compiler rejects everything = except a literal +// integer argument for the `repr(align)` attribute. +#[repr(align(4096))] +pub struct PageSlice([u8; PAGE_SIZE]); + +impl TryFrom<&[u8]> for VVec { + type Error =3D AllocError; + + fn try_from(val: &[u8]) -> Result { + let mut k =3D VVec::new(); + let aligned_len: usize; + + // Ensure the size is page-aligned. + match core::alloc::Layout::from_size_align(val.len(), PAGE_SIZE) { + Ok(align) =3D> { aligned_len =3D align.pad_to_align().size() }, + Err(_) =3D> return Err(AllocError), + }; + let pages =3D aligned_len >> PAGE_SHIFT; + match k.reserve(pages, GFP_KERNEL) { + Ok(()) =3D> { + // SAFETY: from above, the length should be equal to the v= ector's capacity + unsafe { k.set_len(pages); } + // SAFETY: src buffer sized val.len() does not overlap wit= h dst buffer since + // the dst buffer's size is val.len() padded up to a multi= ple of PAGE_SIZE. + unsafe { ptr::copy_nonoverlapping(val.as_ptr(), k.as_mut_p= tr() as *mut u8, + val.len()) }; + Ok(k) + }, + Err(_) =3D> Err(AllocError), + } + } +} + unsafe impl Ownable for Page { unsafe fn ptr_drop(ptr: *mut Self) { // SAFETY: By the type invariants, we have ownership of the page a= nd can free it. --=20 2.43.0 From nobody Tue Nov 26 01:32:47 2024 Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (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 5EAF91CDFC3; Tue, 22 Oct 2024 22:49:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637362; cv=none; b=tIB2OuIr0kTLrh7m7LfEnKxzc4OKerkIN7AIiwJwAZ4rUD2tAPJjO4RTb3BTUELyOB/xGOusIqOK7MIX6zv+0H21ZL8wNc8u2n9hSAORVxBsWWyqJ33aFIWgJo6izOT2uL6AmId3X+isklQVPN39I/UoY9vWwhWB2IBJ+HTsdR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729637362; c=relaxed/simple; bh=uW9diALEP9ZtiLTXAb1PZ+oZzD1vayfhCvZE6VvGSGc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ltg7dsNwhFcsfl4zslL4KewdNq7RQATT/vzvv5yUGOh19O8FZqcVhEKoRWilnMdHiB9X6dOEeMyaxonmckqs7c5SfeJ4j38xn5jzamli9HkLwvTNDcLmxMYJmxKwmv6G6jagoYGvFL/atC+zC6Lp+nrbnrf05BhxtXvyPpnZYF4= 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=gk5US8YZ; arc=none smtp.client-ip=209.85.167.53 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="gk5US8YZ" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-539f76a6f0dso5499405e87.1; Tue, 22 Oct 2024 15:49:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729637358; x=1730242158; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Q/j3y+C65g8JL4SR/Lkh7VbOU4M9pFoYcH6/NF8qhIk=; b=gk5US8YZjUUXbV5FV1CBz+DpqwstZS9YU8OEZVPsg0ptkvjjHMC33TehZUB76nzxkm /Z29+nDWzM22s+U2QJ7iHoCiTQpowBoK51d7wbnEph8336hhjU9Y7CR9SrYaO5D2GH6Z 2OuIdy31zLPB78GlhFKOZr2v/Z6tOcq1MSp9BoxDLVxwWqLeOR9/LhijJIU41RN/9YHW g+OlYTycrwYqnIAfMEDJXC7B1xxRAkveh2/AzlHn4RuFDDg9Dpf5qSBscY0hySGEWAI4 M9YhetLvGUu/DxsaJZdinHzP3blmF995gsQJOAIIjjPaG6xyWHXymOQTw7GOZrsNQ0GK q5rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729637358; x=1730242158; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q/j3y+C65g8JL4SR/Lkh7VbOU4M9pFoYcH6/NF8qhIk=; b=Hu8Ua7HOTiw5UhlludtVFHMxzDzCLWK5gnkNudAPilMJkAmYdR4RTgyMbaTm2qjlyo QoBxx3HNNSJPu53Ah4foGpKDD6vdTzKjM2Ks/GmUMH3g9qtqWpnUBBrnUPEP6y3dx6IY nE70W+lxyjBxZStvknrvFOmOoaLPneQive2RKuhl1FT2bYcNegOJ3BwMYlxR0vWUV3Xc OT1cYy0oKFsJ28H1BTBwVuln39rHVcke7NZceIB4pACUjAF5sNgLqnL0nGSyCoJtiTox X5mS6eoqXfe3YF/pKOGcII9A1IZq0/vu7J3OxQS8ae2haiFhq71R1LQRsNilO5OwcO0W K27w== X-Forwarded-Encrypted: i=1; AJvYcCWmImNYGGAbMcfT/x+/46Baxzygm5w9aV/vYIq6W1chl4BCJ+ikav/ntzRpdbKlQoe+EtQiYTIqNSU6+ec=@vger.kernel.org X-Gm-Message-State: AOJu0YzhKerCEPKHa6vyQ9rBLDF91+iQh6WWWciadp6mNwbO++zjczR2 Da1tGTaTH+UuITHl6s9Cvbh/M5vRMzy+nlxe3zLezAtBjIv/epRKnh/yhQ== X-Google-Smtp-Source: AGHT+IGJNc5G/N9oAN/iMJnW3Q1hdzKMq4lY+yTSxrxoH6XLwRn2fVgS/hlgwcDG1ZslsQYakLw6dA== X-Received: by 2002:a05:6512:281e:b0:539:89f7:3187 with SMTP id 2adb3069b0e04-53b1a36c709mr169463e87.47.1729637358314; Tue, 22 Oct 2024 15:49:18 -0700 (PDT) Received: from abj-NUC9VXQNX.. (87-94-132-183.rev.dnainternet.fi. [87.94.132.183]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53a223e595csm894881e87.14.2024.10.22.15.49.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Oct 2024 15:49:16 -0700 (PDT) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, aliceryhl@google.com Cc: dakr@redhat.com, linux-kernel@vger.kernel.org, airlied@redhat.com, miguel.ojeda.sandonis@gmail.com, boqun.feng@gmail.com, Abdiel Janulgue Subject: [PATCH v2 5/5] rust: firmware: implement `Ownable` for Firmware Date: Wed, 23 Oct 2024 01:44:49 +0300 Message-ID: <20241022224832.1505432-6-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> References: <20241022224832.1505432-1-abdiel.janulgue@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For consistency, wrap the firmware as an `Owned` smart pointer in the constructor. Cc: Danilo Krummrich Suggested-by: Boqun Feng Signed-off-by: Abdiel Janulgue --- rust/kernel/firmware.rs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs index dee5b4b18aec..6da834b37455 100644 --- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -4,8 +4,8 @@ //! //! C header: [`include/linux/firmware.h`](srctree/include/linux/firmware.= h) =20 -use crate::{bindings, device::Device, error::Error, error::Result, str::CS= tr}; -use core::ptr::NonNull; +use crate::{bindings, device::Device, error::Error, error::Result, str::CS= tr, + types::{Opaque, Owned, Ownable}}; =20 /// # Invariants /// @@ -52,10 +52,11 @@ fn request_nowarn() -> Self { /// # Ok(()) /// # } /// ``` -pub struct Firmware(NonNull); + #[repr(transparent)] +pub struct Firmware(Opaque); =20 impl Firmware { - fn request_internal(name: &CStr, dev: &Device, func: FwFunc) -> Result= { + fn request_internal(name: &CStr, dev: &Device, func: FwFunc) -> Result= > { let mut fw: *mut bindings::firmware =3D core::ptr::null_mut(); let pfw: *mut *mut bindings::firmware =3D &mut fw; =20 @@ -65,25 +66,26 @@ fn request_internal(name: &CStr, dev: &Device, func: Fw= Func) -> Result { if ret !=3D 0 { return Err(Error::from_errno(ret)); } - + // CAST: Self` is a `repr(transparent)` wrapper around `bindings::= firmware`. + let ptr =3D fw.cast::(); // SAFETY: `func` not bailing out with a non-zero error code, guar= antees that `fw` is a // valid pointer to `bindings::firmware`. - Ok(Firmware(unsafe { NonNull::new_unchecked(fw) })) + Ok(unsafe { Owned::to_owned(ptr) }) } =20 /// Send a firmware request and wait for it. See also `bindings::reque= st_firmware`. - pub fn request(name: &CStr, dev: &Device) -> Result { + pub fn request(name: &CStr, dev: &Device) -> Result> { Self::request_internal(name, dev, FwFunc::request()) } =20 /// Send a request for an optional firmware module. See also /// `bindings::firmware_request_nowarn`. - pub fn request_nowarn(name: &CStr, dev: &Device) -> Result { + pub fn request_nowarn(name: &CStr, dev: &Device) -> Result= > { Self::request_internal(name, dev, FwFunc::request_nowarn()) } =20 fn as_raw(&self) -> *mut bindings::firmware { - self.0.as_ptr() + self.0.get() } =20 /// Returns the size of the requested firmware in bytes. @@ -101,10 +103,13 @@ pub fn data(&self) -> &[u8] { } } =20 -impl Drop for Firmware { - fn drop(&mut self) { - // SAFETY: `self.as_raw()` is valid by the type invariant. - unsafe { bindings::release_firmware(self.as_raw()) }; +unsafe impl Ownable for Firmware { + unsafe fn ptr_drop(ptr: *mut Self) { + // SAFETY: + // - By the type invariants, we have ownership of the ptr and can = free it. + // - Per function safety, this is called in Owned::drop(), so `ptr= ` is a + // unique pointer to object, it's safe to release the firmware. + unsafe { bindings::release_firmware(ptr.cast()) }; } } =20 --=20 2.43.0