From nobody Sun Feb 8 03:58:31 2026 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (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 A267F2153DE; Fri, 7 Mar 2025 11:08:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345720; cv=none; b=a81jclQY3s330jOANhfDAWK17cz7oq+r0TZqrcVr/rJnSez6kzJQ9RYzY3RV/KvRUNkF1gRpfV18rMSWtbgVRHdk0EEFCxjDfSTBG8wWE+6fl8IqCH0XHyve3c9+1BGrCc+vaHt+irkW/08dAZgm8KFkY406++Gbg4POyQeCaf4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345720; c=relaxed/simple; bh=7EWHV9dXU2kG/xafKevv9SzG5SSqBdCFZI3L654ZQDs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rJo0KycVdBYYMQm13ScGeJ/QQz/65ErtCvrYfiV0Ovu1xPP+SdkyFVm8qJKA0kiEkuuxS8u+YyicRvLi4P9LP2d+fE+2RmtbB1O0WtR5ir2qHd2PMvqzi7BNCtFvmsCk5kxPEU+ORveT1sOu4LNEQHPBJnwSwnX+6rV6b/FfMOg= 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=RTN+pnXZ; arc=none smtp.client-ip=209.85.167.54 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="RTN+pnXZ" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-5494cb8c2e7so1870261e87.0; Fri, 07 Mar 2025 03:08:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345717; x=1741950517; 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=QE3/EOD24kfqjSTHkaz9KRGvlEanB1hF966k3hECCPg=; b=RTN+pnXZELpGE/BUdfQWqC+71/XQveuvXeqJ8uxPbrF8cGfO5JCZWJj31oVYPbS/Xm Klty46VmRGMtujvlr6NQMHuu/TwrNcf3MjyDhcXut32p402Wp7cub1cj4dhA09KuW9+4 DdpDCzwc5DE6VEiO/QdbhsTW4WhKuOzggjF3sAU9gq9lThIDBtqLAMMlNufo8g7FLXKh H0lTJK1L/JdBtfYeGE55dRvuUknBB5r8R7WnJqf2dpw/fm/36AfqODnhkCujFounHVE/ hOj0ScwnwEyUk/pf2zNe8a66hYo072R6CpGapm9YWDkqvu8mDL2DQdzoL3NsjWcdBSIQ zmAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345717; x=1741950517; 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=QE3/EOD24kfqjSTHkaz9KRGvlEanB1hF966k3hECCPg=; b=PWTxOiSWIFNK8sO2G/UUJGw9N8Hq5ZN+0tNN1qq43hovPICx/Gfire9jiBJFQ9azL9 dyWpWeQ+TCrkxQDFwiWwEs6KW5TdzC4VQgYYDeWOs6XSB/mDo6/Fb5l0bJJuXJvGrglV BMeuAgEP1iYmS+fZh2vvlDd92IW4qv4tTkcVknhHi61h/jeSBUGKlpHMThnJhqR3RKr/ Rp+NkFUJdhuKVRgPFv6YFIVnIo2pI/JnBqOU/iV5yrAX6ySHQOPH+h7oJfa+EnBsq4Cj hYKQMQ2h/oDHWtD36gP2llUspRjXOlfiuO9M4sQyp86+H6UwYDs5f+SMGmeXEaaWiq94 QGWA== X-Forwarded-Encrypted: i=1; AJvYcCXvdOrX9jHdR/uBeZXCeIiesWaLpVrcGZ45y8nWm9aBIAumRd9vsVNyNfW82BQpDbFdClvFvS7IXTNv0ug=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+fG45IUhGBIveqdkFYZN2ykt9uBH7uoOpc6LCYsz6044qYO95 OWWwsehrOGc8NDd1L12o0XG6ZaD1W0z4gKvrbRctTS61r9OFFBDOspzEEg== X-Gm-Gg: ASbGncuG0k56WDHjOCGk0XCZw1Tlz9Gc5Ma3mXRV3VId94yfKobEJS5Ob7U8X4Fdk4y fk2qRqcw9rQ0prmspocoPQS+E2TvPCZVp6u7/3WbNSslNA4kUqplL55XSrSrE0zUULWX+IM8wCw DqwJm4ScQv4EYN5PfPCNKOcDSrJHs1v8/LozGwJeNb31LOTu5qjY3c24dILlmBZUrjwwN06zBFk mmu7WXvqxUSy7aeVQVV47PXvrwoMaPF9I01+hKyGD8XiIWvG9c3cQcDINB/lnhJjaeNfJsy0qj4 ePKqffxK3E5pAk6/dpNkZEIMbUHa3hrEHB/v4QtPmiMgAY/rjjIvmAmsSSoCkUzimBwC7Eh9wXv lTM0Hkz7YDYNHrNzLKQuclw== X-Google-Smtp-Source: AGHT+IE08HRwi5zEAOrxjSmh0hF4NwG0alA2vND812imDj4F+QH8VbA/puyLUNVeEErub3tHh6+9Jw== X-Received: by 2002:a05:6512:118a:b0:549:5b54:2c77 with SMTP id 2adb3069b0e04-54990eaa9e3mr941912e87.32.1741345716393; Fri, 07 Mar 2025 03:08:36 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:35 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 1/7] rust: error: Add EOVERFLOW Date: Fri, 7 Mar 2025 13:06:18 +0200 Message-ID: <20250307110821.1703422-2-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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" Trivial addition for missing EOVERFLOW error. This is used by a subsequent patch that might require returning EOVERFLOW as a result of `checked_mul`. Reviewed-by: Alice Ryhl Reviewed-by: Andreas Hindborg Signed-off-by: Abdiel Janulgue --- rust/kernel/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index f6ecf09cb65f..1e510181432c 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -64,6 +64,7 @@ macro_rules! declare_err { declare_err!(EPIPE, "Broken pipe."); declare_err!(EDOM, "Math argument out of domain of func."); declare_err!(ERANGE, "Math result not representable."); + declare_err!(EOVERFLOW, "Value too large for defined data type."); declare_err!(ERESTARTSYS, "Restart the system call."); declare_err!(ERESTARTNOINTR, "System call was interrupted by a signal = and will be restarted."); declare_err!(ERESTARTNOHAND, "Restart if no handler."); --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 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 8ADF5215764; Fri, 7 Mar 2025 11:08:41 +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=1741345723; cv=none; b=SCEh41xxmyRktgfKzNrrhjpT3RMWOj1799ukl3+Z7XJpmQ5fmD6gOTCZBO0H3kPcpgMd1VrI9V4zmdn+2pQkLY/6jOTq5B3EvfRKHZtQP5Q8jSjltupG2w0D4m8BU3W10Sa8HpAa5Lf7ndMAqP3tHtUSNaAnJBPaJEDAcCKmzRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345723; c=relaxed/simple; bh=wifw/dEujCJ3OVoPR2EsPHuRAc7kCpIPBo1//png4vk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iwfL3wFhJS9OtcHfV4ttJE8c7j6lI9Y3kUqH8JY0NaGaR+gJT9hvmxZH0TDb3W/SARn0PsDrxJ8c6xBikFImX8ek+DI0a029obsckNfmqFUbUz9XAdSOcc/yHfomAgO/Ra2khDhc8uFqL3qweqUv1Q2Ae0VUun2hcWJlnoeHn1w= 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=dG9qgGPt; 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="dG9qgGPt" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-5498d2a8b89so1719871e87.1; Fri, 07 Mar 2025 03:08:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345720; x=1741950520; 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=F0FVS9VLJIIJ6kHkmWCSquWbZ6SxQbrrZYisX5uBmSA=; b=dG9qgGPt8k8qUR1/GtpgYPb4h0NabnHvq5/t68vBlvO6zMhxgVoaGMPYrweTJCF6Ed QbfEsCbzc1LGg+377RPeobKLIkP5SBxljN3zVzUnk/W/NtoGOMeGWZOaSUGRSWNPxvt1 hunofnvyDGOLEEWkmL5z8DzJuoLg4dw/gByUJcWK0nnQsB5XyPDAgsGyDtI2VO4DsQFP HhrKWxIu7rOGgZCoXIGn2JBWpuNYQagighLQ+ci2McP7Sr6IxMh2c3btoVQf/1kK/48S PI9S1B0cJPxNNQrwGSNWnUUcoiG2sKv/toSVRyCxNAxOOwIg5X4xFjU5V17pwIB0C62s jgoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345720; x=1741950520; 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=F0FVS9VLJIIJ6kHkmWCSquWbZ6SxQbrrZYisX5uBmSA=; b=raDdIw76cxr4DGhg4VgnBaCusnwTE1m+l86CXRAHjjRG4hKKMXbcKf+hjAOO9//XnX iX1uJTauYeGzVfTnNdJuXhJCqLrnrgdVl33tj/d47Nz5faI8Oda04q4puCaCO8o9A1pD 3c4dSX9ywJxdidx40lr49A/B3Z6l9WrfJQCLOdl+yoIh4V8NWonscqMT4CVWH6M+bRv6 /TcAVjfwDbntoJQZsc/SWB96qlqgkYzQlS6MvWO634izBtY6opPmFB7igEEXYDERGuDF v/ohh9rHEnLgV7qyPzlh6lusPhUXwHIn2qyuylmFDT/6SmqAta3Iwk5wGfNJMCSaoQsC fihA== X-Forwarded-Encrypted: i=1; AJvYcCXjzR8vi8HXoZB2c2OYR24kWwkNd3o9+G8xQDPpAFpSTp+DoNviXRLPlS8AinG3yseWYNVhYGW0RDqvaO8=@vger.kernel.org X-Gm-Message-State: AOJu0YyaFJYKrmbrmXD0GOkq6lCgkxqYlM891kW94okjJfxcbbBXie4s cIIcS26lYTLdkYX4QXuFHK2G+4vVj5HzjBRmipGu3/3LmdeRpmN6tBAfcA== X-Gm-Gg: ASbGncujryRL79X6FaAsBQ9X1EOCc10qYGwxq9JjDMAo+ylb2RNnYU5pPlF7emWbtdM wG7yaow1NphS5UzAmXDr8ne20X/v7LVmlTduuQ5QcVY6PmO8BfiqiinE596HUgTMmMSQDPJXR9X se6ZAuwvZD4b+AjiHTZUdnYQUyNhoJdPwtpjlf7vxeJvVbkP1BfS0iIvm+34zJ7qdOK+8aVJDXk pHA75vvc0ZOExAT8yID0ZbuDvliuTVIDnqstjlcS9A7lm12Rj86ia78OgTVnklnbv+qGh0xY+k4 wXoXeg3JK7ucVcedlqSjrBSclZwQZYk9Dp9eKEpO8SbSWaFMP8SGR9u5Y2Wd6rxpvaHMHcmEEI4 EikHeLHnYKjXmWjracDzPLQ== X-Google-Smtp-Source: AGHT+IHtERMjJN0wtv6/JAlhVWXUoGZyadEVLU0EhqhPw3wRQN3LEAPG7QX6lyT89Ml2GPPXGSMgpg== X-Received: by 2002:a05:6512:b14:b0:549:9044:94ab with SMTP id 2adb3069b0e04-54990eb17b0mr961360e87.35.1741345719218; Fri, 07 Mar 2025 03:08:39 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:37 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 2/7] rust: add dma coherent allocator abstraction. Date: Fri, 7 Mar 2025 13:06:19 +0200 Message-ID: <20250307110821.1703422-3-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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 a simple dma coherent allocator rust abstraction. Based on Andreas Hindborg's dma abstractions from the rnvme driver, which was also based on earlier work by Wedson Almeida Filho. A CoherentAllocation is wrapped in Devres which basically guarantees that a driver can't make a CoherentAllocation out-live driver unbind. This is needed, since DMA allocations potentially also result in programming of the IOMMU. IOMMU mappings are device resources and hence the device / driver lifecycle needs to be enforced. Signed-off-by: Abdiel Janulgue Reviewed-by: Alice Ryhl --- rust/bindings/bindings_helper.h | 1 + rust/kernel/dma.rs | 378 ++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 1 + 3 files changed, 380 insertions(+) create mode 100644 rust/kernel/dma.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index f46cf3bb7069..bf1110590c19 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs new file mode 100644 index 000000000000..8a250242641c --- /dev/null +++ b/rust/kernel/dma.rs @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Direct memory access (DMA). +//! +//! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-ma= pping.h) + +use crate::{ + bindings, build_assert, + device::Device, + devres::Devres, + error::code::*, + error::Result, + transmute::{AsBytes, FromBytes}, + types::ARef, +}; +use kernel::prelude::*; + +/// Possible attributes associated with a DMA mapping. +/// +/// They can be combined with the operators `|`, `&`, and `!`. +/// +/// Values can be used from the [`attrs`] module. +/// +/// # Examples +/// +/// ``` +/// use kernel::{device::Device, devres::Devres,}; +/// use kernel::dma::{attrs::*, CoherentAllocation}; +/// +/// # fn test(dev: &Device) -> Result { +/// let attribs =3D DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_WARN; +/// let c: Devres> =3D +/// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, attribs)?; +/// # Ok::<(), Error>(()) } +/// ``` +#[derive(Clone, Copy, PartialEq)] +#[repr(transparent)] +pub struct Attrs(u32); + +impl Attrs { + /// Get the raw representation of this attribute. + pub(crate) fn as_raw(self) -> crate::ffi::c_ulong { + self.0 as _ + } + + /// Check whether `flags` is contained in `self`. + pub fn contains(self, flags: Attrs) -> bool { + (self & flags) =3D=3D flags + } +} + +impl core::ops::BitOr for Attrs { + type Output =3D Self; + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } +} + +impl core::ops::BitAnd for Attrs { + type Output =3D Self; + fn bitand(self, rhs: Self) -> Self::Output { + Self(self.0 & rhs.0) + } +} + +impl core::ops::Not for Attrs { + type Output =3D Self; + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +/// DMA mapping attributes. +pub mod attrs { + use super::Attrs; + + /// Specifies that reads and writes to the mapping may be weakly order= ed, that is that reads + /// and writes may pass each other. + pub const DMA_ATTR_WEAK_ORDERING: Attrs =3D Attrs(bindings::DMA_ATTR_W= EAK_ORDERING); + + /// Specifies that writes to the mapping may be buffered to improve pe= rformance. + pub const DMA_ATTR_WRITE_COMBINE: Attrs =3D Attrs(bindings::DMA_ATTR_W= RITE_COMBINE); + + /// Lets the platform to avoid creating a kernel virtual mapping for t= he allocated buffer. + pub const DMA_ATTR_NO_KERNEL_MAPPING: Attrs =3D Attrs(bindings::DMA_AT= TR_NO_KERNEL_MAPPING); + + /// Allows platform code to skip synchronization of the CPU cache for = the given buffer assuming + /// that it has been already transferred to 'device' domain. + pub const DMA_ATTR_SKIP_CPU_SYNC: Attrs =3D Attrs(bindings::DMA_ATTR_S= KIP_CPU_SYNC); + + /// Forces contiguous allocation of the buffer in physical memory. + pub const DMA_ATTR_FORCE_CONTIGUOUS: Attrs =3D Attrs(bindings::DMA_ATT= R_FORCE_CONTIGUOUS); + + /// This is a hint to the DMA-mapping subsystem that it's probably not= worth the time to try + /// to allocate memory to in a way that gives better TLB efficiency. + pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs =3D Attrs(bindings::DMA_A= TTR_ALLOC_SINGLE_PAGES); + + /// This tells the DMA-mapping subsystem to suppress allocation failur= e reports (similarly to + /// __GFP_NOWARN). + pub const DMA_ATTR_NO_WARN: Attrs =3D Attrs(bindings::DMA_ATTR_NO_WARN= ); + + /// Used to indicate that the buffer is fully accessible at an elevate= d privilege level (and + /// ideally inaccessible or at least read-only at lesser-privileged le= vels). + pub const DMA_ATTR_PRIVILEGED: Attrs =3D Attrs(bindings::DMA_ATTR_PRIV= ILEGED); +} + +/// An abstraction of the `dma_alloc_coherent` API. +/// +/// This is an abstraction around the `dma_alloc_coherent` API which is us= ed to allocate and map +/// large consistent DMA regions. +/// +/// A [`CoherentAllocation`] instance contains a pointer to the allocated = region (in the +/// processor's virtual address space) and the device address which can be= given to the device +/// as the DMA address base of the region. The region is released once [`C= oherentAllocation`] +/// is dropped. +/// +/// # Invariants +/// +/// For the lifetime of an instance of [`CoherentAllocation`], the `cpu_ad= dr` is a valid pointer +/// to an allocated region of consistent memory and `dma_handle` is the DM= A address base of +/// the region. +pub struct CoherentAllocation { + dev: ARef, + dma_handle: bindings::dma_addr_t, + count: usize, + cpu_addr: *mut T, + dma_attrs: Attrs, +} + +impl CoherentAllocation { + /// Allocates a region of `size_of:: * count` of consistent memory. + /// + /// # Examples + /// + /// ``` + /// use kernel::{device::Device, devres::Devres,}; + /// use kernel::dma::{attrs::*, CoherentAllocation}; + /// + /// # fn test(dev: &Device) -> Result { + /// let c: Devres> =3D + /// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, DMA_ATTR_N= O_WARN)?; + /// # Ok::<(), Error>(()) } + /// ``` + pub fn alloc_attrs( + dev: &Device, + count: usize, + gfp_flags: kernel::alloc::Flags, + dma_attrs: Attrs, + ) -> Result>> { + build_assert!( + core::mem::size_of::() > 0, + "It doesn't make sense for the allocated type to be a ZST" + ); + + let size =3D count + .checked_mul(core::mem::size_of::()) + .ok_or(EOVERFLOW)?; + let mut dma_handle =3D 0; + // SAFETY: Device pointer is guaranteed as valid by the type invar= iant on `Device`. + let ret =3D unsafe { + bindings::dma_alloc_attrs( + dev.as_raw(), + size, + &mut dma_handle, + gfp_flags.as_raw(), + dma_attrs.as_raw(), + ) + }; + if ret.is_null() { + return Err(ENOMEM); + } + // INVARIANT: We just successfully allocated a coherent region whi= ch is accessible for + // `count` elements, hence the cpu address is valid. We also hold = a refcounted reference + // to the device. + let devres =3D Devres::new( + dev, + Self { + dev: dev.into(), + dma_handle, + count, + cpu_addr: ret as *mut T, + dma_attrs, + }, + GFP_KERNEL, + )?; + + Ok(devres) + } + + /// Performs the same functionality as [`alloc_attrs`], except the `dm= a_attrs` is 0 by default. + pub fn alloc_coherent( + dev: &Device, + count: usize, + gfp_flags: kernel::alloc::Flags, + ) -> Result>> { + CoherentAllocation::alloc_attrs(dev, count, gfp_flags, Attrs(0)) + } + + /// Returns the base address to the allocated region in the CPU's virt= ual address space. + pub fn start_ptr(&self) -> *const T { + self.cpu_addr + } + + /// Returns the base address to the allocated region in the CPU's virt= ual address space as + /// a mutable pointer. + pub fn start_ptr_mut(&mut self) -> *mut T { + self.cpu_addr + } + + /// Returns a DMA handle which may given to the device as the DMA addr= ess base of + /// the region. + pub fn dma_handle(&self) -> bindings::dma_addr_t { + self.dma_handle + } + + /// Returns a pointer to an element from the region with bounds checki= ng. `offset` is in + /// units of `T`, not the number of bytes. + /// + /// Public but hidden since it should only be used from [`dma_read`] a= nd [`dma_write`] macros. + #[doc(hidden)] + pub fn item_from_index(&self, offset: usize) -> Result<*mut T> { + if offset >=3D self.count { + return Err(EINVAL); + } + // SAFETY: + // - The pointer is valid due to type invariant on `CoherentAlloca= tion` + // and we've just checked that the range and index is within bound= s. + // - `offset` can't overflow since it is smaller than `self.count`= and we've checked + // that `self.count` won't overflow early in the constructor. + Ok(unsafe { self.cpu_addr.add(offset) }) + } + + /// Reads the value of `field` and ensures that its type is [`FromByte= s`]. + /// + /// # Safety + /// + /// This must be called from the [`dma_read`] macro which ensures that= the `field` pointer is + /// validated beforehand. + /// + /// Public but hidden since it should only be used from [`dma_read`] m= acro. + #[doc(hidden)] + pub unsafe fn field_read(&self, field: *const F) -> F { + // SAFETY: By the safety requirements field is valid. + unsafe { field.read_volatile() } + } + + /// Writes a value to `field` and ensures that its type is [`AsBytes`]. + /// + /// # Safety + /// + /// This must be called from the [`dma_write`] macro which ensures tha= t the `field` pointer is + /// validated beforehand. + /// + /// Public but hidden since it should only be used from [`dma_write`] = macro. + #[doc(hidden)] + pub unsafe fn field_write(&self, field: *mut F, val: F) { + // SAFETY: By the safety requirements field is valid. + unsafe { field.write_volatile(val) } + } +} + +/// Note that the device configured to do DMA must be halted before this o= bject is dropped. +impl Drop for CoherentAllocation { + fn drop(&mut self) { + let size =3D self.count * core::mem::size_of::(); + // SAFETY: Device pointer is guaranteed as valid by the type invar= iant on `Device`. + // The cpu address, and the dma handle are valid due to the type i= nvariants on + // `CoherentAllocation`. + unsafe { + bindings::dma_free_attrs( + self.dev.as_raw(), + size, + self.cpu_addr as _, + self.dma_handle, + self.dma_attrs.as_raw(), + ) + } + } +} + +/// Reads a field of an item from an allocated region of structs. +/// +/// # Examples +/// +/// ``` +/// use kernel::{device::Device, devres::Devres,}; +/// use kernel::dma::{attrs::*, CoherentAllocation}; +/// +/// struct MyStruct { field: u32, } +/// +/// // SAFETY: All bit patterns are acceptable values for `MyStruct`. +/// unsafe impl kernel::transmute::FromBytes for MyStruct{}; +/// // SAFETY: Instances of `MyStruct` have no uninitialized portions. +/// unsafe impl kernel::transmute::AsBytes for MyStruct{}; +/// +/// # fn test(reg: &Devres>) -> Result { +/// let alloc =3D reg.try_access().ok_or(ENXIO)?; +/// let whole =3D kernel::dma_read!(alloc[2]); +/// let field =3D kernel::dma_read!(alloc[1].field); +/// # Ok::<(), Error>(()) } +/// ``` +#[macro_export] +macro_rules! dma_read { + ($dma:expr, $idx: expr, $($field:tt)*) =3D> {{ + let item =3D $crate::dma::CoherentAllocation::item_from_index(&$dm= a, $idx)?; + // SAFETY: `item_from_index` ensures that `item` is always a valid= pointer and can be + // dereferenced. The compiler also further validates the expressio= n on whether `field` + // is a member of `item` when expanded by the macro. + unsafe { + let ptr_field =3D ::core::ptr::addr_of!((*item) $($field)*); + $crate::dma::CoherentAllocation::field_read(&$dma, ptr_field) + } + }}; + ($dma:ident [ $idx:expr ] $($field:tt)* ) =3D> { + $crate::dma_read!($dma, $idx, $($field)*); + }; + ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) =3D> { + $crate::dma_read!($($dma).*, $idx, $($field)*); + }; +} + +/// Writes to a field of an item from an allocated region of structs. +/// +/// # Examples +/// +/// ``` +/// use kernel::{device::Device, devres::Devres,}; +/// use kernel::dma::{attrs::*, CoherentAllocation}; +/// +/// struct MyStruct { member: u32, } +/// +/// // SAFETY: All bit patterns are acceptable values for `MyStruct`. +/// unsafe impl kernel::transmute::FromBytes for MyStruct{}; +/// // SAFETY: Instances of `MyStruct` have no uninitialized portions. +/// unsafe impl kernel::transmute::AsBytes for MyStruct{}; +/// +/// # fn test(reg: &Devres>) -> Result { +/// let alloc =3D reg.try_access().ok_or(ENXIO)?; +/// kernel::dma_write!(alloc[2].member =3D 0xf); +/// kernel::dma_write!(alloc[1] =3D MyStruct { member: 0xf }); +/// # Ok::<(), Error>(()) } +/// ``` +#[macro_export] +macro_rules! dma_write { + ($dma:ident [ $idx:expr ] $($field:tt)*) =3D> {{ + $crate::dma_write!($dma, $idx, $($field)*); + }}; + ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) =3D> {{ + $crate::dma_write!($($dma).*, $idx, $($field)*); + }}; + ($dma:expr, $idx: expr, =3D $val:expr) =3D> { + let item =3D $crate::dma::CoherentAllocation::item_from_index(&$dm= a, $idx)?; + // SAFETY: `item_from_index` ensures that `item` is always a valid= item. + unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item,= $val) } + }; + ($dma:expr, $idx: expr, $(.$field:ident)* =3D $val:expr) =3D> { + let item =3D $crate::dma::CoherentAllocation::item_from_index(&$dm= a, $idx)?; + // SAFETY: `item_from_index` ensures that `item` is always a valid= pointer and can be + // dereferenced. The compiler also further validates the expressio= n on whether `field` + // is a member of `item` when expanded by the macro. + unsafe { + let ptr_field =3D ::core::ptr::addr_of_mut!((*item) $(.$field)= *); + $crate::dma::CoherentAllocation::field_write(&$dma, ptr_field,= $val) + } + }; +} + +/// Helper function to set the bit mask for DMA addressing. +pub const fn dma_bit_mask(n: usize) -> u64 { + if n > 64 { + return 0; + } + if n =3D=3D 64 { + !0 + } else { + (1 << (n)) - 1 + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 398242f92a96..8e76ef9b4346 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -44,6 +44,7 @@ pub mod device; pub mod device_id; pub mod devres; +pub mod dma; pub mod driver; pub mod error; pub mod faux; --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (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 43B0B216394; Fri, 7 Mar 2025 11:08:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345725; cv=none; b=js/ZMygex1W2bPUnn9iUZkmjREJJ/CncTg4O1ww78BN4SeOBfp22JAN4N4fmzOJ8ketJYM7jOgvbnNb28VHTcVgqX967IjHqPqIrsZosdEgj6dlkquupNG4p+wu9FQYjo60OGImpaD50yHUgCia1E3oFO9D6kynJaS4kcr70Ra4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345725; c=relaxed/simple; bh=nWi1w82ZlChughw2atxEeA1HOxW2EcSlkpcjamzBmkA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W6eSk19BPgLi1fGUhdcyCdRHzv7p5l9o7R369VfWsaHbwpMfQ46EwZ+1mud6LjkM2SOuHTxiWPcgcep9jbgzfKR3zHJJvi19CSoX8qIwxdGPuCseIJmLRdXS+OVrLhKg2SIx4AzGWqyX5MngYegosf+EN2TpYOP4y68qqPG6wSo= 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=EcHIiHYS; arc=none smtp.client-ip=209.85.167.43 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="EcHIiHYS" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-549946c5346so351444e87.2; Fri, 07 Mar 2025 03:08:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345722; x=1741950522; 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=SZBUDcLiga65o3ONmY3eoTnwBjqCQOBm6Uo217lnuaM=; b=EcHIiHYSfCw3n6d7fq8lhSRBopNtJpuy2MBrkzILk4CIE+h0CcRPr9gTe1HHuD393O +vc9/ivdRzmIbPc+QPTAVvVLzx1c1vGB4j23PRU1jKsf899k0pRTqpzbzk8lZ6uuO/VL LutFfl0WND0gxuHzUbKRXU24bG0Ef99sjSzteJMyKzygSEqu/o3mpPdE1vO6mVfk39fD fNcWdckuZs51cK1xb8ut08lfRYkytqcJ6RKgd9vWgheKTmEddeG9HfeMmjQkjeyQ7Jfd hzi4WZPINtbNKX6gxuoe66B/BQHJicl6eYMuFsGGQlgTP+bW70v6kpJbNO1168uT0dmF jhIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345722; x=1741950522; 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=SZBUDcLiga65o3ONmY3eoTnwBjqCQOBm6Uo217lnuaM=; b=pZYstDdf+GIbYFWaSKuIC/WHT3HHqpsd7OLmuN1yPV9/+9zWlS1aRb8FwY3EcBg1dJ Jsn9IRSx98kROlfc7+7Pbx44xKvU5vcMUHNFWB2pvLWP28jJtR1miHQBQ4HNqf7tzSAz ORHoIOxLRgwdspgmbav18OghXNgoC4Zbip0NNLCGI8ojEt1nK2MVJEAkUx1WQsJBXpXy 8stkcxXGzTKjPDmtrmpb2BZxL+bmtZap6vqUJD5eTivYHEsERbjG+b5rXiEPcb4EC8Xn V6tnfh2QWlT+vzgz7jFbGIDnTp/yENpBzoOK1MSOQ2q5duJOfSx65q8zUVr1/tDNH096 ODgw== X-Forwarded-Encrypted: i=1; AJvYcCULuezlp9WvqPgFnOzIoUeVi8bxwoZtC7Pr8pHFB4o7Sp8nt+ojkroCRTAh8LQCPDHYMJJl5R6u+SV5gsU=@vger.kernel.org X-Gm-Message-State: AOJu0YzZOg6QnC4ZZLe0Jn72gHEIsc2FMkMDJUKchp7RAlFdk8kykHUC DS/GQK/dTG+ENK2apUNJLGaWy1wVZzwmpKfOwSfkXJ6HoiCmkzTYMZoCmw== X-Gm-Gg: ASbGncsvlkCsAuJFYEsk0DD07KgHe8qwb9vUeEAIRvErGzyaa+gY8ghRfynplHYxmLi RABgalTlx7Bxtmy+hljTk0FZ/NKhWssyh564037juiztcp4JF3jOvVop9zjEUlpy7t6nNZSKDUa 6NJQ3/IPMWUMBHVX4q/LaBwCWSFiiAl3aBzxWOkJdkWgtCUV01TVSzZ+hG34EGnW8cvMQSBq8E1 XeBh+YtQ2nH/vDIGOrH8a2d2Qolmd/KgGWbtRyKRwPPs43Cr+fPJfNFOEojqzOysuCM9IU7Siv5 N/+fDX2aubw7cBY+TARSQLN4ZJVyeSlur+6n3+6YoDaHpB6MQsasP69o0DFoj/dgbHAxrbrjL// g2ZhPTDIrJ/8zddqcRcI6pw== X-Google-Smtp-Source: AGHT+IH0pmG5mntX/CHSlfv4qG5i5KqvwH+6uqJ1o8DOk4THqW5aC9xKMtC/IYhgCK730wYpu9WZGg== X-Received: by 2002:a05:6512:39d4:b0:549:39d8:51ef with SMTP id 2adb3069b0e04-54990e29b80mr1027667e87.6.1741345721906; Fri, 07 Mar 2025 03:08:41 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:40 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS) Subject: [PATCH v13 3/7] rust: pci: impl AsMut for pci::Device Date: Fri, 7 Mar 2025 13:06:20 +0200 Message-ID: <20250307110821.1703422-4-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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" From: Danilo Krummrich Some device methods require mutable references, since they change the underlying struct device without lock protection. Hence, make it possible to retrieve a mutable reference to a Device from a mutable pci::Device. Signed-off-by: Danilo Krummrich --- rust/kernel/pci.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 4c98b5b9aa1e..141430dac2d5 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -432,3 +432,14 @@ fn as_ref(&self) -> &device::Device { &self.0 } } + +impl AsMut for Device { + fn as_mut(&mut self) -> &mut device::Device { + // SAFETY: + // - `self.0.as_raw()` is valid by the type invariant of `device::= Device`, + // - `struct device` is embedded in `struct pci_dev`, hence it is = safe to give out a + // mutable reference for `device::Device` if we have a mutable = reference to the + // corresponding `pci::Device`. + unsafe { &mut *self.0.as_raw().cast() } + } +} --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 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 DE29A2163A8; Fri, 7 Mar 2025 11:08:45 +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=1741345729; cv=none; b=SkngRfJnOIyuzIp65fKdJHeY9nAU3pSn+6KKifcoNweg7TIKJPDj5DgQ3g7yrd9ZBC5ntJYypaYDdm/py1Hdw04DAVT8rEhjwduMZrTZL11WzUSMbmzxxNuHuGppuuePBtJKQzqEYRxrwYD+++swOXHiQTVO0A8dCGqEw4Afm+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345729; c=relaxed/simple; bh=NFKIAidxnRMlrYELYDQT43QLdnHioABterAjD1+vLGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GwHFiqco5eKrAaOK0NG0slzBftxU92h1i3guHaDyg3m+14ex7mUlRg+qNIEuG875jKAyCaRQMJpya5mZmsogvX2lTuDEGsutgSrN2p+DN9yShUq3Qvbk21KAxpC8XLnwWd+2115/VogZmwtIsPbHMnpPTMANs65l6uTrNnkxgXI= 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=iJOVcQWe; 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="iJOVcQWe" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-549946c5346so351469e87.2; Fri, 07 Mar 2025 03:08:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345724; x=1741950524; 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=Bna1rbJPQWibEFwv4J1kDTSY5U7INmYTRZbd16nD/nc=; b=iJOVcQWeSWibvkunksfU1XYIryqmI1QAv5MN2XiSSDQnKm0Mxw9juMuOwi0HREQGrM eIdXQgsLCLalgoRwoRXPdMeeAx3EHk7DZpibxXJHc47Hzu2uOKwhGgp0TSHdn9NIG5P/ Tr8F0B771ZfP822UwR+ZVWnyatdaiviLEepM2Ugv0t2IsPGij/AvP68o1OfSoUTFdX9w pTIz9BCjgwKEfZLpthdhowEehOtkkirLrm6z+GAB0LMRE7dgVCAAV3+i5JCeedpLfujy bgh18Vwg1FOQRC8z4hq7Uy4W2IHPjWm2ii3xYnrNRYWLRYIw0J8ffAUJG9zBbGVj49Ih y2UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345724; x=1741950524; 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=Bna1rbJPQWibEFwv4J1kDTSY5U7INmYTRZbd16nD/nc=; b=JOmQitW603PNYdh1tvI0Xyjl5OzcHba7Lui9ut7qvqrTp0KUnDO90zuouHTAr1IOkr K/yG/XkMuYeRej79Pyd/nNKOlCd97oUGYzoEfT8EZa49bhdArjk12EDTJno9GSpKNZ4a 2UGDNXJ+p0qnehTej8UOro+HPZQJArynFJyRMjR46avvS7Jgq5/gtqrJMgDQyosuQ33D KtZckrC4ixz4tWmqmodTE0/nVMRibRS9EweR93OFX6tukMz2ul0wBnDLNfn+S1n76lM0 eq/JjnwjCa3+JGzSnywNLbj1QiiMaRZuIxQUUBwgqBGjgM9RCHtHVNBCpvz4hwU7hb9T 6WEw== X-Forwarded-Encrypted: i=1; AJvYcCVEAHfIXO2NNZPAIRA9prPT7HNzgrDqm5APzUjPhneAcSr8Z/Ts9TyrLxVSiyfmoJrnkzYXHup+hgLYZCc=@vger.kernel.org X-Gm-Message-State: AOJu0Yy6NVR9yRGv0eyKPthTRxqti0CqyBUDiv7qu+w/5AkSGlf+9hUt +r0UasWQ893UaDjrCbPJsPisXjcXtPtHX/CIcCP2K86La4wuYPov3dozhQ== X-Gm-Gg: ASbGncuvVPXvcafESsA1AkgBOebVmjESIR7i+DzfHTNP6maALmvUc0IzZA7S+YWM9sy y1BpRxIWf6iruvk6fOn56eI28F0nExitGIyRqhhbLQOJzVnHV7xEHTXFO7aDTBWpXocnykIHu+7 1XanLNZp9NPm+IFEatDplaauLm7+OQrYOMYxbGQI4kvQWLR7Eo7gwWqrQ3bBnlwhSghKB52IWwJ YKvrUmkgfvxetLdFsGD9Y4KADLHrG1vtapK9t94W+rYelINPduA0KKiC2VcUqhzJq07ZJL9AsEX 6uzUFgj/vhgIBIxcDrLTqlNl2p7J++PdPnoXVOj82XVHlYrAZXs6tzn4OBUt+ACnfvoIzjH04JT +m7tTxDEjTnvDnn2pYNOWEA== X-Google-Smtp-Source: AGHT+IHjaZ7I8vrWUm2jSrf2K7izD3GQ+2svxuHCSAb3JqdODUfWFeX8SdZqFx0ZMpsg2ApCZyJSYg== X-Received: by 2002:a05:6512:1597:b0:549:8cc8:efed with SMTP id 2adb3069b0e04-54990ebb232mr1066828e87.48.1741345723841; Fri, 07 Mar 2025 03:08:43 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:42 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 4/7] rust: device: add dma addressing capabilities Date: Fri, 7 Mar 2025 13:06:21 +0200 Message-ID: <20250307110821.1703422-5-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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 functions to set the DMA mask to inform the kernel about the device's DMA addressing capabilities. Signed-off-by: Abdiel Janulgue --- rust/helpers/dma.c | 8 ++++++++ rust/helpers/helpers.c | 1 + rust/kernel/device.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 rust/helpers/dma.c diff --git a/rust/helpers/dma.c b/rust/helpers/dma.c new file mode 100644 index 000000000000..8eb482386f93 --- /dev/null +++ b/rust/helpers/dma.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +int rust_helper_dma_set_mask_and_coherent(struct device *dev, u64 mask) +{ + return dma_set_mask_and_coherent(dev, mask); +} diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 0640b7e115be..8f3808c8b7fe 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -13,6 +13,7 @@ #include "build_bug.c" #include "cred.c" #include "device.c" +#include "dma.c" #include "err.c" #include "fs.c" #include "io.c" diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index db2d9658ba47..f9d3d4f60ddb 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -6,10 +6,12 @@ =20 use crate::{ bindings, + error::Result, str::CStr, types::{ARef, Opaque}, }; use core::{fmt, ptr}; +use kernel::prelude::*; =20 #[cfg(CONFIG_PRINTK)] use crate::c_str; @@ -187,6 +189,33 @@ pub fn property_present(&self, name: &CStr) -> bool { // SAFETY: By the invariant of `CStr`, `name` is null-terminated. unsafe { bindings::device_property_present(self.as_raw().cast_cons= t(), name.as_char_ptr()) } } + + /// Inform the kernel about the device's DMA addressing capabilities. + /// + /// Set both the DMA mask and the coherent DMA mask to the same thing. + /// Note that we don't check the return value from the C `dma_set_cohe= rent_mask` + /// as the DMA API guarantees that the coherent DMA mask can be set to + /// the same or smaller than the streaming DMA mask. + pub fn dma_set_mask_and_coherent(&mut self, mask: u64) -> Result { + // SAFETY: device pointer is guaranteed as valid by invariant on `= Device`. + let ret =3D unsafe { bindings::dma_set_mask_and_coherent(self.as_r= aw(), mask) }; + if ret !=3D 0 { + Err(Error::from_errno(ret)) + } else { + Ok(()) + } + } + + /// Same as [`dma_set_mask_and_coherent`], but set the mask only for s= treaming mappings. + pub fn dma_set_mask(&mut self, mask: u64) -> Result { + // SAFETY: device pointer is guaranteed as valid by invariant on `= Device`. + let ret =3D unsafe { bindings::dma_set_mask(self.as_raw(), mask) }; + if ret !=3D 0 { + Err(Error::from_errno(ret)) + } else { + Ok(()) + } + } } =20 // SAFETY: Instances of `Device` are always reference-counted. --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 Received: from mail-lf1-f45.google.com (mail-lf1-f45.google.com [209.85.167.45]) (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 064DA2163BA; Fri, 7 Mar 2025 11:08:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345728; cv=none; b=ozDQtS6Z5vKvdIr4nowuscTUG8lNSw8kwmZHOEAXWK/WZ2th5y814f2gapJCYu2GSWyt+dXhys77GOzgriH5kJiKhdYQn5yvBTd9/YyXwPnH5X7gorGs53BeonIiiS8C0UvYMMiiGjRrfOexiVXPRo5Z4weC1F++SgPNgMdy8PE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345728; c=relaxed/simple; bh=fWkCL8BMSYNMfEbrDrnuytIEF1WS+GC8K9E0V39YodU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O/XKO8oEDUdwa9BGHjaPVJ0CtD/47oMaoGLSbci5Yn3apiZxQlmqFfZvxQmTowbiUlBNJsltkXXIuE76BPBNyNu4CocFcDQ75obk1/lfEzq+aHNVzKmMyT8IRKRhIqPZ91Alzva2/X6+IJorePuVyBdNd7c/ZWpIaxVyn9eL2y0= 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=G35Pw9hK; arc=none smtp.client-ip=209.85.167.45 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="G35Pw9hK" Received: by mail-lf1-f45.google.com with SMTP id 2adb3069b0e04-5497590ffbbso1956470e87.1; Fri, 07 Mar 2025 03:08:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345725; x=1741950525; 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=JjRzcycbu56jCOb7vRNRwX3YWPCEzPaeoXXPekHZQFg=; b=G35Pw9hKozp1SLGGeYYiSrQ0sdrEUGOPW/VU7sSnikUUWzksOgdAkW/KLa7J/vaTHU LITvXQlX7F1sZEoRQl2R96LSKI7yXtL1N9HeUZ1Wb1JPjKg31e1V+z3qe3Hl67bBrN9p Ghq0hu7SMOS8V/U8Qs61wExHmwKOEsLYA2me09I6P214HzrPv2d8lR2PXaYYC4ICKFbj i4lNhrpzJ/b+wfUvVaO1jW2vjXBIrbru0TWcSls6Q4Rv/tiGevDrSpVzFdgnPKRr4lkY 1+ArijcFifZfdLR9tvZcqma5lw1VqsNHRUqGgAWwe22GnNo5o7YM5QCbKRyK8COAcD0f tI2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345725; x=1741950525; 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=JjRzcycbu56jCOb7vRNRwX3YWPCEzPaeoXXPekHZQFg=; b=XAHf5Nl0EFZPMd+ZJrOmEXB329in5GNVZcOMPNVoJxcly8Sxh+qn4zKf+L18qMYFZK 7y6A4ohwSzVCFDJu0+r22vRQzaLTfrBfvIsLvbcO6Kth9kfniyowJKAdCV8Q6T/f+p30 Ft2TB0j6By85rAB9WQHEcfJ21xfwjBX7EAjoaHXAvxFyY83oV7WaEqMjLglRVqe3VuEV BuUiBiYDk46DW7IRGN1HZ9uAKCsAofENBAjU/m2cPtyUhZ8+bzBQNcVw+v9R6U8BeQn6 DedT14kvypmJnnzzKYSFTdG29ylz5NRLInkMNABtfNvGDCAala4aOPhahCFFNS3ag8sg bh9Q== X-Forwarded-Encrypted: i=1; AJvYcCXIyy3ZeTjmkJChO8OPTrmr+KWeIy+Zk0uZQFkj9Iy7AmkocTGcev3/zmicffhZw1Je7ZLXIvU/AB/Wo1w=@vger.kernel.org X-Gm-Message-State: AOJu0YznOgjZjbKI+35Oc2802lWSBXmikOvmnFSR4MoFhs912H7SKCT1 X030u/ZqiEKDgUrtDvCSfWBG5VvDLECyVKXvASK7O8HthVoDyowVuihgcA== X-Gm-Gg: ASbGncvB51dpdV7R/xivyEiPkF5gEnwTKXI/FpmNf52/qWzlSKGwHe6Ackk2V+eoxNT Y6jX+TkavNKrntqOY3YJvusYnOuB3vaO+zzlHGYHJXrsx4eyu9rYz4nQ/rwh9F+Q4kcwkE+i1aq /9zE3dmGnKD540twnqnnA7BLuD3PG+fsauG4zWYQd6P6XbSjm5/J92OnteSfFISpBqAKeMErLZt hTb2uJKhREwKzhiuolEyLeync8b5JbTdmlIZC6usqvEhRygp1C/fIf9GkQI7jelfbsCYuVWiR6U E4v4ZxeLOUPtpo9khbm8MvSdkVT7Hk+q7I8UEsg4dUqHTM1GwMKB8haGfBLSjG0zYTthMzUMPnh 3rJua+0GlgEoQS5X8yucryw== X-Google-Smtp-Source: AGHT+IFjoxl6eClgg1VA0EEBG5W1vMJn01ur8ijpiShnc8E2q98l9Vo8EwdrO+pPkvWO3BDH5B5Afw== X-Received: by 2002:a05:6512:b99:b0:545:2d4d:36d1 with SMTP id 2adb3069b0e04-54990e5d4e3mr996613e87.20.1741345724809; Fri, 07 Mar 2025 03:08:44 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:44 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 5/7] samples: rust: add Rust dma test sample driver Date: Fri, 7 Mar 2025 13:06:22 +0200 Message-ID: <20250307110821.1703422-6-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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 a simple driver to excercise the basics of the Rust DMA coherent allocator bindings. Suggested-by: Danilo Krummrich Signed-off-by: Abdiel Janulgue --- samples/rust/Kconfig | 11 +++++ samples/rust/Makefile | 1 + samples/rust/rust_dma.rs | 104 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 samples/rust/rust_dma.rs diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index 3b6eae84b297..04bbba870bd1 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -78,4 +78,15 @@ config SAMPLE_RUST_HOSTPROGS =20 If unsure, say N. =20 +config SAMPLE_RUST_DRIVER_DMA + tristate "DMA test driver" + depends on PCI + help + This option builds the Rust dma test driver sample. + + To compile this as a module, choose M here: + the module will be called dma. + + If unsure, say N. + endif # SAMPLES_RUST diff --git a/samples/rust/Makefile b/samples/rust/Makefile index 0dbc6d90f1ef..1a9aff6e8d6a 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_SAMPLE_RUST_PRINT) +=3D rust_print.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) +=3D rust_driver_pci.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) +=3D rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) +=3D rust_driver_faux.o +obj-$(CONFIG_SAMPLE_RUST_DRIVER_DMA) +=3D rust_dma.o =20 rust_print-y :=3D rust_print_main.o rust_print_events.o =20 diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs new file mode 100644 index 000000000000..aed55ae4dcfe --- /dev/null +++ b/samples/rust/rust_dma.rs @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust DMA api test (based on QEMU's `pci-testdev`). +//! +//! To make this driver probe, QEMU must be run with `-device pci-testdev`. + +use kernel::{bindings, dma::CoherentAllocation, pci, prelude::*}; + +struct DmaSampleDriver { + pdev: pci::Device, + ca: kernel::devres::Devres>, +} + +const TEST_VALUES: [(u32, u32); 5] =3D [ + (0xa, 0xb), + (0xc, 0xd), + (0xe, 0xf), + (0xab, 0xba), + (0xcd, 0xef), +]; + +struct MyStruct { + h: u32, + b: u32, +} + +impl MyStruct { + fn new(h: u32, b: u32) -> Self { + Self { h, b } + } +} +// SAFETY: All bit patterns are acceptable values for `MyStruct`. +unsafe impl kernel::transmute::AsBytes for MyStruct {} +// SAFETY: Instances of `MyStruct` have no uninitialized portions. +unsafe impl kernel::transmute::FromBytes for MyStruct {} + +kernel::pci_device_table!( + PCI_TABLE, + MODULE_PCI_TABLE, + ::IdInfo, + [( + pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5), + () + )] +); + +impl pci::Driver for DmaSampleDriver { + type IdInfo =3D (); + const ID_TABLE: pci::IdTable =3D &PCI_TABLE; + + fn probe(pdev: &mut pci::Device, _info: &Self::IdInfo) -> Result>> { + let dev =3D pdev.as_mut(); + + dev.dma_set_mask_and_coherent(kernel::dma::dma_bit_mask(64))?; + + dev_info!(dev, "Probe DMA test driver.\n"); + + let ca: kernel::devres::Devres> =3D + CoherentAllocation::alloc_coherent(dev, TEST_VALUES.len(), GFP= _KERNEL)?; + + || -> Result { + let reg =3D ca.try_access().ok_or(ENXIO)?; + + for (i, value) in TEST_VALUES.into_iter().enumerate() { + kernel::dma_write!(reg[i] =3D MyStruct::new(value.0, value= .1)); + } + + Ok(()) + }()?; + + let drvdata =3D KBox::new( + Self { + pdev: pdev.clone(), + ca, + }, + GFP_KERNEL, + )?; + + Ok(drvdata.into()) + } +} + +impl Drop for DmaSampleDriver { + fn drop(&mut self) { + dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n"); + + let _ =3D || -> Result { + let reg =3D self.ca.try_access().ok_or(ENXIO)?; + for (i, value) in TEST_VALUES.into_iter().enumerate() { + assert_eq!(kernel::dma_read!(reg[i].h), value.0); + assert_eq!(kernel::dma_read!(reg[i].b), value.1); + } + Ok(()) + }(); + } +} + +kernel::module_pci_driver! { + type: DmaSampleDriver, + name: "rust_dma", + author: "Abdiel Janulgue", + description: "Rust DMA test", + license: "GPL v2", +} --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (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 B5103216E20; Fri, 7 Mar 2025 11:08:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345731; cv=none; b=oLN+gfMPWiHC4REnAeJrb4GhNJdfCaIShU3dE2DOYPGjgYygAX5C5CGdxTUNiPvqaBOoqGvHvxqBHLjx72LVdHVWRaTkMxl5vIfAmNL2WMyL1IpgcArmFMoScNCFoDgAn8iDGCZGHAOWAp80Z5te6r/Tq5dpXfpyMUL9wgfgVSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345731; c=relaxed/simple; bh=EXM0h+nNXEzWwA+37YY+ZOrUkAfwYMWN8MLzC5oEIWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aH425JQx230mGH1IXkzIPjaqA7UBtZPGtzbN5NNq+oMmChKFrDdxbSG4JcS2CXTeDDsMNILrKmMLYwVsidtoiA4sGFlWZYo9NNVumKsZO6wf9NnzbCP3qvpORy3jPFiiL/Gy3kF1q33iLfr0FUGAeWsh2VZsM9JaMFLxoRdHhaM= 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=kSEkiGvZ; arc=none smtp.client-ip=209.85.167.51 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="kSEkiGvZ" Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-5495078cd59so1968828e87.1; Fri, 07 Mar 2025 03:08:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345728; x=1741950528; 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=HLJkp6MLOD1BiDeGrlidAjVqoKEfJEO/erWzBeDn7QE=; b=kSEkiGvZP9KF4tYX3b41caa3EJin+bxlzR8s6UiHLY/e/94cKrOHqHvZVu1t/veP4Q j7umQo0z/zQ+UMWxdZd7D1HNVByn1kkYy+ZwE0cCiulJzjLb5l0RNNAJBAD8qq4RGpVJ STLko6aIrPVCzApEYMd/7jIwd2ps13juJII7IiTsa1WfllQrHDDngtYEi/0tqvQmPv4y I1UMJbeJSoDbOsS47275WepqQbHp1D4uWWh+jcDXKTOOZjbg6ZgLQHW6w+EAN7wMNYF/ ps1BjSNKK5QusdqI8JnB4L/1+tn1TgO7C3mewvnH1w98cjSBLxbqg0iG9zhRulZxwL0a 3Y2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345728; x=1741950528; 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=HLJkp6MLOD1BiDeGrlidAjVqoKEfJEO/erWzBeDn7QE=; b=fWzZoQUw13caAAuAZzEOJtw8p4CImFqO1aMWEMugYEJSoHI7zYAd6+FJlX+xiu/l44 wLHylvIBzzeU34pJa8BB1T9xUAU92EIA4s5SzKSAYbsXvBbVMDWgCt5FDSpBiRZu1Sht zjGP2thyDf3kPjcDBKyvayrq+1/KlSJ0G/w36jT/v+R1w+mdH4GGZo9XX280WsP9PBuV kHsO+9Ds00Da7SUuW1TLALeyyR4DL7xgybQxDnVY+/G20SF2uOPMWOIQiD/CNN7as4Cp GXvnrl7zpu4yCixEMnMaL7zaW82P/VoVegtG8L4us/K5IJxkeujdf+P1zhCVpD0xeSdr yhPw== X-Forwarded-Encrypted: i=1; AJvYcCWTU0xk/umODhJEWPCgdyTNVxN0HZ8KDmLn9Fez6pihWgYlCB532LQ0BzuOd8KpQ82lx+XclsYeFw4AzzI=@vger.kernel.org X-Gm-Message-State: AOJu0YwCXzbe93s6gsHx4E4JtZNzWLDaEYZPhDdrFs/Z72CIxefI4cBW m07lYEhoqXnqFNYJIyPHAfJKXKm2LxTJ+ogXKWuGNu/WWJpHUOJTs4Wbsg== X-Gm-Gg: ASbGnct55uaQEw7v/xEvsBImhooVG/sElIuuEM8vusKE4WesG1c6AFAc9v6PREswA1T Zf3uz8sxuedqZNRlTPd2AOLmcT782YTwf91DPR/SOu68BAme5HJ2hMkLIvosVfXp6WfbtVumaTD SvHGZvar3pEiQ3i1+4m/VRmoVVpDWtUYRQMOSjK/nDQuDVHG0eFVxvU+N1xE2lRPqe5B3ztpFcc QJo/9m1c/Da/wWT1cmOcPhqhuCZQpuVWsN5qG9mvXGbdioPfX+CP/uXDYeIqbmAMqxkDmA/cPA2 nuvEdacxkhaK2STGESRQaL83KzN+Tziu2wEPwizewSBcs1BNhIEZP7BuY+tmw4GTAcf60OCgbwc Tb+m3+g5xETwrKalxBtt8xw== X-Google-Smtp-Source: AGHT+IGiGpe6CSJJtkufhdPB5iGLtwq4UxbrTZKaH5A1Wg2RvJPmdaO+/Wjn/2beT+7PpJmdLcSDmg== X-Received: by 2002:a05:6512:3dab:b0:549:8d2a:880d with SMTP id 2adb3069b0e04-54990e5005fmr900677e87.21.1741345727697; Fri, 07 Mar 2025 03:08:47 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:46 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 6/7] MAINTAINERS: add entry for Rust dma mapping helpers device driver API Date: Fri, 7 Mar 2025 13:06:23 +0200 Message-ID: <20250307110821.1703422-7-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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 an entry for the Rust dma mapping helpers abstractions. Nacked-by: Christoph Hellwig Acked-by: Danilo Krummrich Acked-by: Andreas Hindborg Signed-off-by: Abdiel Janulgue --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 12f2d79ce174..72daf5db0242 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6902,6 +6902,18 @@ F: include/linux/dma-mapping.h F: include/linux/swiotlb.h F: kernel/dma/ =20 +DMA MAPPING HELPERS DEVICE DRIVER API [RUST] +M: Abdiel Janulgue +M: Danilo Krummrich +R: Daniel Almeida +R: Robin Murphy +R: Andreas Hindborg +L: rust-for-linux@vger.kernel.org +S: Supported +W: https://rust-for-linux.com +T: git https://github.com/Rust-for-Linux/linux.git rust-next +F: rust/kernel/dma.rs + DMA-BUF HEAPS FRAMEWORK M: Sumit Semwal R: Benjamin Gaignard --=20 2.43.0 From nobody Sun Feb 8 03:58:31 2026 Received: from mail-lf1-f52.google.com (mail-lf1-f52.google.com [209.85.167.52]) (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 BD5EB217648; Fri, 7 Mar 2025 11:08:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345733; cv=none; b=gz/y8ogN23pEWt/+h+vl1wngrIrXG5w8Oy5iD5tUPTsQ6I/TON3Q6K8f0OYKEP+JvCBIYeo6Y4Ad3Y+3Nbc6/5ML3DFMJyE0zz3Y7iamsV/Xmwb/EL//xBDcjSWyN7NnDSGVTpVnkfAIu8M3JF9OTXUqZz0zwqgjC1Uy6T2uXQE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741345733; c=relaxed/simple; bh=rrOOzkjgFH92AX8ZIQzQ3stuSFWy3mIsSfUxBAk5e5o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CnrHL1o7mo9R3+v1g2/jUSp5SjFgu8AFK3ZRIM71UXVwpIeu8/M3uGFH5vwkHqzNnuXVmGjCnEYSVaE5pT56FDQ/p57oOShck1ejhiAywmgSsCZ2syAfvx7U1O6ixRKJFN2b2hLhf2eURfKBAGmkOtvRxRSFLWlh4iGGMA+Q3MI= 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=k/OCaOPh; arc=none smtp.client-ip=209.85.167.52 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="k/OCaOPh" Received: by mail-lf1-f52.google.com with SMTP id 2adb3069b0e04-5452c29bacfso1872760e87.3; Fri, 07 Mar 2025 03:08:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741345730; x=1741950530; 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=09GJYTVzja13f3kvBaJ1uBzOOCE24NR3g3J/ynL3xcg=; b=k/OCaOPhqgOeAnqEOeg1E5GO59tdtGZ1UXEpaOV2Tpj1JzkdUJQ7K930mGKKRe5kcv VK7xE1TpVQdv0QWnxF6URNeO7DFhWNGym7lEo8JpCelOq4Uq23RazEliz4W+Bd8TWwza eIAS6PNAAc2NBP5RM7FRHxfYBkE6oHmso0RmLfc9WzVJH8f5fn5dj1+OR+wf8eIyUKtu nDeoyWgtAoWMeJKuAIPLYBWtCWokLuHQfHd1j7F1iTL1edYEkXKG8wYrjV+v/1+Sp8yO cIH6U5PcFzJjZ2zKBUOQKsDW03tuf+BbuCAD5J6qTovo+2gb1wyxFAN+/tmaeXXTMwTQ lLig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741345730; x=1741950530; 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=09GJYTVzja13f3kvBaJ1uBzOOCE24NR3g3J/ynL3xcg=; b=Lu4AyQmSpVvE7EwO5kEMzRQ48YZggGGQO5/MTVMTOtBO/QwZDLll3xKSiOLdJQbf0+ 7ApLB16dbD40UrT3+oRJ/PJ80LK7ClWgTvdqHGeCuClP3TvPvwOGECbCZQK6vTUkMeX0 rbfMBJ8DBUU7slYymndcJr7No2r7XnAGPGDwlQkScupVdwGTdx3RRvmV0jLl8mrPzG2j ee+GuTzpZ51/4EJZoSTht3aEJhdIjcrvVVyb2FmT+6KiGuWKy4wNQdlv43CZAdvWlxkJ 7p9Ug+YnzsFOr1pOnUC1ejhiGeopkiAWNkRIBZChYSAM4//jdKDf9Qdkg0jh/5jsdbci fT2g== X-Forwarded-Encrypted: i=1; AJvYcCX7/9+gOefbSMIEPVy1an3s4DG7GMNCyjFxo6zqpClCc8G4R3edew1Vz/WUi+Q8aLOLIYMWyDPD0qDjZPo=@vger.kernel.org X-Gm-Message-State: AOJu0YwR3ptBGyvA+9aknvHXn/pknu9KHAHmQaahgagwLEGfhosR5LKp TH7ZJODlPNIvIMd/MMIIE3Sy3hAU2BvpFIw5z53HHj8DDP/nYAJA/jFlvQ== X-Gm-Gg: ASbGncsDdP+8GYCuQ5aY6g8aVcDq4RItYzIID6TyES/nSglxHYLDKHWWivnHUNdNGhq /pBp7IoNdmlkGoL9FsfziSK6oBmgnN2WyRWnwixX9tDu83zAUyt6YzV6MIQuido5+ssmi9dGagD abgeLJ9AwHq47pyP1DfMYxmiZDocZJGi24uxK8ZqUNTKj1RUZNYL8QT6e76c4AJBiDDXnVWipEx SR3DSb3Tph16g4xT+aQ6SX1XjM2vflX+d1VoJRg5FdyV5XzAJcL5YSvFGl4laLzB/SMAARkDhFR BByyvaZwOhA77SnRKVkKs8GXANMID4+sZAsXgOZeOX0DWxhswuXN2ooUVraYC+udOhWsvDyuQP7 fT4q5R3hGVpd52QtM6Fc/jA== X-Google-Smtp-Source: AGHT+IGdooSiaMhwC//4GREgXUoEIs+EBOffQpNGTyIYeDlunWJEPmlHzlIklF2/tY9bs8/u3NaQHQ== X-Received: by 2002:a05:6512:159a:b0:549:5c5f:c0c0 with SMTP id 2adb3069b0e04-54990eaca02mr905585e87.41.1741345729577; Fri, 07 Mar 2025 03:08:49 -0800 (PST) Received: from abj-NUC9VXQNX.. (dsl-hkibng22-54f8dc-251.dhcp.inet.fi. [84.248.220.251]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5498b1c2a08sm448920e87.223.2025.03.07.03.08.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Mar 2025 03:08:48 -0800 (PST) From: Abdiel Janulgue To: rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com, dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Trevor Gross , Valentin Obst , linux-kernel@vger.kernel.org (open list), Christoph Hellwig , Marek Szyprowski , airlied@redhat.com, iommu@lists.linux.dev (open list:DMA MAPPING HELPERS), Abdiel Janulgue Subject: [PATCH v13 7/7] rust: dma: add as_slice/write functions for CoherentAllocation Date: Fri, 7 Mar 2025 13:06:24 +0200 Message-ID: <20250307110821.1703422-8-abdiel.janulgue@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250307110821.1703422-1-abdiel.janulgue@gmail.com> References: <20250307110821.1703422-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 unsafe accessors for the region for reading or writing large blocks of data. Signed-off-by: Abdiel Janulgue --- rust/kernel/dma.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 8a250242641c..cee7adc2fc22 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -213,6 +213,92 @@ pub fn dma_handle(&self) -> bindings::dma_addr_t { self.dma_handle } =20 + /// Returns the data from the region starting from `offset` as a slice. + /// `offset` and `count` are in units of `T`, not the number of bytes. + /// + /// Due to the safety requirements of slice, the caller should conside= r that the region could + /// be modified by the device at anytime. For ringbuffer type of r/w a= ccess or use-cases where + /// the pointer to the live data is needed, `start_ptr()` or `start_pt= r_mut()` could be + /// used instead. + /// + /// # Safety + /// + /// * Callers must ensure that no hardware operations that involve the= buffer are currently + /// taking place while the returned slice is live. + /// * Callers must ensure that this call does not race with a write to= the same region while + /// while the returned slice is live. + pub unsafe fn as_slice(&self, offset: usize, count: usize) -> Result<&= [T]> { + let end =3D offset.checked_add(count).ok_or(EOVERFLOW)?; + if end >=3D self.count { + return Err(EINVAL); + } + // SAFETY: + // - The pointer is valid due to type invariant on `CoherentAlloca= tion`, + // we've just checked that the range and index is within bounds. T= he immutability of the + // of data is also guaranteed by the safety requirements of the fu= nction. + // - `offset` can't overflow since it is smaller than `self.count`= and we've checked + // that `self.count` won't overflow early in the constructor. + Ok(unsafe { core::slice::from_raw_parts(self.cpu_addr.add(offset),= count) }) + } + + /// Performs the same functionality as [`as_slice`], except that a mut= able slice is returned. + /// + /// # Safety + /// + /// * Callers must ensure that no hardware operations that involve the= buffer are currently + /// taking place while the returned slice is live. + /// * Callers must ensure that this call does not race with a read or = write to the same region + /// while the returned slice is live. + pub unsafe fn as_slice_mut(&self, offset: usize, count: usize) -> Resu= lt<&mut [T]> { + let end =3D offset.checked_add(count).ok_or(EOVERFLOW)?; + if end >=3D self.count { + return Err(EINVAL); + } + // SAFETY: + // - The pointer is valid due to type invariant on `CoherentAlloca= tion`, + // we've just checked that the range and index is within bounds. T= he immutability of the + // of data is also guaranteed by the safety requirements of the fu= nction. + // - `offset` can't overflow since it is smaller than `self.count`= and we've checked + // that `self.count` won't overflow early in the constructor. + Ok(unsafe { core::slice::from_raw_parts_mut(self.cpu_addr.add(offs= et), count) }) + } + + /// Writes data to the region starting from `offset`. `offset` is in u= nits of `T`, not the + /// number of bytes. + /// + /// # Safety + /// + /// * Callers must ensure that no hardware operations that involve the= buffer overlaps with + /// this write. + /// * Callers must ensure that this call does not race with a read or = write to the same region + /// that overlaps with this write. + /// + /// # Examples + /// + /// ``` + /// # fn test(alloc: &mut kernel::dma::CoherentAllocation) -> Resu= lt { + /// let somedata: [u8; 4] =3D [0xf; 4]; + /// let buf: &[u8] =3D &somedata; + /// // SAFETY: No hw operation on the device and no other r/w access t= o the region at this point. + /// unsafe { alloc.write(buf, 0)?; } + /// # Ok::<(), Error>(()) } + /// ``` + pub unsafe fn write(&self, src: &[T], offset: usize) -> Result { + let end =3D offset.checked_add(src.len()).ok_or(EOVERFLOW)?; + if end >=3D self.count { + return Err(EINVAL); + } + // SAFETY: + // - The pointer is valid due to type invariant on `CoherentAlloca= tion` + // and we've just checked that the range and index is within bound= s. + // - `offset` can't overflow since it is smaller than `self.count`= and we've checked + // that `self.count` won't overflow early in the constructor. + unsafe { + core::ptr::copy_nonoverlapping(src.as_ptr(), self.cpu_addr.add= (offset), src.len()) + }; + Ok(()) + } + /// Returns a pointer to an element from the region with bounds checki= ng. `offset` is in /// units of `T`, not the number of bytes. /// --=20 2.43.0