From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF6693EC807; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; cv=none; b=XlhSnWZP/H8/jV9m6mUAkz8isqlRdmcQSGHrVB/bb75d3G1TkhfRVbr9922teUcHKtR3w2thR47+w8v0CYcJOMbu35N6lnGVDSlGCDzYgUnaOHrUnSk9mCspKsieAxF4UBYy186FWWbJ4mXhW+mRUmkytlfCVThQOAd5cZfAjoc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; c=relaxed/simple; bh=WxqT1yF3M6tgWWKnYg9hdR2pSdYcRFC589aOlzkEKCo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qD1RdtX3OBauyRDgc8AMdMzdhRSpZZAkkqqj7/pPSVoia8fMM/JjFmyUhdq4QTyKJ0aMu6df5l3WE1anMBDu6VyBq5PrNghfCl96HCKfj5dT0G+0tObg3wJ6XJZVvRqexbY/OZUO5eDS64cihu770LGz1GlhojprugdrsYptMJc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GLmhoWjx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GLmhoWjx" Received: by smtp.kernel.org (Postfix) with ESMTPS id 62E34C2BCF4; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=WxqT1yF3M6tgWWKnYg9hdR2pSdYcRFC589aOlzkEKCo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=GLmhoWjxwhNm5JQ1ezCbtiJaIrtLZo2Kg7WS91JNU4wuyw9/mfFna74o4ACU877Kj nbTzDZv+M0xR3UeUMM4WNNtLDzCbO9tbdmvhSz9oCLySJzk1K+ytj4hDy83aWoBOiG BLZdA4S6hGjKDvD86SyT59KvbAdaGrxrVZrQi5UgnrklNsUah4S17QqEOs80deO+II O5IIK3uJabEXMREzHhNeMdNMh6soQnQ9nSmDe/Nt6lkvxIqqE4joPbtnM1RbXUgGLB gop9CisYmZQNve8eYRa4dTRfsb/St9R5E4s/nxheleKAY5sHEU8yFjFrJMkgK4l5nk Sug5eN/00n6Aw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D38BC79FA1; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:48 +0800 Subject: [PATCH v2 1/9] rust: sizes: add SZ_4G constant Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-1-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=1664; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=so+WuqU/pYd8/dKzBVqpgAsW0XebT6xqiODTucEx6fs=; b=w3XcLqR1VQevN3qWcQai1GYtPQNLzv+aBbIvX1piwpdczwbSyazqpxKHZg94TivRfbzcvqI1m qgIWbCsMq4qCZW9sotv5Hu+943CQnyirsVV6qvpcZoE6vXbrJ4Cb0t2 X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun SZ_4G is used by the Tyr driver when splitting the GPU VA range into user and kernel regions. Signed-off-by: Alvin Sun Reviewed-by: Daniel Almeida Reviewed-by: Gary Guo --- rust/bindings/bindings_helper.h | 1 + rust/kernel/sizes.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 4b31aa7f432f5..9bbe1538d7c7c 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -115,6 +115,7 @@ const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN =3D A= RCH_SLAB_MINALIGN; const size_t RUST_CONST_HELPER_ARCH_KMALLOC_MINALIGN =3D ARCH_KMALLOC_MINA= LIGN; const size_t RUST_CONST_HELPER_PAGE_SIZE =3D PAGE_SIZE; const size_t RUST_CONST_HELPER_GENLMSG_DEFAULT_SIZE =3D GENLMSG_DEFAULT_SI= ZE; +const unsigned long long RUST_CONST_HELPER_SZ_4G =3D SZ_4G; const gfp_t RUST_CONST_HELPER_GFP_ATOMIC =3D GFP_ATOMIC; const gfp_t RUST_CONST_HELPER_GFP_KERNEL =3D GFP_KERNEL; const gfp_t RUST_CONST_HELPER_GFP_KERNEL_ACCOUNT =3D GFP_KERNEL_ACCOUNT; diff --git a/rust/kernel/sizes.rs b/rust/kernel/sizes.rs index 521b2b38bfe77..b236573f0792e 100644 --- a/rust/kernel/sizes.rs +++ b/rust/kernel/sizes.rs @@ -132,3 +132,15 @@ impl SizeConstants for $first { } =20 define_sizes!(u32, u64, usize); + +/// Large size constants (=E2=89=A5 4 GiB). +/// +/// Only implemented for `u64`. +pub trait LargeSizeConstants { + /// `0x1_0000_0000`. + const SZ_4G: Self; +} + +impl LargeSizeConstants for u64 { + const SZ_4G: Self =3D bindings::SZ_4G; +} --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF52819644B; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; cv=none; b=OVTsJ1lJbTGtKM4kz7Hr2+2/ePcAYgPgQdgPysF9XXPkPlwNNUX6Tq71PN8RDn87DBYPb+2XPKiDFaJtEuYe0t2h6XibjPCxwhoo0JtPpjZCjqHo0zqw3VfCkcJiaDM1Srmlrx7Y4/AQjuTY38v18+MxKfeIpYveawKd3SYlVrM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; c=relaxed/simple; bh=tAJEHSAuTRx0EwppaN+WcZOoNCdsIpUxUwps4sDokJQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CR1RY2/lpsD3GlNWfh4VIN1IvvZ/QAkiw6dkfbTur75GO+nFJ58xStM4k7LvXZTq9MenGUy87ggFd+B5TyICBzLblqtm3wlZRQb3DMrSkufpiMTbSapeT1hFMULjuBYUCAVzt1V5fLhuC4/ki/+L8J78UAqOastzBi5kRNZN31o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Rbt2fYEQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Rbt2fYEQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 80456C2BD00; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=tAJEHSAuTRx0EwppaN+WcZOoNCdsIpUxUwps4sDokJQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Rbt2fYEQSS4C6EkdvC1fCToikE3BnUr2KIjHVVagi9tu7Irden05SaZW0kRUBOYvQ gbHhxXEwSG+UNMcnDcNzxFYCkhREKSXx9jgqjXeVbIK5RwtPT4kxwfw7XAsMed2c1W bWzasx772rdyAZ4tFhzbdhIohLbvZ9qg1f3pmTq8TFjAoVwuiXj6NREZmsUnWElSwc FlSrUHtUlMrBw3NxC4Oftm8StJ2mLAE0WKAKspm9LSOlRPS6rZd89SqxZi7338NBwR CWbJt7CBn5LiprSZE2MG4PImhAVM3oj/6sEREzGKWL+9CUauAAAjtp0AFd0j56bWG2 yil5XWrUYSH/A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58BF1C79FA7; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:49 +0800 Subject: [PATCH v2 2/9] rust: mm: add `task_size` helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-2-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=951; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=JO+2MVB8/0ZEX96oFL0eP1mAOKrIibNCaD5F9FcB8NY=; b=y55dyR98tdQkyQvRS1h0SbEjSI3cnaIDdg85SX7ZIaWbhXm+f+ZDU47osQZU2PcPwf9rjlhF1 PmbRd8EcCmSC8RgKm7nNWPDYFWRTaPzPs62nL8aNDxU+XaJ2TT4eU/T X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Expose the task's address space size. It is used by the Tyr driver for splitting a VM's GPU address space into user and kernel regions. Signed-off-by: Alvin Sun Reviewed-by: Daniel Almeida --- rust/kernel/mm.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index 4764d7b68f2a7..d2dfbb7d43972 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -149,6 +149,13 @@ pub fn mmget_not_zero(&self) -> Option> { None } } + + /// The size of the process virtual address space. + #[inline] + pub fn task_size(&self) -> usize { + // SAFETY: `self.as_raw()` is a valid pointer to an `mm_struct` pe= r the type invariants. + unsafe { (*self.as_raw()).__bindgen_anon_1.task_size } + } } =20 // These methods require `mm_users` to be non-zero. --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C40FA4398EE; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; cv=none; b=hDQljrutdzfe6PJA+YGa/FifJkwdYw7KTebeZSJludnLuBM/5HgoeqdNdNmbLiyuhaqJUIvTnzXX/Fo+eaNduTR+wVfUyYczqb8p61J4U5+J0NZWTgVsSS/xqfYylv6ff2y+5Sw08AON/xUd+JougrzrrKrY9njrwyW8W6rA5Y8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; c=relaxed/simple; bh=SWfJYfIhU0ceNaMeMrQOIvNiAm90QJeCPkReTr2kGwU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LdpN92xQSlWHq1GL7grOs7kmxTCyJAaQMvjo+YWeHF993xWH2WW0tRu/HbafBmL3fobScDCWL543OAdY6Jvm6qw25Do1i/yu5hgzxpqkE4ULkAITkzoc517Zfr8zkIGF77KZZg5AsNWv2vcx3PMcfSdI3IDVR2zYNS8r3NDx1b0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gdyYYfo6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gdyYYfo6" Received: by smtp.kernel.org (Postfix) with ESMTPS id 882C9C2BD04; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=SWfJYfIhU0ceNaMeMrQOIvNiAm90QJeCPkReTr2kGwU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=gdyYYfo6ympMHjvgiFpwAKnU3kXVjM1uvnukbRGTsAPHYmyW8/1iVrbmboys2RKja tBKJNCTHkhBEXhVpCpBADp/AV/sDgyK7HKFb5wbRqZ0kR+mNYzksc8e+I8BCiNxA6W 5euqlXCiqoc7AL0+RvVNNYY65DzBcDCJFasc9Vw5kgtMx+x7UiNVvNF1irLiE3Gk9u oQ5LN72w36XgArE53hrlaRRV75wC7ScqSY6HbyngRCIlTq/FFnEsLucF/VkVacFk20 Iuohx+i+2D8YkLgbn9K5o9JKVS8YF+0DVBncNlgwjW1VXX2iI2sLTGvUO9+34gt5fV Fqvk0lM7XAC9g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72702C79FA0; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:50 +0800 Subject: [PATCH v2 3/9] rust: sync: arc: relax `ForeignOwnable` for `Arc` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-3-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=1389; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=E65clxOu/qjNbqNDrRBBfaWHB/W/gvw7JStoVkgnAT4=; b=MUGHhOu/L1W8PlCpFLL38urACrHixCRiftGKCn8Otv2NxdConIIXRvD1Ykvxj2WGQejyHWiFX Ekf59qcvlzkAOxJxuDCwj7VDvVlSMLlwndY/CSRCVJX9QHiM1yLd55k X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Drop the `'static` bound so that refcounted values borrowing from a driver registration scope can be foreign-owned by the XArray abstraction. Signed-off-by: Alvin Sun Reviewed-by: Daniel Almeida Reviewed-by: Gary Guo --- rust/kernel/sync/arc.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 8ae0fe6f19ec0..9b582a815f888 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -363,11 +363,17 @@ pub fn into_unique_or_drop(this: Self) -> Option>> { =20 // SAFETY: The pointer returned by `into_foreign` was originally allocated= as an // `KBox>`, so that type is what determines the alignment. -unsafe impl ForeignOwnable for Arc { +unsafe impl ForeignOwnable for Arc { const FOREIGN_ALIGN: usize =3D > as ForeignOwnable>::= FOREIGN_ALIGN; =20 - type Borrowed<'a> =3D ArcBorrow<'a, T>; - type BorrowedMut<'a> =3D Self::Borrowed<'a>; + type Borrowed<'a> + =3D ArcBorrow<'a, T> + where + T: 'a; + type BorrowedMut<'a> + =3D Self::Borrowed<'a> + where + T: 'a; =20 fn into_foreign(self) -> *mut c_void { ManuallyDrop::new(self).ptr.as_ptr().cast() --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CEC474519A4; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; cv=none; b=iu/DvRT41C696QF6m7sOK5XvUxmLbFQo88hihEWDupCGauv5AbE6ydfsj+wQGZJjerkCylrkasoS5YI8BMQAh16mgxod/1jUWRsZboiK+pngWD+oqNummjZx6b/UViaQU5BoiNJnHxHGa0PgtZCaXa3drOeTbqmI3rBik4OJ9jM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799695; c=relaxed/simple; bh=TlVDi0TxMxxZeN20pGON06eoA/EsPc4W/j9d+dr0EhM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XneRdc4K3jtW081C0kn4uE0vbj+nJuqknuNrJ+mgobMhdexG+fxivYHyAyum7jenyjnklVqSAByVqop199EhDUxXoSXr4+O/Jwaw7YZ7pKuUau003wZdsJxC7KQWXksPnnGziwt8K98UZu2/Oyk0v2TSFBqo1ytswiH2wO9QWG4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rrqOjbmp; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rrqOjbmp" Received: by smtp.kernel.org (Postfix) with ESMTPS id A0338C32782; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=TlVDi0TxMxxZeN20pGON06eoA/EsPc4W/j9d+dr0EhM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rrqOjbmpmqhDnPZQ0rqFifLFA1QDqx8VSp7Xw6zgQw360DA8I+CAfJKeMYotSeExN cWt8u/DpXUOFptrj2d8OvYJQFR8v5AmwMzj9qAGJwo66ki+o4coY6jXsnACXPmbYdD A+lYVk63Bo5/uFF3DpJa4sqjJtDOmJnphLMfva70KbJ5n4SoE9Yi5d8nzG21k76E1m nLwCAN29qjSPTjcUvU0HOa5QoeZS0xSCldT6xelKPok+y9f+Hjvp3aVtZxKWyBOE/h ZjmKIBWr54s6dchB/CWxK2UtTj0mJ2bn732+eUjHZr8ThThqVMecJ9Y1qsIIzQCsy6 XRMi3CB+Mk7yA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89A13C79F99; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:51 +0800 Subject: [PATCH v2 4/9] drm/tyr: add per-file VM pool Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-4-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=6892; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=E5fAToBpW3fHYqXQ6LGiOZHomFP/OX5vReY6bzJsSvg=; b=/QTBTvhX2T9UgC1tr/jeIEsYz/XsFx949EuBDEIsCSIpGS0QvOWaEgti35ACCW4yDWb3TyIiN cmwwPpJeyItAczO/lPVp4oRzhYzxwsRNOtPfoGmGNyPagUZbuQnAzCk X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Userspace needs multiple independent GPU address spaces per file, addressed by ID through the VM ioctls as in panthor. Store them in an IdPool (capped at 32 for panthor parity) plus an XArray. Each VM is stored with its VmOwner, so it is killed exactly once - on destroy or file close - regardless of remaining shared references. Signed-off-by: Alvin Sun --- drivers/gpu/drm/tyr/vm.rs | 157 ++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tyr/vm.rs b/drivers/gpu/drm/tyr/vm.rs index c5e307b1e2416..ae58135eeffdc 100644 --- a/drivers/gpu/drm/tyr/vm.rs +++ b/drivers/gpu/drm/tyr/vm.rs @@ -8,6 +8,7 @@ //! mapped into hardware address space (AS) slots for GPU execution. =20 use core::marker::PhantomData; +use core::mem::ManuallyDrop; use core::ops::Range; =20 use kernel::{ @@ -33,6 +34,7 @@ }, // }, fmt, + id_pool::IdPool, impl_flags, io::PhysAddr, iommu::pgtable::{ @@ -53,7 +55,11 @@ ArcBorrow, Mutex, // }, - uapi, // + uapi, + xarray::{ + AllocKind, + XArray, // + }, // }; =20 use crate::{ @@ -154,6 +160,57 @@ fn try_from(value: u32) -> Result { } } =20 +/// Owns a [`Vm`]'s destruction: the VM is killed exactly once, when this +/// value is dropped, regardless of how many `Arc` references remain. +/// +/// Callers that only need to use the VM take an `Arc` via +/// [`VmOwner::get()`], which keeps it alive but does not kill it. +pub(crate) struct VmOwner<'drm>(ManuallyDrop>>); + +impl<'drm> VmOwner<'drm> { + /// A reference for callers that want to use the VM, not own it. + #[expect(dead_code)] + pub(crate) fn get(&self) -> Arc> { + Arc::clone(&self.0) + } + + /// Transfers the VM to the pool without killing it, leaving only the + /// shared reference. The pool reconstructs the owner with + /// [`VmOwner::from_shared()`] when the VM is removed. + fn into_shared(mut self) -> Arc> { + // SAFETY: `self.0` is initialized, and `forget(self)` below preve= nts + // the outer wrapper from being dropped, so the taken `Arc` is mov= ed + // out exactly once and nothing is leaked or double-dropped. + let vm =3D unsafe { ManuallyDrop::take(&mut self.0) }; + core::mem::forget(self); + vm + } + + /// Reconstructs an owner from a shared reference. + /// + /// The caller must currently own the VM's destruction. + fn from_shared(vm: Arc>) -> Self { + Self(ManuallyDrop::new(vm)) + } +} + +impl<'drm> core::ops::Deref for VmOwner<'drm> { + type Target =3D Vm<'drm>; + + fn deref(&self) -> &Vm<'drm> { + &self.0 + } +} + +impl Drop for VmOwner<'_> { + fn drop(&mut self) { + self.0.kill(); + // SAFETY: `self.0` is initialized and we are in `drop`, so it is = safe + // to drop the inner `Arc` now that the VM has been killed. + unsafe { ManuallyDrop::drop(&mut self.0) }; + } +} + /// Arguments for a virtual memory map operation. struct VmMapArgs<'drm> { /// Access permissions and caching behavior for the mapping. @@ -948,3 +1005,101 @@ fn pt_unmap(dev: &Device, pt: &IoPageTable<'_, ARM64= LPAES1>, range: Range) =20 Ok(()) } + +/// Maximum number of VMs a single file may hold, matching panthor's +/// `PANTHOR_MAX_VMS_PER_FILE`. +const MAX_VMS_PER_FILE: usize =3D 32; + +/// Per-open-file pool of VMs. +#[pin_data(PinnedDrop)] +pub(crate) struct VmPool<'drm> { + #[pin] + ids: Mutex, + #[pin] + vms: XArray>>, +} + +impl<'drm> VmPool<'drm> { + /// Creates a new [`VmPool`]. + #[expect(dead_code)] + pub(crate) fn new() -> impl PinInit { + let ids =3D IdPool::new(); + pin_init!(Self { + ids <- new_mutex!(ids), + vms <- XArray::new(AllocKind::Alloc), + }) + } + + /// Takes ownership of `vm` and stores it, returning the allocated ID. + /// + /// On failure - ID space exhausted or store failure - the VM is killed + /// here and only the error is returned. + // TODO: allocate IDs with the XArray directly (once it grows range + // allocation, the equivalent of C's `XA_LIMIT`) and drop the IdPool. + #[expect(dead_code)] + pub(crate) fn add(&self, vm: VmOwner<'drm>) -> Result { + let id =3D { + let mut ids =3D self.ids.lock(); + let unused =3D ids.find_unused_id(1).ok_or(ENOSPC)?; + if unused.as_usize() > MAX_VMS_PER_FILE { + return Err(ENOSPC); + } + unused.acquire() + }; + + let vm =3D vm.into_shared(); + let mut vms =3D self.vms.lock(); + match vms.store(id, vm, GFP_KERNEL) { + Ok(prev_vm) =3D> { + drop(prev_vm); + Ok(id as u32) + } + Err(err) =3D> { + // Drop the XArray spinlock before acquiring the `ids` mut= ex. + drop(vms); + // Kill the VM and release the pooled id before returning. + drop(VmOwner::from_shared(err.value)); + self.ids.lock().release_id(id); + Err(err.error) + } + } + } + + /// Removes the VM with the given ID, handing back its owner. + /// + /// Dropping the returned [`VmOwner`] kills the VM immediately. + #[expect(dead_code)] + pub(crate) fn remove(&self, id: u32) -> Result> { + let mut vms =3D self.vms.lock(); + match vms.remove(id as usize) { + Some(vm) =3D> { + drop(vms); + self.ids.lock().release_id(id as usize); + Ok(VmOwner::from_shared(vm)) + } + None =3D> Err(EINVAL), + } + } + + /// Gets a shared reference to the VM with the given ID. + #[expect(dead_code)] + pub(crate) fn get(&self, id: u32) -> Option>> { + let vms =3D self.vms.lock(); + let borrow =3D vms.get(id as usize)?; + Some(Arc::from(borrow)) + } +} + +#[pinned_drop] +impl PinnedDrop for VmPool<'_> { + fn drop(self: Pin<&mut Self>) { + let this =3D self.project(); + // Kill every VM still owned by the pool. The ID range is bounded = by + // `MAX_VMS_PER_FILE`, so this loop is cheap and runs at file clos= e. + for id in 1..=3DMAX_VMS_PER_FILE { + // Release the XArray lock guard before killing: `kill()` may = sleep. + let vm =3D this.vms.lock().remove(id); + drop(vm.map(VmOwner::from_shared)); + } + } +} --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0C1350AC3D; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; cv=none; b=C73+4ZlcLxmzPelLfA1Mw66UGnaiciDYYwB8sSSAD3CjHP0m6CkJ7MIwk7EgyQxAUhvjJUf3cn40ihQsz7y26zlJOjD/Zs+eL2+ONLJrKlYYNeYWoLpo6IKsGW+pO0WSYdQFDbPcf9ABX08MbhjfXUWydA6zozFkrdlz9fOUVmw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; c=relaxed/simple; bh=byHoQUt0eKprNUVHGwZuLX2Bj5CQjR67ENpGY7WoGvY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ucDnyXWCsBYUMvzKAO1A8KYf0gckoQq54fkxjdxoeRsaRso0japYvK9Y7r02OB32sLT6ZNAXPU2aAyWmx86R4tQDCJJIs5PirenrFDFnXThyMDoA3bXU/V9mAaegbIpwwsc+svl+XV8fj+oPBVWz8pdW8ai7vNE55jvgY/7qcBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lfdWSuaQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lfdWSuaQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id C03F1C32786; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=byHoQUt0eKprNUVHGwZuLX2Bj5CQjR67ENpGY7WoGvY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=lfdWSuaQU+luEpeGj8dHI3FIP6JL7Aq8pqemNCoKQl0Nno1cCrjNyMJOPEFUuV6Zu QZsdi4MQCXNk1oV2NSuis6qdBtA9qJn59XcUn18xygZwfLMTaMOI54yiCyKJw/x0i9 fXqci5MGamYgLILI/y4TEdg3WNzd/i2aeH8cC5oCJ7q5hpoF3EWQxhvENuVTbdwGcH vSdf++78yVu+6Gx8q+FVxbQ/s56YaIlokcEPA4NV4n94JgRLGLnACLXlzQ0oB2BE0W rJfdhDALJD7n3UDdnyFfk0KnB7fgPWMhgirh8NqVaMBPPLmAE7UDLk/g8nkLTJvkf5 m+tUrEI5w2IuQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3851C79FA9; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:52 +0800 Subject: [PATCH v2 5/9] drm/tyr: add user and MCU VM specifications Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-5-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=13328; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=LWBtN12EESI502HFoJUAp2/6XICDPpkFfaH/DGUZKa8=; b=IBuZp9zawXEMk1wICkFi2QOfds8vuGJyGo+EW9VIkODdbliANCbcMhXig02Eq4O31BBJhosAI K0BNwkW5qa3AR0pYVoCgKXO5jGq8WU2quUCUXIzgZeXRkjg2bKsr6qN X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun The MCU and user VMs need different VA layouts. Give each a dedicated constructor: new_for_fw() builds the kernel-only 4G layout, while new_for_user() splits the address space by task_size or a user-provided size, rejecting oversized requests rather than clamping. The resulting user range is what VM_CREATE reports back as user_va_range. Signed-off-by: Alvin Sun --- drivers/gpu/drm/tyr/fw.rs | 37 +++++----- drivers/gpu/drm/tyr/vm.rs | 179 +++++++++++++++++++++++++++++++++++++++++-= ---- 2 files changed, 178 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/tyr/fw.rs b/drivers/gpu/drm/tyr/fw.rs index 47d25c901bd01..6aba9f6e6bc63 100644 --- a/drivers/gpu/drm/tyr/fw.rs +++ b/drivers/gpu/drm/tyr/fw.rs @@ -51,7 +51,6 @@ KernelBoVaAlloc, // }, gpu::GpuInfo, - mmu::Mmu, regs::{ gpu_control::{ @@ -66,7 +65,10 @@ JOB_IRQ_RAWSTAT, // }, // }, - vm::Vm, // + vm::{ + Vm, + VmOwner, // + }, // }; =20 mod parser; @@ -149,7 +151,10 @@ pub(crate) struct Firmware<'drm> { iomem: Arc>, =20 /// MCU VM. - vm: Arc>, + /// + /// As the VM's owner, this field kills the firmware mappings when the + /// firmware is dropped. + vm: VmOwner<'drm>, =20 /// List of firmware sections. #[expect(dead_code)] @@ -160,9 +165,6 @@ impl<'drm> Drop for Firmware<'drm> { fn drop(&mut self) { // Stop the MCU before releasing its firmware mappings and memory. let _ =3D self.stop(); - - // AS slots retain a VM ref, we need to kill the circular ref manu= ally. - self.vm.kill(); } } =20 @@ -220,10 +222,10 @@ pub(crate) fn new( mmu: ArcBorrow<'_, Mmu<'drm>>, gpu_info: &GpuInfo, ) -> Result> { - let vm =3D Vm::new(dev, ddev, mmu, gpu_info)?; + let vm =3D Vm::new_for_fw(dev, ddev, mmu, gpu_info)?; vm.activate()?; =20 - let result =3D (|| { + let sections =3D (|| -> Result>> { let (fw, parsed_sections) =3D Self::load(dev, ddev, gpu_info)?; let mut sections =3D KVec::new(); for parsed in parsed_sections { @@ -233,7 +235,7 @@ pub(crate) fn new( =20 let mut mem =3D KernelBo::new( ddev, - vm.clone(), + vm.get(), size, KernelBoVaAlloc::Explicit(va), parsed.vm_map_flags, @@ -253,18 +255,15 @@ pub(crate) fn new( sections.push(Section { data, mem }, GFP_KERNEL)?; } =20 - Ok(Firmware { - iomem, - vm: vm.clone(), - sections, - }) + Ok(sections) })(); =20 - if result.is_err() { - vm.kill(); - } - - result + // On error, `vm` (the owner) is dropped and kills the MCU VM. + Ok(Firmware { + iomem, + vm, + sections: sections?, + }) } =20 pub(crate) fn boot(&self) -> Result { diff --git a/drivers/gpu/drm/tyr/vm.rs b/drivers/gpu/drm/tyr/vm.rs index ae58135eeffdc..db9e2ccc55056 100644 --- a/drivers/gpu/drm/tyr/vm.rs +++ b/drivers/gpu/drm/tyr/vm.rs @@ -9,6 +9,7 @@ =20 use core::marker::PhantomData; use core::mem::ManuallyDrop; +use core::num::NonZeroU64; use core::ops::Range; =20 use kernel::{ @@ -45,6 +46,8 @@ new_mutex, prelude::*, sizes::{ + LargeSizeConstants, + SizeConstants, SZ_1G, SZ_2M, SZ_4K, // @@ -160,6 +163,25 @@ fn try_from(value: u32) -> Result { } } =20 +/// User VA size request for a user VM. +pub(crate) enum UserVaRequest { + /// Split based on `task_size()` and the GPU VA range. + Auto, + /// Caller-specified size; construction guarantees `> 0`. + Fixed(NonZeroU64), +} + +impl UserVaRequest { + /// UAPI boundary normalization: `0` -> [`Auto`](Self::Auto). + #[expect(dead_code)] + pub(crate) fn from_uapi(v: u64) -> Self { + match NonZeroU64::new(v) { + Some(size) =3D> Self::Fixed(size), + None =3D> Self::Auto, + } + } +} + /// Owns a [`Vm`]'s destruction: the VM is killed exactly once, when this /// value is dropped, regardless of how many `Arc` references remain. /// @@ -169,7 +191,6 @@ fn try_from(value: u32) -> Result { =20 impl<'drm> VmOwner<'drm> { /// A reference for callers that want to use the VM, not own it. - #[expect(dead_code)] pub(crate) fn get(&self) -> Arc> { Arc::clone(&self.0) } @@ -211,6 +232,84 @@ fn drop(&mut self) { } } =20 +/// Final user/kernel VA layout for a VM. +pub(crate) struct VmLayout { + /// Full GPU VA range covered by this VM. + pub(crate) full: Range, + /// User-accessible VA range. Empty for MCU VMs. + pub(crate) user: Range, +} + +impl VmLayout { + /// Kernel VA range, reserved for future kernel object allocation. + #[expect(dead_code)] + pub(crate) fn kernel(&self) -> Range { + self.user.end..self.full.end + } + + /// Compute a user/kernel split for a user VM from the full GPU VA ran= ge and + /// a user request. + pub(crate) fn compute(full: Range, req: UserVaRequest) -> Result<= Self> { + // Minimum VA space reserved for kernel objects (heaps, ring buffe= rs, ...). + const MIN_KERNEL_VA: u64 =3D u64::SZ_256M; + + if full.end <=3D MIN_KERNEL_VA { + pr_err!( + "Invalid VA range {:#x}..{:#x}, kernel VA min required: >{= :#x}\n", + full.start, + full.end, + MIN_KERNEL_VA + ); + return Err(EINVAL); + } + + let user_max =3D full.end - MIN_KERNEL_VA; + + let user_end =3D match req { + UserVaRequest::Fixed(v) =3D> { + let user_size =3D v.get(); + if user_size > user_max { + pr_err!( + "Requested user VA range {:#x} exceeds maximum {:#= x}\n", + user_size, + user_max + ); + return Err(EINVAL); + } + user_size + } + UserVaRequest::Auto =3D> { + let task_size =3D current!().mm().map(|mm| mm.task_size()); + let candidate =3D match task_size { + // `task_size()` returns usize; widen to u64 for the c= omparison. + Some(t) if (t as u64) < full.end =3D> t as u64, + None | Some(_) =3D> { + // If the range exceeds 4G, split it in two so CPU= and + // GPU share the same addresses (SVM). + if full.end > u64::SZ_4G { + full.end / 2 + } else { + user_max + } + } + }; + candidate.min(user_max) + } + }; + + let delta =3D full.end - user_end; + // Pick a kernel VA range that's a power of two, to have a clear s= plit. + let kernel_va_range =3D 1u64 << delta.ilog2(); + let kernel_va_start =3D full.end - kernel_va_range; + let full_start =3D full.start; + + Ok(Self { + full, + user: full_start..kernel_va_start, + }) + } +} + /// Arguments for a virtual memory map operation. struct VmMapArgs<'drm> { /// Access permissions and caching behavior for the mapping. @@ -386,26 +485,64 @@ pub(crate) struct Vm<'drm> { /// Non-core part of the GPUVM. Can be used for stuff that doesn't mod= ify the /// internal mapping tree, like GpuVm::obtain() gpuvm: ARef>>, - /// VA range for this VM. - va_range: Range, + /// VA layout for this VM. + pub(crate) layout: VmLayout, } =20 impl<'drm> Vm<'drm> { - /// Creates a new GPU virtual address space. + /// Creates the MCU/firmware VM. /// - /// The VM is initialized with a page table configured according to th= e GPU's - /// address translation capabilities and registered with the GPUVM fra= mework. - pub(crate) fn new( + /// The MCU VM is entirely kernel-managed: it has no user-accessible r= ange. + pub(crate) fn new_for_fw( + dev: &'drm Device, + ddev: &TyrDrmDevice, + mmu: ArcBorrow<'_, Mmu<'drm>>, + gpu_info: &GpuInfo, + ) -> Result> { + // As in panthor: the CSF MCU is a Cortex-M7 and can only address = 4G. + let layout =3D VmLayout { + full: 0..u64::SZ_4G, + user: 0..0u64, + }; + Self::new_internal(dev, ddev, mmu, gpu_info, layout) + } + + /// Creates a user VM, splitting the GPU VA range per `user_va`. + #[expect(dead_code)] + pub(crate) fn new_for_user( dev: &'drm Device, ddev: &TyrDrmDevice, mmu: ArcBorrow<'_, Mmu<'drm>>, gpu_info: &GpuInfo, - ) -> Result>> { + user_va: UserVaRequest, + ) -> Result> { + let mmu_features =3D MMU_FEATURES::from_raw(gpu_info.mmu_features); + let va_bits =3D mmu_features.va_bits().get(); + let range =3D 0..(1u64 << va_bits); + + let layout =3D VmLayout::compute(range.clone(), user_va).inspect_e= rr(|_| { + dev_err!( + dev, + "Failed to split GPU VA range {:#x}..{:#x} into user and k= ernel regions\n", + range.start, + range.end + ); + })?; + Self::new_internal(dev, ddev, mmu, gpu_info, layout) + } + + /// Initializes a VM with the given layout and hands back its owner. + fn new_internal( + dev: &'drm Device, + ddev: &TyrDrmDevice, + mmu: ArcBorrow<'_, Mmu<'drm>>, + gpu_info: &GpuInfo, + layout: VmLayout, + ) -> Result> { let mmu_features =3D MMU_FEATURES::from_raw(gpu_info.mmu_features); let va_bits =3D mmu_features.va_bits().get(); let pa_bits =3D mmu_features.pa_bits().get(); =20 - let range =3D 0..(1u64 << va_bits); let reserve_range =3D 0..0u64; =20 // dummy_obj is used to initialize the GPUVM tree. @@ -417,7 +554,7 @@ pub(crate) fn new( c"Tyr::GpuVm", ddev, &*dummy_obj, - range.clone(), + layout.full.clone(), reserve_range, GpuVmData::<'drm> { _phantom: PhantomData::<&()>, @@ -437,12 +574,12 @@ pub(crate) fn new( mmu: mmu.into(), gpuvm, gpuvm_unique <- new_mutex!(gpuvm_unique), - va_range: range, + layout, }), GFP_KERNEL, )?; =20 - Ok(vm) + Ok(VmOwner(ManuallyDrop::new(vm))) } =20 /// Returns the parent device used by this VM for DMA mapping and page= -table operations. @@ -467,11 +604,15 @@ fn deactivate(&self) -> Result { } =20 /// Kills the VM by deactivating it and unmapping all regions. - pub(crate) fn kill(&self) { - // TODO: Turn the VM into a state where it can't be used. + /// + /// Only called from [`VmOwner`]'s `Drop`. + fn kill(&self) { let _ =3D self.deactivate(); let _ =3D self - .unmap_range(self.va_range.start, self.va_range.end - self.va_= range.start) + .unmap_range( + self.layout.full.start, + self.layout.full.end - self.layout.full.start, + ) .inspect_err(|e| { dev_err!(self.dev, "Failed to unmap range during deactivat= e: {:?}", e); }); @@ -608,14 +749,14 @@ pub(crate) fn unmap_range(&self, va: u64, size: u64) = -> Result { =20 let end =3D va.checked_add(size).ok_or(EINVAL)?; =20 - if va < self.va_range.start || end > self.va_range.end { + if va < self.layout.full.start || end > self.layout.full.end { dev_err!( self.dev, "Unmap range {:#x}..{:#x} exceeds VM range {:#x}..{:#x}", va, end, - self.va_range.start, - self.va_range.end + self.layout.full.start, + self.layout.full.end ); return Err(EINVAL); } @@ -625,7 +766,7 @@ pub(crate) fn unmap_range(&self, va: u64, size: u64) ->= Result { region: va..end, }; =20 - let full_vm =3D va =3D=3D self.va_range.start && end =3D=3D self.v= a_range.end; + let full_vm =3D va =3D=3D self.layout.full.start && end =3D=3D sel= f.layout.full.end; =20 let mut resources =3D VmOpResources { preallocated_gpuvas: if full_vm { --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4854351E42A; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; cv=none; b=X17r7ztK1Z1+G3KaX7kbzZxB3m0OjuMur8BzXanK8EiNCFCDzMDyVfsWpZ3lvFb/QAxVMB8ffoV3esJmA7Ac5uGuWkW0bqatW4kjQJPSaXcH5GcKhNOiKF9xYeMMFIyphl26F4EOUtRjmdV6VCzlyVavHWO/Tt+SsR1ilGbMD1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; c=relaxed/simple; bh=4fCA01lVKFUQcPLwCosahsFm/a/A5bH2c66xJdLxhxw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SeZHng73ibA9ZQRHVutx+gc1pu0XG4i7gc3747OhnEp6OnxOTWpfvWvI9Js0Bc0nZcNlodvpKML0BQo+0Tx5brw03XHrCVoHBfLHP4eani2n/Y+p4TgBQa31gX0B3/5ed1WopEi9cdTbE5GwIdq1bW2R2GsR6Hb6qrxlXJ2BQjE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KAMGLi5G; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KAMGLi5G" Received: by smtp.kernel.org (Postfix) with ESMTPS id D9352C2BCFC; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799695; bh=4fCA01lVKFUQcPLwCosahsFm/a/A5bH2c66xJdLxhxw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=KAMGLi5GgpROMAvah1Ucb+Y+IL21IvaDpdJiE8Ul+O2TxxHOIRdxT/O/wCPc5k/I9 TSqJbTGwuvG4tc4EEKCrhNi1xR/ekQ7i6l83cwWkaiXbsbU6lnwNTtf85pXrb+zcuR ZKCrEEJKcsWrZDNCqRem1AeTi+IjrHOpW+W7xvY5SrQhPoM+o86gDnjdH1f5Qof78n 4bXtEfP+UY+/FufAXd2FbQVsID1H80OF22owjPCXXf437vJYjXvRnwaKzUomZkPlB+ XgcI7Y/TKyezCP0J8Z5s5yCyI2vb3zcmDCpNS24XKzLstVjv82gRgV5hwpjf7Vtyqt CsjM4IcUJHdog== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C04BBC79F99; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:53 +0800 Subject: [PATCH v2 6/9] drm/tyr: add BO creation and lookup helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-6-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=1988; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=ZYb1XxhHAj4Uxqn92uytJJHTXG1ZVMUU2ITsdjHTgjA=; b=Ac0h3eZ7WiN1yioRZwUbNwv6tjKWJCM+VnK1K8IkRgMNU6aUq+XgAgFZy+Qae5/H0qO+9UORF Z5pYeSYrTAECeTmOw1OTsHafHEvs60gsXpXcADXZD4HADEuTUpyXsfK X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Add helpers for the BO ioctls: new_object() creates a GEM object with the size aligned up to PAGE_SIZE, and lookup_handle() resolves a handle for a DRM file. Signed-off-by: Alvin Sun --- drivers/gpu/drm/tyr/gem.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs index 3bf3787f5c3fd..0e0989a48678f 100644 --- a/drivers/gpu/drm/tyr/gem.rs +++ b/drivers/gpu/drm/tyr/gem.rs @@ -9,8 +9,10 @@ use kernel::{ drm::gem::{ self, - shmem, // + shmem, + BaseObject, // }, + page::PAGE_SIZE, prelude::*, sync::{ aref::ARef, @@ -23,6 +25,7 @@ TyrDrmDevice, TyrDrmDriver, // }, + file::TyrDrmFile, vm::{ Vm, VmMapFlags, // @@ -53,6 +56,32 @@ fn new(_dev: &TyrDrmDevice, _size: usize, args: BoCreate= Args) -> impl PinInit; =20 +/// Create a new GEM buffer object. +#[expect(dead_code)] +pub(crate) fn new_object(ddev: &TyrDrmDevice, size: usize, flags: u32) -> = Result> { + if size =3D=3D 0 { + return Err(EINVAL); + } + + let aligned_size =3D size.checked_next_multiple_of(PAGE_SIZE).ok_or(EI= NVAL)?; + + Bo::new( + ddev, + aligned_size, + shmem::ObjectConfig { + map_wc: true, + parent_resv_obj: None, + }, + BoCreateArgs { flags }, + ) +} + +/// Look up a GEM object by handle for a DRM file. +#[expect(dead_code)] +pub(crate) fn lookup_handle(file: &TyrDrmFile, handle: u32) -> Result> { + Bo::lookup_handle(file, handle) +} + /// Creates a dummy GEM object to serve as the root of a GPUVM. pub(crate) fn new_dummy_object(ddev: &TyrDrmDevice) -> Result> { let bo =3D Bo::new( --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 257A851D50D; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; cv=none; b=VMX43nPkiEIgdonkYZoJL7qr2vywkTahP6W+3y//XsbYw7YxN7Cw5SuF/WRsPTg8+sZlklv4xZT/IP8MTaZOzTiT3R+x7YyGJGj/a0LRCl+9KkmXp1uBmugKd0Gx2hIKb+IDMjSrZnj77Tk2+eEU6uyP82Y7fsRpbOI2gqDjaO4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; c=relaxed/simple; bh=BDSd5Sx099D86mwm18rAhbuJSuhw4ecU8Mnmm/h9BFA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r+D6iaGE1Md//gdKh/UQ5Bq2BJWqvsH2BUBQ8+pENMw9YdMOUAf7yDqTrRt8LdRPStYrDTo2dfQ719rkUbPlf0FkMvU6w4q9mvtgSuhjMubeSzHxIwoSCJPtazsxTQLasJvX7xMacTIe7eJURbyXHeObS73SPueSUQy/f1jXcSM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KLmJC3S6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KLmJC3S6" Received: by smtp.kernel.org (Postfix) with ESMTPS id ECFD4C2BCF4; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799696; bh=BDSd5Sx099D86mwm18rAhbuJSuhw4ecU8Mnmm/h9BFA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=KLmJC3S6WLkI6fhAbR7L7TT+9DfgvWGJP5xTfCUwRBbmJP1FVbj88Mb1Hi0TkvRdy znl+7zN2+dWI/HcxPgoIJz+txQjcPimA4fBkegIOQk0i6w8hsqisROH9QZkZoNbDpV kQJvjLG5vaQQgsigD2eAH0WyosKQgghUXb36QovyW9/HpYhPVm0YuBBPgrvJpeGe/T FCDWrruGEGjZvlR9lUtNxX05SaqBKfTvfgFm+Q4NdrRq10g8uOazYTAGnwBa+0198y Z6Wo+2M6iN3Bw3VMg4S9Eu6hNHSNZxfjdCB9iaQX7jlF14PlYqGMhn8E0NoxJGj7FT vvidE1bUQYLJw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8ECEC79FA7; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:54 +0800 Subject: [PATCH v2 7/9] drm/tyr: refactor new_dummy_object to use new_object Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-7-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=1566; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=evnUd0qm9ZwiYuhFDEcZYkjsD1f1+LG9OpRwEzX78ag=; b=DG8IaoiUFgNeMQe7P8OtUnLRSOFxuZi3gspovlvUFIJefp+Si1hZwHIZBN0xcP6q2w1y7skod SU6JBf12LKxAx8UhwZQ7btB/EOoS7CSkSoQ2zk9aUU0lIOE7Va2JyiU X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun new_dummy_object() duplicated the BO creation code that new_object() now provides; call new_object() instead. Signed-off-by: Alvin Sun Reviewed-by: Daniel Almeida --- drivers/gpu/drm/tyr/gem.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs index 0e0989a48678f..2523d05de5527 100644 --- a/drivers/gpu/drm/tyr/gem.rs +++ b/drivers/gpu/drm/tyr/gem.rs @@ -57,7 +57,6 @@ fn new(_dev: &TyrDrmDevice, _size: usize, args: BoCreateA= rgs) -> impl PinInit; =20 /// Create a new GEM buffer object. -#[expect(dead_code)] pub(crate) fn new_object(ddev: &TyrDrmDevice, size: usize, flags: u32) -> = Result> { if size =3D=3D 0 { return Err(EINVAL); @@ -84,17 +83,8 @@ pub(crate) fn lookup_handle(file: &TyrDrmFile, handle: u= 32) -> Result> =20 /// Creates a dummy GEM object to serve as the root of a GPUVM. pub(crate) fn new_dummy_object(ddev: &TyrDrmDevice) -> Result> { - let bo =3D Bo::new( - ddev, - 4096, - shmem::ObjectConfig { - map_wc: true, - parent_resv_obj: None, - }, - BoCreateArgs { flags: 0 }, - )?; - - Ok(bo) + // FIXME: use a Rust resv-object abstraction once available, rather th= an a real BO. + new_object(ddev, PAGE_SIZE, 0) } =20 /// Specifies how to choose a GPU virtual address for a [`KernelBo`]. --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33D4F51D53F; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; cv=none; b=qOXsV+VIliUX/t6Wm73XPNaLIF7UjNAbj86uNh2i6XeNF7sKFB37LSSo6ImmjSxSCk+lONfTPTBHNv/wcO9aq1XP6EnF3tH9TiQhCPvDO9LcVdfd7yQz1+23BOA7GfAe2Eh72Aukc9CccMnsV8YkvVRlsgCV1ikckQp7WBo2fD4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; c=relaxed/simple; bh=RHfi2Li1pjmMjxsYwpNPo8HFOzZ5whVa/VYLYlScFng=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j/JyO6RS+PdjaLoo+EDzxsbm/d043lzPVxhW90b2qPIU4NCsZAvxOxi4JHzzDDmWVk5CDunwKjWwnIXH/zcxNcix12FBmJO8SjQ9upds2GX1TwK2I41rcyNaP4lSd14TqGLe3T/MeLVfsOJ0JM2F1AnUDCVFpWZxc38r+XUKeT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HKajOxCJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HKajOxCJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 108F7C2BCFD; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799696; bh=RHfi2Li1pjmMjxsYwpNPo8HFOzZ5whVa/VYLYlScFng=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=HKajOxCJZ6bomQ7sisPJKqTgVQUZJITdpnbK6kEA0GmvItvUnDLKGHWurfsjv8Mak OT5+G0P8ci+N3fRDSfHp/4wIXNXvleSQxE+Lcd8kBf6MDPB2ZgU2xdf9DLBclhkKwd wx0vaKz7yNS6I5nZvndNAhMMOomyasrhv1JFmVEk2ZMrU0x94cokb3BWUEjP+Dirg0 pfQ+EOFOfvycFfTOs0p5pcOzZAqgVsQouQBvwHnd+I0t4a0hkuFKatQfSyfmfOviiY CVh0MXRBFHJvJJjTyF3SYG5k/9CA6uDPtlsFaZWBXdIYvhPQSAo+hYES3G0WSmgy+w dTbuH30IaU6wA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F04E4C79FA0; Mon, 7 Sep 2026 16:48:15 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:55 +0800 Subject: [PATCH v2 8/9] drm/tyr: add VM-related ioctls Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-8-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=20871; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=NR7nG2eCm80Nj4zxT38X9areFR+kkKPJPCASC1CIpKU=; b=vx3xtGKuUUse+QSolc01zw3arz+ZEynOpi2J1KLI1QdTqWjgcbuZJgATg09VFjH6sV/PAgJcG gyO1NQXTOmlA0kHF84dxkci/7N42sNH0gmQ4hWc6hy/yA8fnvPw2y6a X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Implement VM_CREATE, VM_DESTROY, VM_BIND and VM_GET_STATE. VM_CREATE gives the new VM's owner to the per-file pool, so an aborted creation never leaks a VM; VM_DESTROY takes it back and dropping it kills the VM immediately even if in-flight jobs still hold references (matching panthor: such jobs are expected to fault). VM_BIND runs synchronously for now. Signed-off-by: Alvin Sun --- drivers/gpu/drm/tyr/driver.rs | 12 +- drivers/gpu/drm/tyr/file.rs | 308 ++++++++++++++++++++++++++++++++++++++= ++-- drivers/gpu/drm/tyr/gem.rs | 1 - drivers/gpu/drm/tyr/vm.rs | 78 ++++++++--- 4 files changed, 369 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index 791c105ce626a..5757956470afd 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -33,7 +33,7 @@ Mutex, // }, time, - types::CovariantForLt, // + types::ForLt, // }; =20 use crate::{ @@ -72,6 +72,9 @@ pub(crate) struct TyrDrmRegistrationData<'drm> { /// Firmware sections. pub(crate) fw: Firmware<'drm>, =20 + /// Memory management unit for address space slots. + pub(crate) mmu: Arc>, + #[pin] clks: Mutex, =20 @@ -163,6 +166,7 @@ fn probe<'bound>( let reg_data =3D pin_init!(TyrDrmRegistrationData { pdev, fw: firmware, + mmu, clks <- new_mutex!(Clocks { core: core_clk, stacks: stacks_clk, @@ -206,7 +210,7 @@ fn drop(self: Pin<&mut Self>) {} impl drm::Driver for TyrDrmDriver { type Data =3D (); type RegistrationData<'drm> =3D TyrDrmRegistrationData<'drm>; - type File =3D CovariantForLt!(TyrDrmFileData); + type File =3D ForLt!(TyrDrmFileData<'_>); type Object =3D Bo; type ParentDevice =3D platform::Device; =20 @@ -215,6 +219,10 @@ impl drm::Driver for TyrDrmDriver { =20 kernel::declare_drm_ioctls! { (PANTHOR_DEV_QUERY, drm_panthor_dev_query, ioctl::RENDER_ALLOW, Ty= rDrmFileData::dev_query), + (PANTHOR_VM_CREATE, drm_panthor_vm_create, ioctl::RENDER_ALLOW, Ty= rDrmFileData::vm_create), + (PANTHOR_VM_DESTROY, drm_panthor_vm_destroy, ioctl::RENDER_ALLOW, = TyrDrmFileData::vm_destroy), + (PANTHOR_VM_BIND, drm_panthor_vm_bind, ioctl::RENDER_ALLOW, TyrDrm= FileData::vm_bind), + (PANTHOR_VM_GET_STATE, drm_panthor_vm_get_state, ioctl::RENDER_ALL= OW, TyrDrmFileData::vm_get_state), } } =20 diff --git a/drivers/gpu/drm/tyr/file.rs b/drivers/gpu/drm/tyr/file.rs index 933a365cb016e..dceaae6fb9717 100644 --- a/drivers/gpu/drm/tyr/file.rs +++ b/drivers/gpu/drm/tyr/file.rs @@ -3,37 +3,60 @@ use kernel::{ drm::{ self, + gem::BaseObject, Registered, // }, prelude::*, - uaccess::UserSlice, + sizes::SizeConstants, + transmute::FromBytes, + uaccess::{ + UserSlice, + UserSliceReader, // + }, uapi, // }; =20 -use crate::driver::{ - TyrDrmDevice, - TyrDrmDriver, - TyrDrmRegistrationData, // +use crate::{ + driver::{ + TyrDrmDevice, + TyrDrmDriver, + TyrDrmRegistrationData, // + }, + vm::{ + UserVaRequest, + Vm, + VmBindOpType, + VmMapFlags, + VmPool, // + }, // }; =20 #[pin_data] -pub(crate) struct TyrDrmFileData {} +pub(crate) struct TyrDrmFileData<'a> { + reg: &'a TyrDrmRegistrationData<'a>, + + #[pin] + vm_pool: VmPool<'a>, +} =20 /// Convenience type alias for our DRM `File` type. pub(crate) type TyrDrmFile =3D drm::file::File; =20 -impl drm::file::DriverFile<'_> for TyrDrmFileData { +impl<'a> drm::file::DriverFile<'a> for TyrDrmFileData<'a> { type Driver =3D TyrDrmDriver; =20 fn open( _device: &TyrDrmDevice, - _reg_data: &TyrDrmRegistrationData<'_>, + reg_data: &'a TyrDrmRegistrationData<'a>, ) -> impl PinInit { - Ok(Self {}) + try_pin_init!(Self { + reg: reg_data, + vm_pool <- VmPool::new(), + }) } } =20 -impl TyrDrmFileData { +impl TyrDrmFileData<'_> { pub(crate) fn dev_query( _ddev: &TyrDrmDevice, reg_data: &TyrDrmRegistrationData<'_>, @@ -65,4 +88,269 @@ pub(crate) fn dev_query( } } } + + pub(crate) fn vm_create( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + vmcreate: &mut uapi::drm_panthor_vm_create, + file: &TyrDrmFile, + ) -> Result { + if vmcreate.flags !=3D 0 { + dev_err!( + ddev.as_ref(), + "Invalid VM create flags: {:#x}\n", + vmcreate.flags + ); + return Err(EINVAL); + } + + let ret: Result =3D file.inner_with(|pfile| { + let vm =3D Vm::new_for_user( + pfile.reg.pdev.as_ref(), + ddev, + pfile.reg.mmu.as_arc_borrow(), + &pfile.reg.gpu_info, + UserVaRequest::from_uapi(vmcreate.user_va_range), + )?; + let user_va_range =3D vm.layout.user.end; + let id =3D pfile.vm_pool.add(vm)?; + vmcreate.user_va_range =3D user_va_range; + vmcreate.id =3D id; + + Ok(0) + }); + ret + } + + pub(crate) fn vm_destroy( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + vmdestroy: &mut uapi::drm_panthor_vm_destroy, + file: &TyrDrmFile, + ) -> Result { + if vmdestroy.pad !=3D 0 { + dev_err!( + ddev.as_ref(), + "Invalid VM destroy pad: {:#x}\n", + vmdestroy.pad + ); + return Err(EINVAL); + } + + let ret: Result =3D file.inner_with(|pfile| { + pfile.vm_pool.remove(vmdestroy.id)?; + Ok(0) + }); + ret + } + + pub(crate) fn vm_bind( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + vmbind: &mut uapi::drm_panthor_vm_bind, + file: &TyrDrmFile, + ) -> Result { + let async_flag =3D uapi::drm_panthor_vm_bind_flags_DRM_PANTHOR_VM_= BIND_ASYNC; + + if vmbind.flags & !async_flag !=3D 0 { + dev_err!( + ddev.as_ref(), + "Invalid VM_BIND flags: {:#x}\n", + vmbind.flags + ); + return Err(EINVAL); + } + + if vmbind.flags & async_flag !=3D 0 { + dev_err!(ddev.as_ref(), "Async VM_BIND not supported\n"); + return Err(ENOTSUPP); + } + + let count =3D vmbind.ops.count as usize; + if count =3D=3D 0 { + return Ok(0); + } + + let size_of_op =3D size_of::(); + // Stride versions the UAPI struct: reject only undersized strides. + if size_of_op > vmbind.ops.stride as usize { + dev_err!( + ddev.as_ref(), + "Invalid VM_BIND op stride {} (expected at least {})\n", + vmbind.ops.stride, + size_of::() + ); + return Err(EINVAL); + } + let stride =3D vmbind.ops.stride as usize; + + let total_len =3D stride.checked_mul(count).ok_or_else(|| { + dev_err!(ddev.as_ref(), "VM_BIND ops length overflow\n"); + EINVAL + })?; + let mut reader =3D + UserSlice::new(UserPtr::from_addr(vmbind.ops.array as usize), = total_len).reader(); + let mut ops =3D KVec::new(); + for _ in 0..count { + ops.push(reader.read::()?, GFP_KERNEL)?; + read_padding_zero(&mut reader, stride - size_of_op)?; + } + + let ret: Result =3D file.inner_with(|pfile| { + let vm =3D pfile.vm_pool.get(vmbind.vm_id).ok_or_else(|| { + dev_err!(ddev.as_ref(), "Invalid VM_BIND vm_id: {}\n", vmb= ind.vm_id); + EINVAL + })?; + + for (i, op) in ops.iter().enumerate() { + if let Err(e) =3D vm_bind_exec_op(&vm, file, op) { + dev_dbg!(ddev.as_ref(), "VM_BIND op {} failed: {:?}\n"= , i, e); + vmbind.ops.count =3D i as u32; + return Err(e); + } + } + + Ok(0) + }); + ret + } + + pub(crate) fn vm_get_state( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + vmgetstate: &mut uapi::drm_panthor_vm_get_state, + file: &TyrDrmFile, + ) -> Result { + file.inner_with(|pfile| { + let vm =3D pfile.vm_pool.get(vmgetstate.vm_id).ok_or_else(|| { + dev_err!( + ddev.as_ref(), + "Invalid VM_GET_STATE vm_id: {}\n", + vmgetstate.vm_id + ); + EINVAL + })?; + vmgetstate.state =3D if vm.is_unusable() { + uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_UNUSABLE + } else { + uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_USABLE + }; + Ok(0) + }) + } } + +fn vm_bind_exec_op(vm: &Vm<'_>, file: &TyrDrmFile, op: &VmBindOp) -> Resul= t { + if op.size =3D=3D 0 { + return Ok(()); + } + + if op.syncs.count !=3D 0 { + dev_err!(vm.dev(), "VM_BIND op syncs not supported\n"); + return Err(EINVAL); + } + + let end =3D match op.va.checked_add(op.size) { + Some(end) =3D> end, + None =3D> { + dev_err!(vm.dev(), "VM_BIND op VA range overflow\n"); + return Err(EINVAL); + } + }; + if op.va < vm.layout.user.start || end > vm.layout.user.end { + dev_err!( + vm.dev(), + "VM_BIND op VA range {:#x}..{:#x} outside user range\n", + op.va, + end + ); + return Err(EINVAL); + } + + if (op.va | op.size | op.bo_offset) & (u64::SZ_4K - 1) !=3D 0 { + dev_err!(vm.dev(), "VM_BIND op not GPU-page-aligned\n"); + return Err(EINVAL); + } + + match VmBindOpType::try_from(op.flags) { + Ok(VmBindOpType::Map) =3D> { + // Once the VM is unusable only MAP ops are rejected; UNMAP + // stays available for cleanup (see the UAPI docs). + if vm.is_unusable() { + dev_err!(vm.dev(), "VM_BIND map op on unusable VM\n"); + return Err(EINVAL); + } + + let map_flags =3D match VmMapFlags::try_from(op.flags & !VmBin= dOpType::MASK) { + Ok(flags) =3D> flags, + Err(_) =3D> { + dev_err!(vm.dev(), "VM_BIND op invalid map flags {:#x}= \n", op.flags); + return Err(EINVAL); + } + }; + let bo =3D crate::gem::lookup_handle(file, op.bo_handle).map_e= rr(|_| { + dev_err!(vm.dev(), "VM_BIND op invalid BO handle {}\n", op= .bo_handle); + EINVAL + })?; + // Validate the BO window before mapping. + let bo_size =3D bo.size() as u64; + if op.size > bo_size || op.bo_offset > bo_size - op.size { + dev_err!(vm.dev(), "VM_BIND op BO range out of bounds\n"); + return Err(EINVAL); + } + vm.map_bo_range(&bo, op.bo_offset, op.size, op.va, map_flags) + } + Ok(VmBindOpType::Unmap) =3D> { + // Unmap must not carry map-specific flags or BO references. + if op.flags & !VmBindOpType::MASK !=3D 0 || op.bo_handle !=3D = 0 || op.bo_offset !=3D 0 { + dev_err!( + vm.dev(), + "VM_BIND UNMAP carries flags/BO refs: flags=3D{:#x} bo= _handle=3D{} bo_offset=3D{}\n", + op.flags, + op.bo_handle, + op.bo_offset + ); + return Err(EINVAL); + } + vm.unmap_range(op.va, op.size) + } + Err(_) =3D> { + dev_err!( + vm.dev(), + "VM_BIND op type {:#x} not supported\n", + op.flags & VmBindOpType::MASK + ); + Err(EINVAL) + } + } +} + +/// Reads `len` bytes of array padding, rejecting any nonzero byte with `E= 2BIG`. +fn read_padding_zero(reader: &mut UserSliceReader, len: usize) -> Result { + let mut buf =3D [0u8; 64]; + let mut remaining =3D len; + while remaining > 0 { + let chunk =3D remaining.min(buf.len()); + reader.read_slice(&mut buf[..chunk])?; + if buf[..chunk].iter().any(|&b| b !=3D 0) { + return Err(E2BIG); + } + remaining -=3D chunk; + } + Ok(()) +} + +#[repr(transparent)] +struct VmBindOp(uapi::drm_panthor_vm_bind_op); + +impl core::ops::Deref for VmBindOp { + type Target =3D uapi::drm_panthor_vm_bind_op; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// SAFETY: `VmBindOp` contains only integers, so any bit pattern is valid; +// the `#[repr(transparent)]` wrapper has the same layout as the UAPI stru= ct. +unsafe impl FromBytes for VmBindOp {} diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs index 2523d05de5527..e5030b645527d 100644 --- a/drivers/gpu/drm/tyr/gem.rs +++ b/drivers/gpu/drm/tyr/gem.rs @@ -76,7 +76,6 @@ pub(crate) fn new_object(ddev: &TyrDrmDevice, size: usize= , flags: u32) -> Result } =20 /// Look up a GEM object by handle for a DRM file. -#[expect(dead_code)] pub(crate) fn lookup_handle(file: &TyrDrmFile, handle: u32) -> Result> { Bo::lookup_handle(file, handle) } diff --git a/drivers/gpu/drm/tyr/vm.rs b/drivers/gpu/drm/tyr/vm.rs index db9e2ccc55056..bd23f75a5bd8a 100644 --- a/drivers/gpu/drm/tyr/vm.rs +++ b/drivers/gpu/drm/tyr/vm.rs @@ -54,6 +54,11 @@ }, sync::{ aref::ARef, + atomic::{ + Acquire, + Atomic, + Release, // + }, Arc, ArcBorrow, Mutex, // @@ -173,7 +178,6 @@ pub(crate) enum UserVaRequest { =20 impl UserVaRequest { /// UAPI boundary normalization: `0` -> [`Auto`](Self::Auto). - #[expect(dead_code)] pub(crate) fn from_uapi(v: u64) -> Self { match NonZeroU64::new(v) { Some(size) =3D> Self::Fixed(size), @@ -182,6 +186,38 @@ pub(crate) fn from_uapi(v: u64) -> Self { } } =20 +/// Operation type, packed into the top nibble of +/// `drm_panthor_vm_bind_op::flags`. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum VmBindOpType { + /// Map a BO range into the VM. + Map, + /// Unmap a VA range. + Unmap, +} + +impl VmBindOpType { + /// Bits occupied by the op type in `drm_panthor_vm_bind_op::flags`. + pub(crate) const MASK: u32 =3D + uapi::drm_panthor_vm_bind_op_flags_DRM_PANTHOR_VM_BIND_OP_TYPE_MAS= K as u32; +} + +impl TryFrom for VmBindOpType { + type Error =3D Error; + + fn try_from(flags: u32) -> Result { + const MAP: u32 =3D uapi::drm_panthor_vm_bind_op_flags_DRM_PANTHOR_= VM_BIND_OP_TYPE_MAP as u32; + const UNMAP: u32 =3D + uapi::drm_panthor_vm_bind_op_flags_DRM_PANTHOR_VM_BIND_OP_TYPE= _UNMAP as u32; + + match flags & Self::MASK { + MAP =3D> Ok(Self::Map), + UNMAP =3D> Ok(Self::Unmap), + _ =3D> Err(EINVAL), + } + } +} + /// Owns a [`Vm`]'s destruction: the VM is killed exactly once, when this /// value is dropped, regardless of how many `Arc` references remain. /// @@ -254,12 +290,6 @@ pub(crate) fn compute(full: Range, req: UserVaReq= uest) -> Result { const MIN_KERNEL_VA: u64 =3D u64::SZ_256M; =20 if full.end <=3D MIN_KERNEL_VA { - pr_err!( - "Invalid VA range {:#x}..{:#x}, kernel VA min required: >{= :#x}\n", - full.start, - full.end, - MIN_KERNEL_VA - ); return Err(EINVAL); } =20 @@ -269,11 +299,6 @@ pub(crate) fn compute(full: Range, req: UserVaReq= uest) -> Result { UserVaRequest::Fixed(v) =3D> { let user_size =3D v.get(); if user_size > user_max { - pr_err!( - "Requested user VA range {:#x} exceeds maximum {:#= x}\n", - user_size, - user_max - ); return Err(EINVAL); } user_size @@ -487,6 +512,8 @@ pub(crate) struct Vm<'drm> { gpuvm: ARef>>, /// VA layout for this VM. pub(crate) layout: VmLayout, + /// Whether the VM is unusable. + unusable: Atomic, } =20 impl<'drm> Vm<'drm> { @@ -508,7 +535,6 @@ pub(crate) fn new_for_fw( } =20 /// Creates a user VM, splitting the GPU VA range per `user_va`. - #[expect(dead_code)] pub(crate) fn new_for_user( dev: &'drm Device, ddev: &TyrDrmDevice, @@ -575,6 +601,7 @@ fn new_internal( gpuvm, gpuvm_unique <- new_mutex!(gpuvm_unique), layout, + unusable: Atomic::new(false), }), GFP_KERNEL, )?; @@ -607,6 +634,7 @@ fn deactivate(&self) -> Result { /// /// Only called from [`VmOwner`]'s `Drop`. fn kill(&self) { + self.mark_unusable(); let _ =3D self.deactivate(); let _ =3D self .unmap_range( @@ -618,6 +646,15 @@ fn kill(&self) { }); } =20 + /// Marks the VM unusable. + fn mark_unusable(&self) { + self.unusable.store(true, Release); + } + + pub(crate) fn is_unusable(&self) -> bool { + self.unusable.load(Acquire) + } + /// Executes a virtual memory operation. /// /// This handles both map and unmap operations by coordinating between= the @@ -729,6 +766,17 @@ pub(crate) fn map_bo_range( }; let result =3D { let mut gpuvm_unique =3D self.gpuvm_unique.lock(); + // Check under the GPUVM lock so a concurrent kill cannot race + // with this operation. + if self.is_unusable() { + dev_err!( + self.dev, + "Failed to map VA {:#x}..{:#x}: VM is unusable\n", + req.region.start, + req.region.end + ); + return Err(EINVAL); + } self.exec_op(gpuvm_unique.as_mut().get_mut(), req, &mut resour= ces) }; // We flush the defer cleanup list now. Things will be different in @@ -1162,7 +1210,6 @@ pub(crate) struct VmPool<'drm> { =20 impl<'drm> VmPool<'drm> { /// Creates a new [`VmPool`]. - #[expect(dead_code)] pub(crate) fn new() -> impl PinInit { let ids =3D IdPool::new(); pin_init!(Self { @@ -1177,7 +1224,6 @@ pub(crate) fn new() -> impl PinInit { /// here and only the error is returned. // TODO: allocate IDs with the XArray directly (once it grows range // allocation, the equivalent of C's `XA_LIMIT`) and drop the IdPool. - #[expect(dead_code)] pub(crate) fn add(&self, vm: VmOwner<'drm>) -> Result { let id =3D { let mut ids =3D self.ids.lock(); @@ -1209,7 +1255,6 @@ pub(crate) fn add(&self, vm: VmOwner<'drm>) -> Result= { /// Removes the VM with the given ID, handing back its owner. /// /// Dropping the returned [`VmOwner`] kills the VM immediately. - #[expect(dead_code)] pub(crate) fn remove(&self, id: u32) -> Result> { let mut vms =3D self.vms.lock(); match vms.remove(id as usize) { @@ -1223,7 +1268,6 @@ pub(crate) fn remove(&self, id: u32) -> Result> { } =20 /// Gets a shared reference to the VM with the given ID. - #[expect(dead_code)] pub(crate) fn get(&self, id: u32) -> Option>> { let vms =3D self.vms.lock(); let borrow =3D vms.get(id as usize)?; --=20 2.43.0 From nobody Fri Sep 25 23:10:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51A6651E433; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; cv=none; b=kBi3CwMfpyxPqw6IfouGmrA4dCWHsFff4yxA0Tj8imVhtYq6KCGiYpMg8iFA3IGbon4mw0wLWpkuPu+ODstr5YK/RT+EtD7PsljxtN52VcMf9d7mNg1Q2nC62ssn7qaNzj1DT5dIk5byPOQNE3JMQksnE5AOS5FYw4HwJU+RyFY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788799696; c=relaxed/simple; bh=tG9MtH7XTUY6M2vbhj4/1uyraDN80MRt2bwRHxYGjQk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QGHEuoXhYtiQkgNNgJmaBXVFUAaYA3is/WlKmzQ7QV107qLVi0PRUoNRAS60i33mHZKkSEpKbdAHRgRI/vvvHHfTFOy7/PHXsUr0lBCn2xEOaAFShj+lvkLScIY2r5Qf7f1Gn45ab9Y7BGrbBRvG/LOZhLPMupeR/McidC/qJ3g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lftWQdYS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lftWQdYS" Received: by smtp.kernel.org (Postfix) with ESMTPS id 250BFC2BD04; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788799696; bh=tG9MtH7XTUY6M2vbhj4/1uyraDN80MRt2bwRHxYGjQk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=lftWQdYS1I7JvcQrH2iixLIRO7UvxgVLB6XL+m0pWayJI2YqamxAu+onABVAk4Djj WnCQM+a3z8N7MNQ2md3VzEG2XC4OoEIIB4AyWE5YO2OSNoWC6GYS/sRDY2apZs6n8V X9rL59/g3YRWTXERLkF7h88+8pfytVxyet4ytUmY58OlkBisHzOTcR+ijvBaiFd7RJ y+O4qh1QKd9yrDO8Y0Psuy8c2t/A1lusdQnyAoq65ob3lqZUl/RimPS3PzKSej4M+q DWIEY6Asfb24ER3CS+j3wPUDYXxeNQ6RWgkwkEPqCi5FS6J02auzz//j66DkSKWSZm SMd+kZvieJm6g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12460C79FA1; Mon, 7 Sep 2026 16:48:16 +0000 (UTC) From: Ke Sun via B4 Relay Date: Tue, 08 Sep 2026 00:47:56 +0800 Subject: [PATCH v2 9/9] drm/tyr: add BO-related ioctls Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260908-tyr-ioctls-v2-9-88bea777df67@kylinos.cn> References: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> In-Reply-To: <20260908-tyr-ioctls-v2-0-88bea777df67@kylinos.cn> To: rust-for-linux@vger.kernel.org Cc: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Lorenzo Stoakes , "Liam R. Howlett" , Lyude Paul , David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, linux-mm@kvack.org, dri-devel@lists.freedesktop.org, Ke Sun , Alvin Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788799692; l=4712; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=xnfV+DL8ObyMU6ybdjvxrzU2shgkBW1Lv77J/eSf2Rw=; b=8tq66fA+IKBrwmpTmb2HoubKsKAR0nqE1yXq2iF9mNzf398J98tq2fBNP53ZJ5PWj2hVJivjn baSuZar3upOAmohyGmYlLZqBhgl6FVxKhqaNA22vyS5Fp9Taia2ottq X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= X-Endpoint-Received: by B4 Relay for sunke@kylinos.cn/20260317 with auth_id=950 X-Original-From: Ke Sun Reply-To: sunke@kylinos.cn From: Alvin Sun Implement BO_CREATE and BO_MMAP_OFFSET so userspace can allocate GPU buffers and obtain a DRM mmap offset for the generic mmap path. BO_CREATE page-aligns the requested size; BO_MMAP_OFFSET rejects NO_MMAP objects, which must never be CPU-mapped. Signed-off-by: Alvin Sun Reviewed-by: Daniel Almeida --- drivers/gpu/drm/tyr/driver.rs | 2 ++ drivers/gpu/drm/tyr/file.rs | 70 +++++++++++++++++++++++++++++++++++++++= ++++ drivers/gpu/drm/tyr/gem.rs | 7 +++++ 3 files changed, 79 insertions(+) diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs index 5757956470afd..06e0feae289c2 100644 --- a/drivers/gpu/drm/tyr/driver.rs +++ b/drivers/gpu/drm/tyr/driver.rs @@ -223,6 +223,8 @@ impl drm::Driver for TyrDrmDriver { (PANTHOR_VM_DESTROY, drm_panthor_vm_destroy, ioctl::RENDER_ALLOW, = TyrDrmFileData::vm_destroy), (PANTHOR_VM_BIND, drm_panthor_vm_bind, ioctl::RENDER_ALLOW, TyrDrm= FileData::vm_bind), (PANTHOR_VM_GET_STATE, drm_panthor_vm_get_state, ioctl::RENDER_ALL= OW, TyrDrmFileData::vm_get_state), + (PANTHOR_BO_CREATE, drm_panthor_bo_create, ioctl::RENDER_ALLOW, Ty= rDrmFileData::bo_create), + (PANTHOR_BO_MMAP_OFFSET, drm_panthor_bo_mmap_offset, ioctl::RENDER= _ALLOW, TyrDrmFileData::bo_mmap_offset), } } =20 diff --git a/drivers/gpu/drm/tyr/file.rs b/drivers/gpu/drm/tyr/file.rs index dceaae6fb9717..ec6b53c586d02 100644 --- a/drivers/gpu/drm/tyr/file.rs +++ b/drivers/gpu/drm/tyr/file.rs @@ -238,6 +238,76 @@ pub(crate) fn vm_get_state( Ok(0) }) } + + pub(crate) fn bo_create( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + bocreate: &mut uapi::drm_panthor_bo_create, + file: &TyrDrmFile, + ) -> Result { + if bocreate.size =3D=3D 0 + || bocreate.pad !=3D 0 + || bocreate.flags & !uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO= _NO_MMAP !=3D 0 + || bocreate.exclusive_vm_id !=3D 0 + { + dev_err!( + ddev.as_ref(), + "Invalid BO_CREATE params: size=3D{}, pad=3D{}, flags=3D{:= #x}, exclusive_vm_id=3D{}\n", + bocreate.size, + bocreate.pad, + bocreate.flags, + bocreate.exclusive_vm_id + ); + return Err(EINVAL); + } + + let size =3D usize::try_from(bocreate.size).map_err(|_| { + dev_err!( + ddev.as_ref(), + "BO_CREATE size {:#x} too large\n", + bocreate.size + ); + EINVAL + })?; + let bo =3D crate::gem::new_object(ddev, size, bocreate.flags)?; + bocreate.handle =3D bo.create_handle(file)?; + bocreate.size =3D bo.size() as u64; + + Ok(0) + } + + pub(crate) fn bo_mmap_offset( + ddev: &TyrDrmDevice, + _reg_data: &TyrDrmRegistrationData<'_>, + bommap: &mut uapi::drm_panthor_bo_mmap_offset, + file: &TyrDrmFile, + ) -> Result { + if bommap.pad !=3D 0 { + dev_err!( + ddev.as_ref(), + "BO mmap offset pad not zero: {}\n", + bommap.pad + ); + return Err(EINVAL); + } + + let bo =3D crate::gem::lookup_handle(file, bommap.handle).inspect_= err(|_| { + dev_err!(ddev.as_ref(), "Invalid BO mmap handle: {}\n", bommap= .handle); + })?; + if bo.flags() & uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP = !=3D 0 { + dev_err!(ddev.as_ref(), "BO mmap offset on NO_MMAP object\n"); + return Err(EPERM); + } + bommap.offset =3D bo.create_mmap_offset().inspect_err(|_| { + dev_err!( + ddev.as_ref(), + "Failed to create mmap offset for handle {}\n", + bommap.handle + ); + })?; + + Ok(0) + } } =20 fn vm_bind_exec_op(vm: &Vm<'_>, file: &TyrDrmFile, op: &VmBindOp) -> Resul= t { diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs index e5030b645527d..27273636c09c9 100644 --- a/drivers/gpu/drm/tyr/gem.rs +++ b/drivers/gpu/drm/tyr/gem.rs @@ -38,6 +38,13 @@ pub(crate) struct BoData { flags: u32, } =20 +impl BoData { + /// Returns the flags the BO was created with. + pub(crate) fn flags(&self) -> u32 { + self.flags + } +} + /// Provides a way to pass arguments when creating BoData /// as required by the gem::DriverObject trait. pub(crate) struct BoCreateArgs { --=20 2.43.0