From nobody Fri Sep 25 03:16:19 2026 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010041.outbound.protection.outlook.com [52.101.201.41]) (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 8478445040F; Thu, 17 Sep 2026 08:35:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.41 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789634141; cv=fail; b=OLNQk8xd6YZI01lDXsmabmyqxRATOtpJRX0iMt8998eGww2VfWns8LmgysoJRZ/JXaFiI5G+wHFXpoT+/8ADCiZC4klDOYRIx+z6SHPEHSNxnLOkWxJQ3zGamCWfx0c1fnE19jw82G7AyDEkx4jkjx7As/Be3QuqCHmA2qvipCA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789634141; c=relaxed/simple; bh=+vtAEqHnTQSY8AbG6oUc4DU0kTKTiWzzceoUDDRL7IM=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=sF8o/GSr3uXWCuBghG7kjEgX3umMpIWQwr3p7CpIO7e0sAcNrDhkvOMxZ3/XfNAgugQ0MTkSflM9SlYQESAtEWX/Y/yVsc4awKwD7GB8oew918SD42xD0GasxDXgD8PZiofYse0C06cDgmXScmqFUjmI1iLMnA30ZQ7LcV7Qu1I= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=Sw47KuNK; arc=fail smtp.client-ip=52.101.201.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="Sw47KuNK" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YIRGzNMyv1xhSw1aRLrgsl26vlqDFZfqExb5rUOi008OQfJ4eu5+AcWyAC8JOlVqgKmHjuCwBaHEtIzi3wVV37qwBCnpcNGzgciMzjBljhKuq62GZA3sQw1qT6z2cOR4m/d7WbCW8apMz9jfjAwZR/IlwRflaGdhnCIXsAkAxrTpQSidD3zAUe5rAmQYMC7Y7290ZT8SPLTNdJ11JnGLK8dH4p5UeyZTebKsbJIA9hdUX1h6zA/hm1JZ5eBApsTgxGCy9oba/Rd+Y/P0le/RTFOMEzCr3CZxRlmCKldNDvVmXclvkgDymUFI2/7OpBLqUjijDihWPn1/GK43mMA9zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LMS1FIugYhsdli8tJjQoX+SyFNuQTQ2VusLS3zOkT/8=; b=nQiwLma2eze/8GG1hqCKz+JVgkjC+RxdsXIfSe3epBazAhhiQJPRLu5sDyHY0WlDhG91mYz9DX7Av+9oUcsV4CB6rhWn1jvQ4If1GZM0Sc+IuLZ/6yeITubTzumEb2RnFFr0HjHyamSCnLWvukBcekxJSNjlBYZ2LaR45r0j0wcwaUHO1PAv4z8btlgB2HGiSy916tbtICgOwj9wi93hghRNxL8alCEfYE+ZdF+wH+q6121yGytHG/NogdASyHzFb6ZNqJ0u8YoN5TTUFFjn6JGWA0uDVv2L3UHeA+LmDg0vNx+0mvoYjPUo2I8ZQiDyDRCJw65lja3Lf6oyDLQ5vw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LMS1FIugYhsdli8tJjQoX+SyFNuQTQ2VusLS3zOkT/8=; b=Sw47KuNKtXDCtEJ95cj4fT3ZUEog5rfYZT4W2YYJ3R9y+6RmlW+9lSuK718ZCDKy/OjZElhdxvx+oVAo3tCOhGHrwUp2t3P3xRdb39tF+tt8qxZEz7VWJnhHo7taoHtDzj2Ezj46M5CYQHm7Ab+TiHrNCECw0asV6yx/qQkQWBkhdOxvzljWlkxA4/StTO6Oq8SuKp/UiiKOii3RhiDzJ1J4ZCtNIGvs/jl597i240epJ7dRJfHBHTyL0FpmFggyiKcAAhjwDPuTi3zQV2UUxgr0V+QztKrsLgv+YD8MN2VNXmyqJxeCHYycAr7x3yBwGrxpZZKyxPYiOhIcf0WcKQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS0PR12MB6413.namprd12.prod.outlook.com (2603:10b6:8:ce::10) by PH0PR12MB8800.namprd12.prod.outlook.com (2603:10b6:510:26f::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.406.10; Thu, 17 Sep 2026 08:35:15 +0000 Received: from DS0PR12MB6413.namprd12.prod.outlook.com ([fe80::e82a:6673:4142:37fa]) by DS0PR12MB6413.namprd12.prod.outlook.com ([fe80::e82a:6673:4142:37fa%5]) with mapi id 15.21.0428.011; Thu, 17 Sep 2026 08:35:15 +0000 From: Eliot Courtney Date: Thu, 17 Sep 2026 17:34:50 +0900 Subject: [PATCH v4 1/2] rust: num: add cv! macro to create values from constant expressions Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260917-cv-v4-1-547ef5727451@nvidia.com> References: <20260917-cv-v4-0-547ef5727451@nvidia.com> In-Reply-To: <20260917-cv-v4-0-547ef5727451@nvidia.com> To: Alexandre Courbot , Yury Norov , 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 , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter Cc: John Hubbard , Alistair Popple , Timur Tabi , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, Eliot Courtney X-Mailer: b4 0.15.2 X-ClientProxiedBy: TYCP286CA0298.JPNP286.PROD.OUTLOOK.COM (2603:1096:400:3c8::12) To DS0PR12MB6413.namprd12.prod.outlook.com (2603:10b6:8:ce::10) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS0PR12MB6413:EE_|PH0PR12MB8800:EE_ X-MS-Office365-Filtering-Correlation-Id: dd18a6bf-4866-45bb-d0a7-08df149698bc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|7416014|10070799003|366016|23010399003|6133799003|18002099003|22082099003|3023799007|921020|11063799006|5023799004|56012099006|10067099003; X-Microsoft-Antispam-Message-Info: fsSZp8pDA7jdQRZfXQfsWN2+DCQKjfFoI59qKpc1/eZ7Ht8uaZquIxQjKaPxUPmRSljk2PnfnHhtiPx8YB+cqOyzPbJg6kJbo3HD//O5qbvnvGvpVhs4+uWR/nyUKnpal+zTq74V77U48HoapUE0DuA3AU5zACuED5/V380t/CSi3Pyvgez477/lChFPY9Tz2fGHpdlOBeVPVJiZwYdEhMsQ+RG9Wb1cja8evvITOVD9x3AMQ3cHzAH1iFQD7t07QHLNOj6AXVlXjMav7WxlS37l2P6ExaDVj8ooriZVLdK5Qe+2F964MPaVdFMMLWzolHPdbp1SJ9lZYLPp6PqqRRCiWls/4X2qmv/seWRY0ooBCb74pHFuMOXk+uvpdzWgRxOKS+pdPo8k8RG71ynvkpfjzlOktNCkoVr8mxzauvaDlICmwSRvyr1+JYMgeV/ZE6JBIGCS4uVPSS9touet1kxISZnPIsaDZbKGdVwsK45XW2/qqJRfncEujLK7KGY+qxPYPbg0kXYWGi9rX28Qv6lh2q5fSy4i1XVfeBUryomm72c8SJXrR2qbLTaLovAdUYn+jNHdT3z4gWycEBOBom6UZ9xRr10IwJNksIY6nMh5ta7h8cO9lH2BEKykynP/9M0uktsmte7BDDlw8jwnSRXrHnTegm1ugzOCgIcbmVN445Hl5bvcPd5BbAkyIw2Yc93i6/bFPYIj2D9UJQEhqg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS0PR12MB6413.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(7416014)(10070799003)(366016)(23010399003)(6133799003)(18002099003)(22082099003)(3023799007)(921020)(11063799006)(5023799004)(56012099006)(10067099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?SFE4UnBMZGpsb3ZUZlI3R0lpL1BQTW4yZXQ0QnZ2b251Ujk2QkE3Q2NrOEhK?= =?utf-8?B?aW9oVS9WQXlsd1FGOEk3dE12RTJPZWlHRGU5TGNEaGEvUDlzYVhJVTF1czVG?= =?utf-8?B?TzJNb0lFMjlnR05ZYmdoNVlIQTVzdm5WbFBFRlo1bFJnUGQ1NThUMXM3WXJW?= =?utf-8?B?ZlJtMmpFK2tSeVB3dlJEVnUrMWovb2VKTWZMcjVWLzFyMHRvZHFDRituZmIz?= =?utf-8?B?RXcyWTc3eld6V3RkOFJkaU52VEF1NXZVNDdpem84VDF5cm0xbHE5aTdQRmFk?= =?utf-8?B?d1QwSU9SUEUrallIWTk4Z2hZelErVVJKVlN3ekZEZE5DRStCbnB5enJpdndI?= =?utf-8?B?WEFkNm40UEN3Q2RvUFhzZWowdlY3UWgyOXBpUE5pWjh1dFlqdlZOL05wK00w?= =?utf-8?B?YzR2TXB6SEVXUTN4QkRya2tiVU5Nd1NpNEh4aFRkL2N1Q1l3dE1lRWFDbDFL?= =?utf-8?B?UStUZFdYZjRKZkxxMjJzaWJ2WnBmM2o4QmhkTWJId2h4VlBoaW1uK1JXZ0lz?= =?utf-8?B?dWRGSlNPVE1OZ0lmejcxQjZ4VDgvMXJTK2luNllDUWF4UENNS0g4MmtJamI1?= =?utf-8?B?QmJiRGJvNkQ5b3RvcUlKK1I2TVdDZEp0cDhhTlR1NnUrQ2FTOElTRWFpaEth?= =?utf-8?B?QnBzbVhUcVNaMVBodm52SFZnMnVYQzhlNEFLeENsdEZ3M0tUT1JXME5vTTJq?= =?utf-8?B?QXhBMDNGTDd0bGJ0Qk01ZWFtVW44ajFhQWZZNzhMQ3l2bVBCenhBM2c0Lzc0?= =?utf-8?B?SzJLQ1dHMmpRVUhIVjFQTmxDQ2lOY1krd3hmZHVEOERxVWdRY0M2TDFJdUN0?= =?utf-8?B?YlBJbmI4WmNNc2dhdzYrYldBNGhmWGs0TitrbkVISVhmMEJ0WUE2UzA4ZnY4?= =?utf-8?B?dGllZUQzdUpFcVI4SlR1dm1IWEpZQzBCWVVyUS95dlJidElqS2xwVGNuTHUv?= =?utf-8?B?N1EwOTFMVERLaC9PeDlqc211M25IeXU1bm1uNk1KdnlQYWxzK2dqei9vZXYv?= =?utf-8?B?dDNjU01EeForenRjbmhKWFZzc1ZaVS9tNTQrbGY0M25pbmNKa3FmMDYxWUlK?= =?utf-8?B?b3hSeDdvenZ0Rm4vSWw3QmI4SUNLbDNjN0t4MkdhejlnNURFYmZVajhaMll1?= =?utf-8?B?MVdqRUZtaHp6N0FlcGRybXJQMHNROHVZazJPbjgxVlFMTUtUTk5lZzZzQWdL?= =?utf-8?B?VG5ueDlpb00xREx6YjN1TXR1K1d0b1ZLYnlqdkd3eEE5MDd6b29WNXFka1Bh?= =?utf-8?B?MGJzMURFTjZFZVNUTUxUUE9UaklxMXpsaEdJTUFTVy9YWkJObXVkenFCYWxj?= =?utf-8?B?VXZYRnM1NGRjODN5akpMMTQrVWlYSzl2aEZ4eUVWVHMxSFNlbDkwSURDYmlV?= =?utf-8?B?a3g0Mnp0eU1NdzFSanBuYjhnQ2hoQ0ExZUxRNHkrVG1HNytLb0JSbG1DTmlt?= =?utf-8?B?Q29jVDRETlRESnBINXgwK0NNUmhwTktCLysvaUJwODVocElGUFRCTkVXdHd6?= =?utf-8?B?U1lHMU5RaU42ZzJvN0wxUmRhd0NBWlVBMDVLSFMrZ2tlTnBmTHh0MHZ3K25N?= =?utf-8?B?YmpJdXdPRE9nWnVTNFU1U2UvNlhBbURqZ2wvb3JLNW9pUjRVOTdXY2lEbWxD?= =?utf-8?B?Q0pkU0tWWFFMT1RGQlRXRkIySU9VWnZLWnJYN3o0dVpjT2ZTOWtaU1FZVVBG?= =?utf-8?B?OUgxQVRDcGdkOHppbEkyK1hKaStxcXBqY1FvL1VyOTNtQi9XUUtzaG5ldjZu?= =?utf-8?B?ZGtGQmtuUjRXTnhZdjJPckhPQWt0RWdFTFVpNGhuYlB6VkZ1aGFWWFR2d3A1?= =?utf-8?B?bXJpRlBTQlg1MWp6T2ViMC9Qak16Q1g0SVhKa2FGOGo0TnI3Y0RXMVJ2cW5w?= =?utf-8?B?djc0S1Vqa1BRTEdkd20zL2YvTjZyNGNmZE12RkVIejAyNjIxZ1dUcWxqVXpm?= =?utf-8?B?U1cwcUhLdTFlcDVXZzN4NUNUallkUmhLaEZ6d3ZBa0poeE9uRzNFWXhiZDJZ?= =?utf-8?B?RDZieFFLTEtPdk9qZFZTU29yTTlvZFBFM0M1SFNCT0VmZzVmUFNUL0Z3S0Vk?= =?utf-8?B?Szg3cnZXREYwSkNLVVYybWthSitoNHBra2FaTnlNTHFaQlQ1MzdpdmEyV2h0?= =?utf-8?B?SU5oU0dWWEFwOWFTM0gvM3N2WHJmd0RkUUVlOXg2TGtoRVZIM3Vac01ocmk3?= =?utf-8?B?U3AwaTBYK01rZ0RtcmlRWk14WFJxYzF2bkRXQnFQUnNuVkNncHpoODFCWnNL?= =?utf-8?B?dFdUZGlERjRDWG1odTYzRjAxT1pLSWE1MWFlaU5KaytjQlQ0U2tQWDZpbkRF?= =?utf-8?B?RmNaQmpjSC91Y1dUYVJVYWtmcTA4djgwdVNUSFR0RHdWQ2NMN2d0dStUYlhU?= =?utf-8?Q?XIdnPvHjTcLsjKZEf7JiUAxPpnMbMtxZR5m4qjckLlPAx?= X-MS-Exchange-AntiSpam-MessageData-1: Ui3kqQQE5+5VCQ== X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: dd18a6bf-4866-45bb-d0a7-08df149698bc X-MS-Exchange-CrossTenant-AuthSource: DS0PR12MB6413.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2026 08:35:15.1049 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Iqt6C56Sv3U67k6gm89uhDfBZb+vyy6L6pVzjrkee0hfxJHLYy+oUL3cPff2+rGqK8wZ+xFDBqa0w0JAnLzR/w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB8800 Currently, using NonZero/Bounded constants is quite verbose. It's unfortunate because it disincentivizes using it in interface boundaries. Introduce a macro to make it nicer to use. The macro `cv!` (for constant value) takes a const integer expression and widens it to i128 (at build time only) before passing it as a const generic value to a new trait `FromConst`. The value is then converted and appears in the associated constant `FromConst::VALUE`. The trait is implemented by NonZero, Bounded, and Alignment and lets values of each be constructed from constants without a verbose turbofish syntax. For example, `const { NonZero::new(1).unwrap() }` can be written as `cv!(1)`. Add the `cv!` macro to the prelude so it doesn't need to be imported explicitly to use it. Suggested-by: Gary Guo Reviewed-by: Gary Guo Signed-off-by: Eliot Courtney Acked-by: Danilo Krummrich --- rust/kernel/num.rs | 135 +++++++++++++++++++++++++++++++++++++++++= ++++ rust/kernel/num/bounded.rs | 16 ++++++ rust/kernel/prelude.rs | 1 + rust/kernel/ptr.rs | 12 +++- 4 files changed, 163 insertions(+), 1 deletion(-) diff --git a/rust/kernel/num.rs b/rust/kernel/num.rs index dbe848e30efe..6a4cb8d3ec95 100644 --- a/rust/kernel/num.rs +++ b/rust/kernel/num.rs @@ -79,3 +79,138 @@ impl Integer for $type { i128: Signed, isize: Signed ); + +/// Creates a value from an integer constant expression, with validity che= cked at build time. +/// +/// This works for any type that implements [`FromConst`], with the target= type inferred from +/// the context, or named explicitly with `cv!(value =3D> Type)`. +/// +/// # Examples +/// +/// ``` +/// use core::num::NonZero; +/// use kernel::num::Bounded; +/// use kernel::ptr::Alignment; +/// +/// let v: NonZero =3D cv!(8); +/// assert_eq!(v.get(), 8); +/// +/// // Any integer constant expression works, not only literals. +/// let m: NonZero =3D cv!(usize::MAX); +/// assert_eq!(m.get(), usize::MAX); +/// +/// let b: Bounded =3D cv!(15); +/// assert_eq!(b.get(), 15); +/// +/// let a: Alignment =3D cv!(4096); +/// assert_eq!(a.as_usize(), 4096); +/// +/// // Checked narrowing of integer constants, including in `const` items. +/// const SMALL: u8 =3D cv!(200u32); +/// assert_eq!(SMALL, 200); +/// +/// const N: NonZero =3D cv!(5); +/// assert_eq!(N.get(), 5); +/// +/// // The target type can be given explicitly. +/// let e =3D cv!(200u32 =3D> u8); +/// assert_eq!(e, 200); +/// +/// // With an explicit primitive target, the expression can use generic p= arameters. +/// const fn as_u64() -> u64 { +/// cv!(KEY =3D> u64) +/// } +/// assert_eq!(as_u64::<0x40>(), 0x40); +/// ``` +#[macro_export] +#[doc(hidden)] +macro_rules! cv { + (@cast $v:expr =3D> $t:ty) =3D> { + const { + #[allow(unused_comparisons, unused_assignments, clippy::as_und= erscore)] + { + let v =3D $v; + let r =3D v as $t; + // Pin `back` to `v`'s type so `as _` casts back to the so= urce type. + let mut back =3D v; + back =3D r as _; + + ::core::assert!( + back =3D=3D v && (v < 0) =3D=3D (r < 0), + "value does not fit into the target type" + ); + + r + } + } + }; + // Using `FromConst::VALUE` means const generic expressions can't b= e used, since it requires + // the `generic_const_exprs` feature. Provide a special path for each = primitive type that allows + // const generic expressions. + ($v:expr =3D> u8) =3D> { $crate::cv!(@cast $v =3D> u8) }; + ($v:expr =3D> u16) =3D> { $crate::cv!(@cast $v =3D> u16) }; + ($v:expr =3D> u32) =3D> { $crate::cv!(@cast $v =3D> u32) }; + ($v:expr =3D> u64) =3D> { $crate::cv!(@cast $v =3D> u64) }; + ($v:expr =3D> u128) =3D> { $crate::cv!(@cast $v =3D> u128) }; + ($v:expr =3D> usize) =3D> { $crate::cv!(@cast $v =3D> usize) }; + ($v:expr =3D> i8) =3D> { $crate::cv!(@cast $v =3D> i8) }; + ($v:expr =3D> i16) =3D> { $crate::cv!(@cast $v =3D> i16) }; + ($v:expr =3D> i32) =3D> { $crate::cv!(@cast $v =3D> i32) }; + ($v:expr =3D> i64) =3D> { $crate::cv!(@cast $v =3D> i64) }; + ($v:expr =3D> i128) =3D> { $crate::cv!(@cast $v =3D> i128) }; + ($v:expr =3D> isize) =3D> { $crate::cv!(@cast $v =3D> isize) }; + ($v:expr =3D> $t:ty) =3D> { + <$t as $crate::num::FromConst<{ $crate::cv!(@cast $v =3D> i128) }>= >::VALUE + }; + ($v:expr) =3D> { + <_ as $crate::num::FromConst<{ $crate::cv!(@cast $v =3D> i128) }>>= ::VALUE + }; +} +#[doc(inline)] +pub use cv; + +/// Types that can be created from an integer constant expression validate= d at build time. +/// +/// Implement this trait to make a type usable with [`cv!`]. Use the [`cv`= ] macro, not this trait +/// directly, for creating values. +#[diagnostic::on_unimplemented(message =3D "`{Self}` cannot be converted f= rom a constant")] +pub trait FromConst: Sized { + /// The value that corresponds to the constant `V`. + /// + /// Fails the build if `V` is not a valid value for `Self`. + const VALUE: Self; +} + +/// Implements [`FromConst`] for primitive integer types and their [`NonZe= ro`](core::num::NonZero) +/// versions. +macro_rules! impl_from_const { + ($($type:ty)*) =3D> { + $( + impl FromConst for $type { + const VALUE: Self =3D { + // CAST: the macro is only used for types up to 64 bits wi= de, so `MIN` and `MAX` + // widen to `i128` losslessly. + assert!( + V >=3D <$type>::MIN as i128 && V <=3D <$type>::MAX as = i128, + "constant cannot be represented by the target type" + ); + + // CAST: the assert above confirmed that `V` fits in `$typ= e`. + V as $type + }; + } + + impl FromConst for core::num::NonZero<$type> { + const VALUE: Self =3D match core::num::NonZero::new(<$type as = FromConst>::VALUE) { + Some(value) =3D> value, + None =3D> panic!("constant cannot be zero"), + }; + } + )* + }; +} + +impl_from_const!( + u8 u16 u32 u64 usize + i8 i16 i32 i64 isize +); diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs index 2a2b0a4bca5e..1d5a151478a7 100644 --- a/rust/kernel/num/bounded.rs +++ b/rust/kernel/num/bounded.rs @@ -14,6 +14,7 @@ =20 use kernel::{ num::{ + FromConst, Integer, Unsigned, // }, @@ -272,6 +273,21 @@ pub const fn new() -> Self { unsafe { Self::__new(VALUE) } } } + + impl FromConst for Bounded<$type, = N> { + const VALUE: Self =3D { + let value =3D <$type as FromConst>::VALUE; + // Statically assert that `value` fits within the set numb= er of bits. + assert!( + fits_within!(value, $type, N), + "constant cannot be represented within the given numbe= r of bits" + ); + + // SAFETY: the assert above confirmed that `value` can be = represented within `N` + // bits. + unsafe { Self::__new(value) } + }; + } )* }; } diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index ca396f1f78a6..5facf8f7af90 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -106,6 +106,7 @@ Result, // }, init::InPlaceInit, + num::cv, pr_alert, pr_crit, pr_debug, diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs index 82acb531b17b..2c12e4fd4572 100644 --- a/rust/kernel/ptr.rs +++ b/rust/kernel/ptr.rs @@ -11,7 +11,10 @@ }; use core::num::NonZero; =20 -use crate::const_assert; +use crate::{ + const_assert, + num::FromConst, // +}; =20 /// Type representing an alignment, which is always a power of two. /// @@ -166,6 +169,13 @@ pub const fn mask(self) -> usize { } } =20 +impl FromConst for Alignment { + const VALUE: Self =3D match Alignment::new_checked(>::VALUE) { + Some(alignment) =3D> alignment, + None =3D> panic!("constant is not a power of two"), + }; +} + /// Trait for items that can be aligned against an [`Alignment`]. pub trait Alignable: Sized { /// Aligns `self` down to `alignment`. --=20 2.55.0 From nobody Fri Sep 25 03:16:19 2026 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010041.outbound.protection.outlook.com [52.101.201.41]) (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 AB9924582E1; Thu, 17 Sep 2026 08:35:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.41 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789634155; cv=fail; b=Awo1YozANpC8nqDKhu0tjnNhPMMyecyfygkwvmVUD5iJy4kIDAR/MzVTJnoaJU6jrmtCxLsfcyQZkJEQrPWqAOkUr1qsue/4Obl7N0bW/jMdsPYnBl+2/qSaO3iKsr9t3SUkqSNX5zBSN4RdvFTSjD2Oz/kHdDNm25BtfO74oIE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789634155; c=relaxed/simple; bh=57o9/UHokbdTo2zMADOgaGApO305tBpsqQZQnSF7JwE=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=c29yf9gw6OSD414fRdExJ6X6s92MIBT8JK3WrADVgMhvz0r8qrpLVAMzehaaYS3ePUMfIoLggTvxeyCSv5VSA4e6SPT4Z1eObuqWNNSQ7xapFlt/YE5tNvn0F2P1kbpbzWzj7paJ6qdaVgkPdpC+ingZCtssf16hswlhMRtX8hI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=CpIcKBIS; arc=fail smtp.client-ip=52.101.201.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="CpIcKBIS" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VJwgZzZ2EhyOQWDZxYuwGXP2azWw6YLhAWKCZ8X6lvWzKue1RhVbH14a/n6RTY4AAGuqgZfnuacvHnZzNAVUKC9E+/BbWRPL9KvRHrzeOAEoEo+u1yE++yPwsoz5YxXldHnT5Xv+1U0QeGFjBUXgABcvIPjqPW6l3lqM3OIekEJi7xFeuwy/L5ZOM/lwp42kasB1gb9tYuovPC8Uiag/ZUuPMieOczHYFpdCKFaAKuA2kF4cC8BX72uieEwIIQcHN0gOyam17fmcVzF2WYSC2PBW3ltAJstaoBfgroIXp5h38AFhqpZOoJzzIuM3IjAnPwDx//cvh7frwQVAW7L2sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yQ/SwdTfDHb0DLot1l3ciHVfNbIYKzXb1zX4QVILZSM=; b=iFrNVYCCHjxvRuIvF9mHn6KilDuXWHC90gVC9rIlB4zFAAZuiEo/SQHrc1F0JtwNxdG64pRFMw9v8AnFDBzG9f0k+n08T31G+YdIUnW4hsRHe3aKzcNToVIALUIzhKOdO7Hwbqs5N+/yU4GLgvZIZFzMzBcmgU1DhVvaCP+SLahP692kTla3OHFxuUOGfbHjlQiBlB1OzzcF/J0iMZYxWlwihWRMV6naB7coX0NDK7cgF/Z7K4fnf2nBqtVQYM9mEoYWLJ/tUZ0Xv0KeS3idPU3moz7UD8M7HXEnrNxWw5MXZ4ulG4x979fTtUlw3jCtxsgmpVW+63biWwl4GDdNvQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yQ/SwdTfDHb0DLot1l3ciHVfNbIYKzXb1zX4QVILZSM=; b=CpIcKBISA9UIL50Q4u0M7tz5TeXv4V3QSxQuK40LWeduD1cExeX+uacp6UlhhlU2Pg9nSwq4zAnHJA20coGGLYOMGy02D39sHY+cKsJz1oWn+w2c2C6kMT3qd3ZFxlRUDEWjwyv3qjuqNJQRYVCaQgpOsnBXfRbHVgcYmr6ZGHnKEavImkbO40uA7cm+EJ32lkacrgDP2DgUYmMNhOR/tF/5vKBfFHmAVo2ytx/ndkwoNBjdbXGcGAwrZ1w2kvIKEjeYJd3W24P3lJmYR4SFruA21mk18hPsflQeoemnzKoJmd4XximhpUCfZq2uUs5nPb2qK6UvRbe6Z9ggvwHv0A== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS0PR12MB6413.namprd12.prod.outlook.com (2603:10b6:8:ce::10) by PH0PR12MB8800.namprd12.prod.outlook.com (2603:10b6:510:26f::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.406.10; Thu, 17 Sep 2026 08:35:18 +0000 Received: from DS0PR12MB6413.namprd12.prod.outlook.com ([fe80::e82a:6673:4142:37fa]) by DS0PR12MB6413.namprd12.prod.outlook.com ([fe80::e82a:6673:4142:37fa%5]) with mapi id 15.21.0428.011; Thu, 17 Sep 2026 08:35:18 +0000 From: Eliot Courtney Date: Thu, 17 Sep 2026 17:34:51 +0900 Subject: [PATCH v4 2/2] gpu: nova-core: use cv! for constant casts Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260917-cv-v4-2-547ef5727451@nvidia.com> References: <20260917-cv-v4-0-547ef5727451@nvidia.com> In-Reply-To: <20260917-cv-v4-0-547ef5727451@nvidia.com> To: Alexandre Courbot , Yury Norov , 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 , =?utf-8?q?Onur_=C3=96zkan?= , David Airlie , Simona Vetter Cc: John Hubbard , Alistair Popple , Timur Tabi , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, Eliot Courtney X-Mailer: b4 0.15.2 X-ClientProxiedBy: TY4P286CA0039.JPNP286.PROD.OUTLOOK.COM (2603:1096:405:2b2::7) To DS0PR12MB6413.namprd12.prod.outlook.com (2603:10b6:8:ce::10) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS0PR12MB6413:EE_|PH0PR12MB8800:EE_ X-MS-Office365-Filtering-Correlation-Id: 25b7c317-13fb-4574-c258-08df14969ad8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|7416014|10070799003|366016|23010399003|6133799003|18002099003|22082099003|3023799007|921020|11063799006|56012099006|10067099003; X-Microsoft-Antispam-Message-Info: f8L2LMD+ItrMlJjmecWwkS8YHQyNO2liSJIad9KIrfyog6XYn/0Am9OAAEI4Chu6/ZngRnCdC5s2gTmIhwGTFzAaytR5mZQfjfA1TUnHl0kyLKsKu5Qc+0iBE2nJNAcdt1rNaqiaqCBjS/eGm8X4L2pod13gMBuEdKoZLd32783ph2YtrYCULo+jCdU72HGecyLoh4UvUA6tlthCAhqoyiZpiM59V7q3/SaOiM/gBd6DQdKn7PCdqtUUGGH4/509HAihAAFy/YlruM8GGyEinKZw2T766Zj3ZHin/pJ82Msx6MT0Tvh6KRJ8FlD0WViy7W4nK7wIVOOpPKr0ppWxODCbkonA3DLZ7MVNWGCXxIqpAbwbhJ3+d5kK5nlsBcck8VPiTRPo6LAEU6fYpTo8IQYwaOPKQ+mQ+krQZe5SQPSbsnBHNGXkvWtWelSeyrn45fPMnUXa0JXo7E/TRmAUvreUk3YWvlrAXFA9dPECT7QffeLn2L1s28giM7D5AmHiwARZAvwjWcZdPsyysdcmn6xQaIZis7JN5LuusIS1BqJTh742kD46p7OIL8QgsYgNHv03AdVvhk8AyBsgr85BXyz8w6HZ72JvujLYeoP87paKuI7rMPyLK9ysvFWyq6UfGY1aY2DPRFU1ulpQUrSB4PZvf2t1TTUg5xOTBJaPX82lbQwY3koYwRhHsIQNitm2eCHx1x14qIXHCReTnQXyEQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS0PR12MB6413.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(7416014)(10070799003)(366016)(23010399003)(6133799003)(18002099003)(22082099003)(3023799007)(921020)(11063799006)(56012099006)(10067099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?UDNLYWZBblZjVVBEc0RzWGVPOWtuRDNRMzVNS2FaNUNIaU1hWFMvK2dJMlli?= =?utf-8?B?WE1kMFo5eklVZ09mUGZnWmg1NG1WWmpQL3ZBN0RaWXhXNkwrT2VPVHdnekdM?= =?utf-8?B?RmZHRVdkRllISTFtMlpIR2UydDFMdFlxbyszaUZnZEE1aVVYMHJVblBqNFk1?= =?utf-8?B?Qlc1blhzTFNna21mRjVhS1RMc1hnc1R6L0M4ak11Z3FUWUZZU1NmYm02ZW9k?= =?utf-8?B?WUs3SWNYbUhVRUczb3l2V29kbTFxMmtMVDlhMWNTZGhESnUyRmVhcXV4NUVX?= =?utf-8?B?bXRFNnJaUUJRSTZ3aVRuVklCZTNodTcrQm5zVDh5dnJYbERZMWJUa04waDI0?= =?utf-8?B?UEMydC9naDN0c0tXWjdjbEsyT2NqSmNyRWRmZThEUzlLMlJMaVk4L0hOQVNG?= =?utf-8?B?WjlzMTdnL3ZVdlExRWRNbGwrU01TUkd5UVJMOTc3VmFZUEtKNWlTaHpOei8v?= =?utf-8?B?QUhxQ1g0SFFxd1U3VU5VeVBSc3pqUEhuUUZ6aDNaSm5MTktZQWxqTStiVDdp?= =?utf-8?B?bDFCSGt3NW8xSmUyMGdkK3Z6RzBwcnlNWndhK2NtT05SZzNvVWJzZnY3cEEw?= =?utf-8?B?TmRxZHFXTW1pZ2tPdTVxRGZUZVJoVlFzbHdYMzJ6Vk9GMElQdlJGb005ZEZl?= =?utf-8?B?SHFwNVg0WmZEdjhpY3ZWaVRxWU1VY3M0VlFMR3Nrb2EwYVU0RW1zaTYwWVBU?= =?utf-8?B?RmRzZDlEYis2NWw4NE1uS28rK01qSTNWa0VoNTErQnR0L0ZBUFFDNUxqVWVm?= =?utf-8?B?TjdCVCtXU0YvcnZOZlpYKzhDN29ya0RoZ2xuNXl6dnJsSWt2Q3I2MVJxelU3?= =?utf-8?B?cmlKTWJvYkk5SDZXZU8rYlE3bWFnanF4YnVMaFhvM0NFM1V5bzJLTTMwVkNP?= =?utf-8?B?UGJqTGtxWStlSDJEN0U5K3h2ekZGWXV1VjZWNDFpMkdBaFc0MXp0Ty9uTURp?= =?utf-8?B?cDdMb3g0bWZGVFM3ckFpTmtNNm9YcDlBU05uWjBSVko5SkdoK2U1WHlsUm92?= =?utf-8?B?MnNuNkRaYlZqS05qallFdW1iWUZsSlhyUGpZWEpLMDhidnR4ZGVrK3JQVkhz?= =?utf-8?B?S2RRQWVRS3FJdkdJQURxb25DU2Z4aGRjaDM1anNmVkFQdEV2MXZBVXBteVRO?= =?utf-8?B?ZElwa01TS21Xd0tDVVBJckNhMjdXYkNvQk5MR1hEdCt4RnhVYjBxVE9ZK0hm?= =?utf-8?B?d0p1ZEs3UkhmcGNsdStMaTZvb0pMYUFsTVA3bEcyWURrM1c3WEgwc3d2WEpM?= =?utf-8?B?empralN2amUvN2NIc2NyclJrSHlNTER6M3I2dUpuYVB6cW56TzdLa0xHWG1B?= =?utf-8?B?TGpJT25DS1dCTFlldkhjNHVTQ3VMOEV4bkE2MzduVWEwVTNyWUVsZHVwSnUz?= =?utf-8?B?eXMwNmkrWDJ4Y3dtam5yZCt5aWphTjlhaTdkUU9YaWZBbnZGcHEwb0Q4RjE0?= =?utf-8?B?QlVybzJHejRIek0wZnVQNW5DZjNsYTJFQ1J1ZlVmbGxiTmsvVncxbDNzaS9B?= =?utf-8?B?bE9rdXlUcnFVOEtaMlpQbEc5TUFzNW5Na2trZy9WOWJnVjIyRGoxSUtKcXJW?= =?utf-8?B?eGlXdkdIUTVMU2txaTRlb0dYTllxYjR2ekJuRCt0VGVvbTZ0emIvNyttOU5p?= =?utf-8?B?VnFzblBhY0YxdDNVbUJTWHJoT2hIUEwzVnVyczUra0gzMXBYTWZHZGRKTmto?= =?utf-8?B?cUE1ZjNkOUZTenJ5bGdpU1l1TEE4WnRpblhXR2NLN1NDOGhjMDVTdzRWeXJp?= =?utf-8?B?aFUzV1J2K21rVDdyUStGQjNBclRBZXRFS0s0QnhWaGxRM1FoeVdBVG9uaEJm?= =?utf-8?B?ZE9rNVVYdzlHYlE0bUQ2WWlNSjdCV0ozOUNlelhIbVM3ODk5blNjczVaQUM3?= =?utf-8?B?bkpCS1prd1E2Nm1KekJLc2paNFBNdWFrLzhQekdWQnRzdnNuVVoxemNTWHVW?= =?utf-8?B?UW1NMU9TSkJBZEtkMlJJSU90S3IydFFQZUMyeThHc0UyZFZLY1AyK1A4eHo4?= =?utf-8?B?T0toaktCSUhTN0xKaDFUdk9OMGV3dE4wQWxZVmczaW9FQjdZRU9TMjQzTm8v?= =?utf-8?B?ZXBEMUFlV05yYklESmFMMWlNbUxHMGg4b2Q4SEFmNExXR2Z4alQ5WGZDMzMw?= =?utf-8?B?d2g1VTFsTTMxcDFpUmc3OXNrSDNsNWJxSVRpSllNQjVKanYyeVZKVmdSL3Ax?= =?utf-8?B?d1VwTjF5eXUwWFhNVDNyeXV0Ukd4YUwvSENZWXJwcUxZaUsvNmpzSEM4K21y?= =?utf-8?B?NlBGL1dINi9tUFZhNGpWQ1NQK0htUTg3L29oQTgyRU93eStrdmJxTUw2WWNN?= =?utf-8?B?b0F2dnZ1VEM4bUNSVXNtejFYeGc2eTRVOWVJc25pNzQrUXVTZU1JTjBFQTJ2?= =?utf-8?Q?JWV3SsYypzdQb+Zzwc+rUet2H2yNiBiC7bLT8GHJ3i2d6?= X-MS-Exchange-AntiSpam-MessageData-1: IX1cr2yBuTQKZg== X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 25b7c317-13fb-4574-c258-08df14969ad8 X-MS-Exchange-CrossTenant-AuthSource: DS0PR12MB6413.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2026 08:35:18.7713 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: NZFIxvaQ0XtNnEp3iXmUdC+2403qet5YohxwYlsrSEs7laUP2qmutTPV+59fRy0HuwOQDaFkhFqoiUrbZLN/AA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB8800 The new `cv!` macro allows safe casting of constant expressions in a const context. Update code in nova-core to use it. Reviewed-by: Gary Guo Signed-off-by: Eliot Courtney Reviewed-by: Danilo Krummrich --- drivers/gpu/nova-core/falcon.rs | 9 ++-- drivers/gpu/nova-core/fb/hal/gb100.rs | 4 +- drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 7 +-- drivers/gpu/nova-core/fsp.rs | 3 +- drivers/gpu/nova-core/gsp/cmdq.rs | 6 +-- drivers/gpu/nova-core/gsp/fw.rs | 38 +++++++-------- drivers/gpu/nova-core/gsp/fw/commands.rs | 2 +- drivers/gpu/nova-core/num.rs | 55 +-----------------= ---- 8 files changed, 28 insertions(+), 96 deletions(-) diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon= .rs index 9015de965a53..0b377bd6524a 100644 --- a/drivers/gpu/nova-core/falcon.rs +++ b/drivers/gpu/nova-core/falcon.rs @@ -28,11 +28,8 @@ driver::Bar0, falcon::hal::LoadMethod, gpu::Chipset, - num::{ - self, - FromSafeCast, // - }, - regs, + num::FromSafeCast, + regs, // }; =20 pub(crate) mod fsp; @@ -515,7 +512,7 @@ fn dma_wr( target_mem: FalconMem, load_offsets: FalconDmaLoadTarget, ) -> Result { - const DMA_LEN: u32 =3D num::usize_into_u32::<{ MEM_BLOCK_ALIGNMENT= }>(); + const DMA_LEN: u32 =3D cv!(MEM_BLOCK_ALIGNMENT); =20 // DMA transfers can only be done in units of 256 bytes. Compute h= ow many such transfers we // need to perform. diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/= fb/hal/gb100.rs index 9fa094939600..612f70333c11 100644 --- a/drivers/gpu/nova-core/fb/hal/gb100.rs +++ b/drivers/gpu/nova-core/fb/hal/gb100.rs @@ -28,7 +28,6 @@ hal::FbHal, regs, // }, - num::usize_into_u32, }; =20 struct Gb100; @@ -81,8 +80,7 @@ fn write_sysmem_flush_page_gb100(hshub0: Mmio<'_, regs::H= shub0Registers>, addr: =20 // This PMU reservation size is r570-specific. pub(super) const fn pmu_reserved_size_gb100() -> u32 { - usize_into_u32::<{ const_align_up(SZ_8M + SZ_16M + SZ_4K, Alignment::n= ew::()).unwrap() }>( - ) + cv!(const_align_up(SZ_8M + SZ_16M + SZ_4K, Alignment::new::()= ).unwrap()) } =20 impl FbHal for Gb100 { diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/g= pu/nova-core/firmware/fwsec/bootloader.rs index a87878fe2aec..35a813584baf 100644 --- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs +++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs @@ -17,10 +17,7 @@ Io, // }, prelude::*, - ptr::{ - Alignable, - Alignment, // - }, + ptr::Alignable, sizes, transmute::AsBytes, }; @@ -136,7 +133,7 @@ pub(crate) fn new( let code_size =3D usize::from_safe_cast(tlv.get_u32(b"CDSZ")?); let code =3D blob.get(..code_size).ok_or(EINVAL)?; let aligned_code_size =3D code_size - .align_up(Alignment::new::<{ falcon::MEM_BLOCK_ALIGNMENT }= >()) + .align_up(cv!(falcon::MEM_BLOCK_ALIGNMENT)) .ok_or(EINVAL)?; =20 let mut ucode =3D KVec::with_capacity(aligned_code_size, GFP_K= ERNEL)?; diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs index b738dcabcdef..3a4a10487f33 100644 --- a/drivers/gpu/nova-core/fsp.rs +++ b/drivers/gpu/nova-core/fsp.rs @@ -50,7 +50,6 @@ NvdmHeader, NvdmType, // }, - num, regs, // }; =20 @@ -288,7 +287,7 @@ fn new<'a>( }; =20 let version =3D hal.cot_version(); - let size =3D num::usize_into_u16::<{ core::mem::size_of::() }>(); + let size =3D cv!(core::mem::size_of::() =3D> u16); =20 Ok(init!(Self { header: FspMessageHeader::new(NvdmType::Cot), diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/= cmdq.rs index 9f99e6bbb4fa..cb757bea0ad4 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -161,7 +161,7 @@ fn read( #[repr(C, align(0x1000))] #[derive(Debug)] struct MsgqData { - data: [[u8; GSP_PAGE_SIZE]; num::u32_as_usize(MSGQ_NUM_PAGES)], + data: [[u8; GSP_PAGE_SIZE]; cv!(MSGQ_NUM_PAGES)], } =20 // Annoyingly we are forced to use a literal to specify the alignment of @@ -234,8 +234,8 @@ unsafe impl FromBytes for GspMem {} impl<'a> DmaGspMem<'a> { /// Allocate a new instance and map it for `dev`. fn new(dev: &'a device::Device) -> Result { - const MSGQ_SIZE: u32 =3D num::usize_into_u32::<{ size_of::()= }>(); - const RX_HDR_OFF: u32 =3D num::usize_into_u32::<{ mem::offset_of!(= Msgq, rx) }>(); + const MSGQ_SIZE: u32 =3D cv!(size_of::()); + const RX_HDR_OFF: u32 =3D cv!(mem::offset_of!(Msgq, rx)); =20 let mut gsp_mem =3D CoherentBox::<'_, GspMem>::zeroed(dev, GFP_KER= NEL)?; gsp_mem.cpuq.tx =3D MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_= NUM_PAGES); diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw= .rs index 8778c4bf79c0..29759882920b 100644 --- a/drivers/gpu/nova-core/gsp/fw.rs +++ b/drivers/gpu/nova-core/gsp/fw.rs @@ -57,7 +57,7 @@ =20 /// Maximum size of a single GSP message queue element in bytes. pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =3D - num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX); + cv!(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX); =20 /// Empty type to group methods related to heap parameters for running the= GSP firmware. enum GspFwHeapParams {} @@ -110,20 +110,18 @@ pub(crate) struct LibosParams { impl LibosParams { /// Version 2 of the GSP LIBOS (Turing and GA100) const LIBOS2: LibosParams =3D LibosParams { - carveout_size: num::u32_as_u64(bindings::GSP_FW_HEAP_PARAM_OS_SIZE= _LIBOS2), - allowed_heap_size: num::u32_as_u64(bindings::GSP_FW_HEAP_SIZE_OVER= RIDE_LIBOS2_MIN_MB) + carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2), + allowed_heap_size: cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_= MIN_MB =3D> u64) * u64::SZ_1M - ..num::u32_as_u64(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_M= AX_MB) * u64::SZ_1M, + ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MAX_MB =3D> u= 64) * u64::SZ_1M, }; =20 /// Version 3 of the GSP LIBOS (GA102+) const LIBOS3: LibosParams =3D LibosParams { - carveout_size: num::u32_as_u64(bindings::GSP_FW_HEAP_PARAM_OS_SIZE= _LIBOS3_BAREMETAL), - allowed_heap_size: num::u32_as_u64( - bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, - ) * u64::SZ_1M - ..num::u32_as_u64(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_B= AREMETAL_MAX_MB) - * u64::SZ_1M, + carveout_size: cv!(bindings::GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BARE= METAL), + allowed_heap_size: cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_= BAREMETAL_MIN_MB =3D> u64) + * u64::SZ_1M + ..cv!(bindings::GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MAX= _MB =3D> u64) * u64::SZ_1M, }; =20 /// Returns the libos parameters corresponding to `chipset`. @@ -682,12 +680,8 @@ fn id8(name: &str) -> u64 { id8: id8(name), pa: obj.dma_address(), size: num::usize_as_u64(obj.size()), - kind: num::u32_into_u8::< - { bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONT= IGUOUS }, - >(), - loc: num::u32_into_u8::< - { bindings::LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LOC_S= YSMEM }, - >(), + kind: cv!(bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_= CONTIGUOUS), + loc: cv!(bindings::LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LO= C_SYSMEM), ..Zeroable::init_zeroed() }); =20 @@ -715,12 +709,12 @@ pub(crate) fn new(msgq_size: u32, rx_hdr_offset: u32,= msg_count: u32) -> Self { Self(bindings::msgqTxHeader { version: 0, size: msgq_size, - msgSize: num::usize_into_u32::(), + msgSize: cv!(GSP_PAGE_SIZE), msgCount: msg_count, writePtr: 0, flags: 1, rxHdrOff: rx_hdr_offset, - entryOff: num::usize_into_u32::(), + entryOff: cv!(GSP_PAGE_SIZE), }) } =20 @@ -947,9 +941,9 @@ impl MessageQueueInitArguments { fn new<'a, 'b>(cmdq: &'a Cmdq<'b>) -> impl Init + use<'a, 'b> { init!(MessageQueueInitArguments { sharedMemPhysAddr: cmdq.dma_addr, - pageTableEntryCount: num::usize_into_u32::<{ Cmdq::NUM_PTES }>= (), - cmdQueueOffset: num::usize_as_u64(Cmdq::CMDQ_OFFSET), - statQueueOffset: num::usize_as_u64(Cmdq::STATQ_OFFSET), + pageTableEntryCount: cv!(Cmdq::NUM_PTES), + cmdQueueOffset: u64::from_safe_cast(Cmdq::CMDQ_OFFSET), + statQueueOffset: u64::from_safe_cast(Cmdq::STATQ_OFFSET), ..Zeroable::init_zeroed() }) } @@ -969,7 +963,7 @@ impl GspAcrBootGspRmParams { fn new(target: GspDmaTarget, wpr_meta_addr: u64) -> impl Init { let params =3D init!(Self { target: target as u32, - gspRmDescSize: num::usize_into_u32::<{ size_of::= () }>(), + gspRmDescSize: cv!(size_of::()), gspRmDescOffset: wpr_meta_addr, bIsGspRmBoot: 1, wprCarveoutOffset: 0, diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-co= re/gsp/fw/commands.rs index 32856ff74183..f50cf110a822 100644 --- a/drivers/gpu/nova-core/gsp/fw/commands.rs +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs @@ -82,7 +82,7 @@ pub(crate) fn new(offset: u32, value: u32) -> Self { =20 // We only support DWORD types for now. Support for other = types // will come later if required. - type_: bindings::REGISTRY_TABLE_ENTRY_TYPE_DWORD as u8, + type_: cv!(bindings::REGISTRY_TABLE_ENTRY_TYPE_DWORD), __bindgen_padding_0: Default::default(), data: value, length: 0, diff --git a/drivers/gpu/nova-core/num.rs b/drivers/gpu/nova-core/num.rs index 6eb174d136ab..2e5c9937b3a6 100644 --- a/drivers/gpu/nova-core/num.rs +++ b/drivers/gpu/nova-core/num.rs @@ -96,8 +96,7 @@ pub(crate) const fn [<$from _as_ $into>](value: $from) ->= $into { /// /// Prefer this over the `as` keyword to ensure no lossy casts are perform= ed. /// -/// If you need to perform a conversion in `const` context, use [`u64_as_u= size`], [`u32_as_usize`], -/// [`usize_as_u64`], etc. +/// If you need to perform a conversion in `const` context, use [`cv!`](ke= rnel::num::cv). /// /// # Examples /// @@ -164,58 +163,6 @@ fn into_safe_cast(self) -> T { } } =20 -/// Implements lossless conversion of a constant from a larger type into a= smaller one. -macro_rules! impl_const_into { - ($from:ty =3D> { $($into:ty),* }) =3D> { - $( - paste! { - #[doc =3D ::core::concat!( - "Performs a build-time safe conversion of a [`", - ::core::stringify!($from), - "`] constant value into a [`", - ::core::stringify!($into), - "`].")] - /// - /// This checks at compile-time that the conversion is lossles= s, and triggers a build - /// error if it isn't. - /// - /// # Examples - /// - /// ``` - /// use crate::num; - /// - /// // Succeeds because the value of the source fits into the = destination's type. - #[doc =3D ::core::concat!( - "assert_eq!(num::", - ::core::stringify!($from), - "_into_", - ::core::stringify!($into), - "::<1", - ::core::stringify!($from), - ">(), 1", - ::core::stringify!($into), - ");")] - /// ``` - #[allow(unused)] - pub(crate) const fn [<$from _into_ $into>]() -= > $into { - // Make sure that the target type is smaller than the sour= ce one. - static_assert!($from::BITS >=3D $into::BITS); - // CAST: we statically enforced above that `$from` is larg= er than `$into`, so the - // `as` conversion will be lossless. - build_assert!(N >=3D $into::MIN as $from && N <=3D $into::= MAX as $from); - - N as $into - } - } - )* - }; -} - -impl_const_into!(usize =3D> { u8, u16, u32 }); -impl_const_into!(u64 =3D> { u8, u16, u32 }); -impl_const_into!(u32 =3D> { u8, u16 }); -impl_const_into!(u16 =3D> { u8 }); - /// Creates an enum type associated to a [`Bounded`](kernel::num::Bounded)= , with a [`From`] /// conversion to the associated `Bounded` and either a [`TryFrom`] or `Fr= om` conversion from the /// associated `Bounded`. --=20 2.55.0