Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2225776/?format=api
{ "id": 2225776, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2225776/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260421-io_projection-v2-3-4c251c692ef4@garyguo.net/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/1.1/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<20260421-io_projection-v2-3-4c251c692ef4@garyguo.net>", "date": "2026-04-21T14:56:14", "name": "[v2,03/11] rust: io: use pointer types instead of address", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b7131528c6f597dcd78786ded246553efceb5c1c", "submitter": { "id": 76823, "url": "http://patchwork.ozlabs.org/api/1.1/people/76823/?format=api", "name": "Gary Guo", "email": "gary@garyguo.net" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260421-io_projection-v2-3-4c251c692ef4@garyguo.net/mbox/", "series": [ { "id": 500833, "url": "http://patchwork.ozlabs.org/api/1.1/series/500833/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=500833", "date": "2026-04-21T14:56:19", "name": "rust: I/O type generalization and projection", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/500833/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2225776/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2225776/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-pci+bounces-52842-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=garyguo.net header.i=@garyguo.net header.a=rsa-sha256\n header.s=selector1 header.b=tkQEhTUZ;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-52842-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net\n header.b=\"tkQEhTUZ\"", "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=52.101.196.82", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=garyguo.net", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=garyguo.net", "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=garyguo.net;" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0QcN1Y2Dz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 01:04:20 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 03AF230B5BA8\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 14:56:59 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id EBAD73DA5CD;\n\tTue, 21 Apr 2026 14:56:37 +0000 (UTC)", "from LO3P265CU004.outbound.protection.outlook.com\n (mail-uksouthazon11020082.outbound.protection.outlook.com [52.101.196.82])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id B04AF3D9021;\n\tTue, 21 Apr 2026 14:56:33 +0000 (UTC)", "from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16)\n by CWLP265MB5523.GBRP265.PROD.OUTLOOK.COM (2603:10a6:400:1b9::6) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9846.16; Tue, 21 Apr\n 2026 14:56:28 +0000", "from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.20.9846.016; Tue, 21 Apr 2026\n 14:56:28 +0000" ], "ARC-Seal": [ "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776783397; cv=fail;\n b=OLLvDmjFNUtOJEGBz2a1CcvL6PNyKCvGk1854qdwvcrVWAjUI6HsPECkSVSoFuY417+4MGAIya6gV3sqlQ3tg9+7IU+KpWvMFuZL8PucKSBI0t8uLKhd2SQWA0pPtVb/aSb81B4wzRWDmHHogTHw5bIdN88Qfy1/DUx/qxG9+gM=", "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=HaGwfNv72mYchzzfVvgspeUAuI2IivVFBPgtTeRZbM8DB7aj8ph6hjLfsavrr4OkaDa7R6dU2bW41BUD1xczxYmplHOuIRopjHRUCZD64DFWeEJPRPOIXQtlU303m9sphuUAiYLstFfq1sy4aMmdnDtMQLuC9ShBCSvrrjSBSzkYlPe1pGck6IqJ1kNXs08bEkGfXMDIk4H9GIy1sWJN9CteXURlHH7J3rVRqDPd6Wj3s9rLYIahEeFaDfA/ziYEHfg0nrBAtMEHcSTj5hcph21jZC2k0gBx6MHIJW/07MvH4RKZbb3ki2j4KO5gToq5HJ/8Iq0mposWb0IA2mVUnA==" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776783397; c=relaxed/simple;\n\tbh=+v90d6nPJJL+5nNeYYRyZ5OswaRENd0OB2njGVD8jPs=;\n\th=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To:\n\t To:Cc:MIME-Version;\n b=QD5t00Y0aOuruoAcgbAUzw8u22rErtXZ2Sy39WKCxa1ve0UKcPmQKo47tZwar/1bBqwkA4U+VG5kQ4wleJi1Gf2XDJAiImpsNvKHGENraYFhhf/kzrBzLrl9zKxqhjPGelOqin60D+itESs26k3sLBhqpW7C2LoTLQ4IEBIMFto=", "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n 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;\n bh=LMrf3c+zwtgjUAEfo1PPqVecL3lCus38m4GaKEn0YNE=;\n b=roYH/ekkbH0gAlrjf8/DPh842k2rVGlT3UQRnbKg9wg1bH9/vViiSff1ud08twTma32+/MjHwYsyZ5NTH4VwMNzHXcOicndXmHkFMyKgiynHRghwTztEfbg1NVvadkL88SaAO/mVK0yVShJ7t595kANo5x5mHWFAE58Z7yR/pizjRWiiCFdr3SwRDq/sI4rV3/UhPtYhwH6tWs4HHk8qOaMecODqpNFKOa0pSuq6/O9R8pnWyto3w0KOMXSCe8JI7VyaAOksMfkIe1HQbMDFGEqOSoMioyxe9kx4KdzaZAPMIJzt9CkdnzpGPKzLBmwnAqGABMPe/KxtT+PaBxfUyw==" ], "ARC-Authentication-Results": [ "i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=garyguo.net;\n spf=pass smtp.mailfrom=garyguo.net;\n dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net\n header.b=tkQEhTUZ; arc=fail smtp.client-ip=52.101.196.82", "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net;\n dkim=pass header.d=garyguo.net; arc=none" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=LMrf3c+zwtgjUAEfo1PPqVecL3lCus38m4GaKEn0YNE=;\n b=tkQEhTUZ61ZhGpzOKQRAkuDB0Ly1iKddFS8/n9jWBEiqDV/sIDG8p5Qk3nzPX/wNGsEqH/4cn2ZVK8rbnS9Hzc3KZE9HItMsKkcXyARfOzwVHUA5mL+v9woWxB0Am7zA5YVXHcsh1IefRb8wpWIiOpXxeTrJCABcerLHtg/mxik=", "From": "Gary Guo <gary@garyguo.net>", "Date": "Tue, 21 Apr 2026 15:56:14 +0100", "Subject": "[PATCH v2 03/11] rust: io: use pointer types instead of address", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260421-io_projection-v2-3-4c251c692ef4@garyguo.net>", "References": "<20260421-io_projection-v2-0-4c251c692ef4@garyguo.net>", "In-Reply-To": "<20260421-io_projection-v2-0-4c251c692ef4@garyguo.net>", "To": "Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n \"Rafael J. Wysocki\" <rafael@kernel.org>, Danilo Krummrich <dakr@kernel.org>,\n Miguel Ojeda <ojeda@kernel.org>, Boqun Feng <boqun@kernel.org>,\n Gary Guo <gary@garyguo.net>,\n =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= <bjorn3_gh@protonmail.com>,\n Benno Lossin <lossin@kernel.org>, Andreas Hindborg <a.hindborg@kernel.org>,\n Alice Ryhl <aliceryhl@google.com>, Trevor Gross <tmgross@umich.edu>,\n Daniel Almeida <daniel.almeida@collabora.com>,\n Bjorn Helgaas <bhelgaas@google.com>,\n =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= <kwilczynski@kernel.org>,\n Abdiel Janulgue <abdiel.janulgue@gmail.com>,\n Robin Murphy <robin.murphy@arm.com>,\n Alexandre Courbot <acourbot@nvidia.com>, David Airlie <airlied@gmail.com>,\n Simona Vetter <simona@ffwll.ch>", "Cc": "driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,\n nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org", "X-Mailer": "b4 0.15.1", "X-Developer-Signature": "v=1; a=ed25519-sha256; t=1776783386; l=19161;\n i=gary@garyguo.net; s=20221204; h=from:subject:message-id;\n bh=+v90d6nPJJL+5nNeYYRyZ5OswaRENd0OB2njGVD8jPs=;\n b=vDuEVX4OICrx6bQ7VPCc+PjRpdD5QenD1dHrTb3fP1soxlglMrTgxHWFC/Pgx/QR55uYDaPZF\n 4XiArnKHTapAdTxdAJR9HTNY7MqyWut9f7ldElTDRIiEHGPWx2g0AzF", "X-Developer-Key": "i=gary@garyguo.net; a=ed25519;\n pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo=", "X-ClientProxiedBy": "LO4P123CA0142.GBRP123.PROD.OUTLOOK.COM\n (2603:10a6:600:193::21) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n (2603:10a6:600:488::16)", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "X-MS-PublicTrafficType": "Email", "X-MS-TrafficTypeDiagnostic": "LOVP265MB8871:EE_|CWLP265MB5523:EE_", "X-MS-Office365-Filtering-Correlation-Id": "c3dac4c9-99d0-4c0d-71e0-08de9fb62a9d", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|1800799024|376014|7416014|10070799003|366016|921020|22082099003|18002099003|56012099003;", "X-Microsoft-Antispam-Message-Info": "\n\tr7i6aAoXO9YKwdyiGKUS/f4fYtuhO8bM7SAcvasLLwGpad3OfhLSydN3XkH/vlSMnrE5/YVdP0RBRNIhkPzDUtb7jZddBuxccDsSWRwmKwOS1pKMFbrb/7AvPmk5w+riAJ9CT36kMeS+Gg3i3bQuQ1+U3ieHFmweX41L0TW8r1RZnjRBw0f3QDi+6YyFr50yuB/6FjMTNtUk52BFuKX+NgcLC4lY387m1XjmHQycM779P2TL6ggfjyhoLxxp+cfU4dDmcZVbmwj1lUVT2gOvW1u2PcBizxFq91ThLJxXhxjaTAOzgo/7ao8pdyx0q2+aAl9QMFS5PbvKzF1ZuM0OpnTq7H0UEG9MI/H9yyYH4lMsKW+u0ldXyz6B1eWPjKZdfZtoePTLqQkKvgy7LNS9hvbaVNDt7hM15IVxqhWpnUigm/GFG9ZHdxvhc4gPzcM8/meKQKUgHtaIN7vgn5XpkNGD2oBa/eJpe8ZEIko+05XTN/UQ/Dq+nu+7DXUlSQdnA+cjKlPe5rrgXxx3wqqNXAcycr7drOTp90Zsk+IFPfw+3olqSRu+PD44sI4WSrneixt9PjvKvP+WoRB+Eh3Qcw2c4dMK7wvSV8+t+nBkvkuAq37osGrfLTsJta/nE+g2eJoE3zgkaP9wVOqqGTdwjZy1SDZtS9Ze/PxD7SBbFlvqJoAb91un5rfIwOvob1TsutPHx/ktJrGILV6adHi+W/u0mcNwPzTW+K7b05jZIy/mKkx3Yk60lRAKtB3HaFPeAZe4ffQh0id2PMjfwB5tdA==", "X-Forefront-Antispam-Report": "\n\tCIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(7416014)(10070799003)(366016)(921020)(22082099003)(18002099003)(56012099003);DIR:OUT;SFP:1102;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?vFztxhXR1cJMzM1lTzURu2X97BWc?=\n\t=?utf-8?q?Gdoe4bxxfnPxiLBOvhPsSC8akIpt56vudInjRlU0z0RE+7thwO7dbeO7KFxSQzCQQ?=\n\t=?utf-8?q?uz+Y0AG2Sc2In0fJMUT4GYd/735C8tTmnXPa+gxoAvDX9GIIQcK/bWARFVGKwPNws?=\n\t=?utf-8?q?E+XCPbEzAWrZBLy2n6z6FRSy+QX0SBeJWxn4tx1SVNMFP5i7BqztPYMMm7FKVzwRK?=\n\t=?utf-8?q?E8HUAwhXSW2m3KLkD6BpfX646nq8+7+Fqd4mm0hakj5Fz7tl196zKKFN2HrbbIF9D?=\n\t=?utf-8?q?b6PJU7dxzsq12cv4dGmulND5IM7nYI49hL10NSlZqSGNfodUiQzASr1NoQ9s1l+d5?=\n\t=?utf-8?q?sWdLW+A6QvSl5oMHT57xUEgXuHuxAYZqG0W+vLU4cXjApY4y5MS1pu+our82cP1ah?=\n\t=?utf-8?q?D8XtsPyDyp/lrLqx5lGB3do0xFAHZHt4V9gnMJfGd8cZkrMBjrNFUrqZOvMPrptF/?=\n\t=?utf-8?q?k9E6n/d65SH8xZRrhFC78ADMFx3N1RlqOuawBPtOFCONrYm2Y9ieAqlNGjKpBmJZ0?=\n\t=?utf-8?q?wRYYFUp7Db+2IyyWW5xyAGrTpsoL1g5feXLjNvADe26qM8D3zewS0lzuOrSobnqrs?=\n\t=?utf-8?q?KDtszUhdh1JXK2unJuS4l8ftd+jxJ0lb9owdjtQ7y9S2OwupxXdULNAIXodAPqhtu?=\n\t=?utf-8?q?3Wva2nFGiX8SKM3GmptKzbBWyBK8v9prm5902+2ugQ9mdBCiHvNo2nHIjrpNiEequ?=\n\t=?utf-8?q?f57YtBgAuo7zAyzG1qj1o/QTiAGtMB62Upelyn1VK6uLW+CNzHxIIzNxAOm3pkNU8?=\n\t=?utf-8?q?t3Vhmro3bK1pkJvAXpPwMJfdKOZ2p3J4MibXn4ossfIO58MhhHH2ZN8+o9phVoLrY?=\n\t=?utf-8?q?crJYkx9obCY6uehqxhwvwJORgFqve98ZftCGcGlixzi0TMc5gOosmAZ1HRzT8BOPs?=\n\t=?utf-8?q?RsaM1kXQ8lQyPP11wN80nBYs84p/fa2CDr5pFPt74BuOXsC2N1E5D51rZVGX3BidJ?=\n\t=?utf-8?q?bRvYr409LkyMYGfxBdR3W9q91ilmwm6GmXKPLIrFMIn/Yv+XkbmOzNYDNys74TkjE?=\n\t=?utf-8?q?SEW6eNCOJat/OjucIqaB6SEtrugy0Ub7OWh6eYZQ7T+++CPQtapal7NhYNaV2Yzx0?=\n\t=?utf-8?q?J2nDzVyAbgSPSXH6TKgkrOOVOoCyHALc2uwKtcWiAqN7a8x4tHrJSeVHUQdwXparV?=\n\t=?utf-8?q?24ByaA+XKYAXcz7gU8Fg9haPa4uQyBugxwD/epd5opkvNZ/PxH3x/OoduyQfwAjrX?=\n\t=?utf-8?q?dm+90Ayn1eO1MRri7jejv+DxD4M6/fugO/62SEfIDsi+qCYa+i+tHcFCXUfze/fcg?=\n\t=?utf-8?q?tdoCf2RRHM96KqsT+fU0lidE3F5y8UA/L2NcTikr12Axiryv3yx48XUU5b+ok62wB?=\n\t=?utf-8?q?LCgC1J7F9g2E/hnkGUPggpt7+fuRoa8NhSrSAjLRtU8TR3TYqBzCoFO6qg7RzfQIJ?=\n\t=?utf-8?q?/IZwAbUecmyQJ778FdmEGs8p7N4pxEG66MFtk5m99EJIg19f2n0lbgdIdhOUTY0vr?=\n\t=?utf-8?q?Zy/YItacCI8yPQLGob4KOK22dP7TFRfCK6GI72jUq3i4T/uIj2IEf5cj+GsfSTx56?=\n\t=?utf-8?q?PW2ekMz47vhV0QQ5LI9rE2Y9Q8J9E/cQwBy3yGxgJK0MBOWXYrjQqLMDp2QkZMMo8?=\n\t=?utf-8?q?TmFVzBVUOamdKh8pH+lEAcur+kHVohkFzI+xR0SCgdXkOOa7E3wJ0g6GChEvqSqOq?=\n\t=?utf-8?q?0owp/ngpIvJjIHO/iHcJ9rjC71grFYlA=3D=3D?=", "X-OriginatorOrg": "garyguo.net", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n c3dac4c9-99d0-4c0d-71e0-08de9fb62a9d", "X-MS-Exchange-CrossTenant-AuthSource": "LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM", "X-MS-Exchange-CrossTenant-AuthAs": "Internal", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "21 Apr 2026 14:56:28.1880\n (UTC)", "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted", "X-MS-Exchange-CrossTenant-Id": "bbc898ad-b10f-4e10-8552-d9377b823d45", "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED", "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n hZcMwBZCgR2Ml0FPY5vTc3uhkoRdzqcFg7l8CbxSViYmnI7T4kOGC1IiXxEEiuDjjJN0fGDCE4mx6YAROvplBA==", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CWLP265MB5523" }, "content": "This carries the size information with the pointer type and metadata, makes\nit possible to use I/O projections and paves the way for IO view types.\n\nWith this change, minimum size information becomes available through types;\nso `KnownSize::MIN_SIZE` can be used and `IoKnownSize` trait is no longer\nnecessary. The trait is kept for compatibility and can be removed when\nusers stop using it for bounds.\n\nPCI config space uses only offsets and not pointers like MMIO; for this\nnull pointers (with proper size metadata) is used. This is okay as I/O\ntrait impl and I/O projections can operate on invalid pointers, and for PCI\nconfig space we will only use address info and ignore the provenance.\n\nSigned-off-by: Gary Guo <gary@garyguo.net>\n---\n rust/kernel/devres.rs | 2 +-\n rust/kernel/io.rs | 123 +++++++++++++++++++++-----------------------------\n rust/kernel/io/mem.rs | 2 +-\n rust/kernel/pci/io.rs | 74 ++++++++++++++++++------------\n 4 files changed, 99 insertions(+), 102 deletions(-)", "diff": "diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs\nindex 3e22c63efb98..ea86e9c62cdf 100644\n--- a/rust/kernel/devres.rs\n+++ b/rust/kernel/devres.rs\n@@ -101,7 +101,7 @@ struct Inner<T> {\n /// impl<const SIZE: usize> Drop for IoMem<SIZE> {\n /// fn drop(&mut self) {\n /// // SAFETY: `self.0.addr()` is guaranteed to be properly mapped by `Self::new`.\n-/// unsafe { bindings::iounmap(self.0.addr() as *mut c_void); };\n+/// unsafe { bindings::iounmap(self.0.as_ptr().cast()); };\n /// }\n /// }\n ///\ndiff --git a/rust/kernel/io.rs b/rust/kernel/io.rs\nindex 0b9c97c0a1d7..1682f2a0d20d 100644\n--- a/rust/kernel/io.rs\n+++ b/rust/kernel/io.rs\n@@ -105,8 +105,8 @@ pub fn new_region(addr: usize, size: usize) -> Result<Self> {\n impl<T: ?Sized + KnownSize> MmioRaw<T> {\n /// Returns the base address of the MMIO region.\n #[inline]\n- pub fn addr(&self) -> usize {\n- self.addr.addr()\n+ pub fn as_ptr(&self) -> *mut T {\n+ self.addr\n }\n \n /// Returns the size of the MMIO region.\n@@ -166,7 +166,7 @@ pub fn size(&self) -> usize {\n /// impl<const SIZE: usize> Drop for IoMem<SIZE> {\n /// fn drop(&mut self) {\n /// // SAFETY: `self.0.addr()` is guaranteed to be properly mapped by `Self::new`.\n-/// unsafe { bindings::iounmap(self.0.addr() as *mut c_void); };\n+/// unsafe { bindings::iounmap(self.0.as_ptr().cast()); };\n /// }\n /// }\n ///\n@@ -217,14 +217,14 @@ pub trait IoCapable<T> {\n /// # Safety\n ///\n /// The range `[address..address + size_of::<T>()]` must be within the bounds of `Self`.\n- unsafe fn io_read(&self, address: usize) -> T;\n+ unsafe fn io_read(&self, address: *mut T) -> T;\n \n /// Performs an I/O write of `value` at `address`.\n ///\n /// # Safety\n ///\n /// The range `[address..address + size_of::<T>()]` must be within the bounds of `Self`.\n- unsafe fn io_write(&self, value: T, address: usize);\n+ unsafe fn io_write(&self, value: T, address: *mut T);\n }\n \n /// Describes a given I/O location: its offset, width, and type to convert the raw value from and\n@@ -291,23 +291,35 @@ fn offset(self) -> usize {\n /// For MMIO regions, all widths (u8, u16, u32, and u64 on 64-bit systems) are typically\n /// supported. For PCI configuration space, u8, u16, and u32 are supported but u64 is not.\n pub trait Io {\n- /// Returns the base address of this mapping.\n- fn addr(&self) -> usize;\n+ /// Type of this I/O region. For untyped I/O regions, [`Region`] type can be used.\n+ type Type: ?Sized + KnownSize;\n+\n+ /// Returns the base pointer of this mapping.\n+ ///\n+ /// This is a pointer to capture metadata. The specific meaning of the pointer depends on\n+ /// I/O backend and is not necessarily valid.\n+ fn as_ptr(&self) -> *mut Self::Type;\n+\n+ /// Returns the absolute I/O address for a given `offset`,\n+ /// performing compile-time bound checks.\n+ // Always inline to optimize out error path of `build_assert`.\n+ #[inline(always)]\n+ fn io_addr_assert<U>(&self, offset: usize) -> *mut U {\n+ build_assert!(offset_valid::<U>(offset, Self::Type::MIN_SIZE));\n \n- /// Returns the maximum size of this mapping.\n- fn maxsize(&self) -> usize;\n+ self.as_ptr().wrapping_byte_add(offset).cast()\n+ }\n \n /// Returns the absolute I/O address for a given `offset`,\n /// performing runtime bound checks.\n #[inline]\n- fn io_addr<U>(&self, offset: usize) -> Result<usize> {\n- if !offset_valid::<U>(offset, self.maxsize()) {\n+ fn io_addr<U>(&self, offset: usize) -> Result<*mut U> {\n+ let ptr = self.as_ptr();\n+ if !offset_valid::<U>(offset, Self::Type::size(ptr)) {\n return Err(EINVAL);\n }\n \n- // Probably no need to check, since the safety requirements of `Self::new` guarantee that\n- // this can't overflow.\n- self.addr().checked_add(offset).ok_or(EINVAL)\n+ Ok(ptr.wrapping_byte_add(offset).cast())\n }\n \n /// Fallible 8-bit read with runtime bounds check.\n@@ -386,7 +398,7 @@ fn try_write64(&self, value: u64, offset: usize) -> Result\n #[inline(always)]\n fn read8(&self, offset: usize) -> u8\n where\n- Self: IoKnownSize + IoCapable<u8>,\n+ Self: IoCapable<u8>,\n {\n self.read(offset)\n }\n@@ -395,7 +407,7 @@ fn read8(&self, offset: usize) -> u8\n #[inline(always)]\n fn read16(&self, offset: usize) -> u16\n where\n- Self: IoKnownSize + IoCapable<u16>,\n+ Self: IoCapable<u16>,\n {\n self.read(offset)\n }\n@@ -404,7 +416,7 @@ fn read16(&self, offset: usize) -> u16\n #[inline(always)]\n fn read32(&self, offset: usize) -> u32\n where\n- Self: IoKnownSize + IoCapable<u32>,\n+ Self: IoCapable<u32>,\n {\n self.read(offset)\n }\n@@ -413,7 +425,7 @@ fn read32(&self, offset: usize) -> u32\n #[inline(always)]\n fn read64(&self, offset: usize) -> u64\n where\n- Self: IoKnownSize + IoCapable<u64>,\n+ Self: IoCapable<u64>,\n {\n self.read(offset)\n }\n@@ -422,7 +434,7 @@ fn read64(&self, offset: usize) -> u64\n #[inline(always)]\n fn write8(&self, value: u8, offset: usize)\n where\n- Self: IoKnownSize + IoCapable<u8>,\n+ Self: IoCapable<u8>,\n {\n self.write(offset, value)\n }\n@@ -431,7 +443,7 @@ fn write8(&self, value: u8, offset: usize)\n #[inline(always)]\n fn write16(&self, value: u16, offset: usize)\n where\n- Self: IoKnownSize + IoCapable<u16>,\n+ Self: IoCapable<u16>,\n {\n self.write(offset, value)\n }\n@@ -440,7 +452,7 @@ fn write16(&self, value: u16, offset: usize)\n #[inline(always)]\n fn write32(&self, value: u32, offset: usize)\n where\n- Self: IoKnownSize + IoCapable<u32>,\n+ Self: IoCapable<u32>,\n {\n self.write(offset, value)\n }\n@@ -449,7 +461,7 @@ fn write32(&self, value: u32, offset: usize)\n #[inline(always)]\n fn write64(&self, value: u64, offset: usize)\n where\n- Self: IoKnownSize + IoCapable<u64>,\n+ Self: IoCapable<u64>,\n {\n self.write(offset, value)\n }\n@@ -637,7 +649,7 @@ fn try_update<T, L, F>(&self, location: L, f: F) -> Result\n fn read<T, L>(&self, location: L) -> T\n where\n L: IoLoc<T>,\n- Self: IoKnownSize + IoCapable<L::IoType>,\n+ Self: IoCapable<L::IoType>,\n {\n let address = self.io_addr_assert::<L::IoType>(location.offset());\n \n@@ -670,7 +682,7 @@ fn read<T, L>(&self, location: L) -> T\n fn write<T, L>(&self, location: L, value: T)\n where\n L: IoLoc<T>,\n- Self: IoKnownSize + IoCapable<L::IoType>,\n+ Self: IoCapable<L::IoType>,\n {\n let address = self.io_addr_assert::<L::IoType>(location.offset());\n let io_value = value.into();\n@@ -715,7 +727,7 @@ fn write_reg<T, L, V>(&self, value: V)\n where\n L: IoLoc<T>,\n V: LocatedRegister<Location = L, Value = T>,\n- Self: IoKnownSize + IoCapable<L::IoType>,\n+ Self: IoCapable<L::IoType>,\n {\n let (location, value) = value.into_io_op();\n \n@@ -748,7 +760,7 @@ fn write_reg<T, L, V>(&self, value: V)\n fn update<T, L, F>(&self, location: L, f: F)\n where\n L: IoLoc<T>,\n- Self: IoKnownSize + IoCapable<L::IoType> + Sized,\n+ Self: IoCapable<L::IoType>,\n F: FnOnce(T) -> T,\n {\n let address = self.io_addr_assert::<L::IoType>(location.offset());\n@@ -762,41 +774,25 @@ fn update<T, L, F>(&self, location: L, f: F)\n }\n }\n \n-/// Trait for types with a known size at compile time.\n-///\n-/// This trait is implemented by I/O backends that have a compile-time known size,\n-/// enabling the use of infallible I/O accessors with compile-time bounds checking.\n-///\n-/// Types implementing this trait can use the infallible methods in [`Io`] trait\n-/// (e.g., `read8`, `write32`), which require `Self: IoKnownSize` bound.\n-pub trait IoKnownSize: Io {\n- /// Minimum usable size of this region.\n- const MIN_SIZE: usize;\n-\n- /// Returns the absolute I/O address for a given `offset`,\n- /// performing compile-time bound checks.\n- // Always inline to optimize out error path of `build_assert`.\n- #[inline(always)]\n- fn io_addr_assert<U>(&self, offset: usize) -> usize {\n- build_assert!(offset_valid::<U>(offset, Self::MIN_SIZE));\n+// For compatibility only.\n+#[doc(hidden)]\n+pub trait IoKnownSize: Io {}\n \n- self.addr() + offset\n- }\n-}\n+impl<T: Io + ?Sized> IoKnownSize for T {}\n \n /// Implements [`IoCapable`] on `$mmio` for `$ty` using `$read_fn` and `$write_fn`.\n macro_rules! impl_mmio_io_capable {\n ($mmio:ident, $(#[$attr:meta])* $ty:ty, $read_fn:ident, $write_fn:ident) => {\n $(#[$attr])*\n impl<T: ?Sized> IoCapable<$ty> for $mmio<T> {\n- unsafe fn io_read(&self, address: usize) -> $ty {\n+ unsafe fn io_read(&self, address: *mut $ty) -> $ty {\n // SAFETY: By the trait invariant `address` is a valid address for MMIO operations.\n unsafe { bindings::$read_fn(address as *const c_void) }\n }\n \n- unsafe fn io_write(&self, value: $ty, address: usize) {\n+ unsafe fn io_write(&self, value: $ty, address: *mut $ty) {\n // SAFETY: By the trait invariant `address` is a valid address for MMIO operations.\n- unsafe { bindings::$write_fn(value, address as *mut c_void) }\n+ unsafe { bindings::$write_fn(value, address.cast()) }\n }\n }\n };\n@@ -816,23 +812,15 @@ unsafe fn io_write(&self, value: $ty, address: usize) {\n );\n \n impl<T: ?Sized + KnownSize> Io for Mmio<T> {\n- /// Returns the base address of this mapping.\n- #[inline]\n- fn addr(&self) -> usize {\n- self.0.addr()\n- }\n+ type Type = T;\n \n- /// Returns the maximum size of this mapping.\n+ /// Returns the base address of this mapping.\n #[inline]\n- fn maxsize(&self) -> usize {\n- self.0.size()\n+ fn as_ptr(&self) -> *mut T {\n+ self.0.as_ptr()\n }\n }\n \n-impl<T: ?Sized + KnownSize> IoKnownSize for Mmio<T> {\n- const MIN_SIZE: usize = T::MIN_SIZE;\n-}\n-\n impl<T: ?Sized + KnownSize> Mmio<T> {\n /// Converts an `MmioRaw` into an `Mmio` instance, providing the accessors to the MMIO mapping.\n ///\n@@ -856,21 +844,14 @@ pub unsafe fn from_raw(raw: &MmioRaw<T>) -> &Self {\n pub struct RelaxedMmio<T: ?Sized>(Mmio<T>);\n \n impl<T: ?Sized + KnownSize> Io for RelaxedMmio<T> {\n- #[inline]\n- fn addr(&self) -> usize {\n- self.0.addr()\n- }\n+ type Type = T;\n \n #[inline]\n- fn maxsize(&self) -> usize {\n- self.0.maxsize()\n+ fn as_ptr(&self) -> *mut T {\n+ self.0.as_ptr()\n }\n }\n \n-impl<T: ?Sized + KnownSize> IoKnownSize for RelaxedMmio<T> {\n- const MIN_SIZE: usize = T::MIN_SIZE;\n-}\n-\n impl<T: ?Sized> Mmio<T> {\n /// Returns a [`RelaxedMmio`] reference that performs relaxed I/O operations.\n ///\ndiff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs\nindex a6292f4ebfa4..f87a29f90e79 100644\n--- a/rust/kernel/io/mem.rs\n+++ b/rust/kernel/io/mem.rs\n@@ -284,7 +284,7 @@ pub fn new<'a>(io_request: IoRequest<'a>) -> impl PinInit<Devres<Self>, Error> +\n impl<const SIZE: usize> Drop for IoMem<SIZE> {\n fn drop(&mut self) {\n // SAFETY: Safe as by the invariant of `Io`.\n- unsafe { bindings::iounmap(self.io.addr() as *mut c_void) }\n+ unsafe { bindings::iounmap(self.io.as_ptr().cast()) }\n }\n }\n \ndiff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs\nindex e048370fb8c1..63c35eaab6c3 100644\n--- a/rust/kernel/pci/io.rs\n+++ b/rust/kernel/pci/io.rs\n@@ -10,11 +10,11 @@\n io::{\n Io,\n IoCapable,\n- IoKnownSize,\n Mmio,\n MmioRaw, //\n },\n prelude::*,\n+ ptr::KnownSize,\n sync::aref::ARef, //\n };\n use core::{\n@@ -60,14 +60,37 @@ pub const fn into_raw(self) -> usize {\n pub trait ConfigSpaceKind {\n /// The size of this configuration space in bytes.\n const SIZE: usize;\n+\n+ /// Region type for this kind of config space. This should be [`crate::io::Region<SIZE>`].\n+ type Region: ?Sized + KnownSize;\n+\n+ /// Obtain pointer with actual size information.\n+ fn null_ptr_from_size(size: ConfigSpaceSize) -> *mut Self::Region;\n }\n \n impl ConfigSpaceKind for Normal {\n const SIZE: usize = 256;\n+\n+ type Region = crate::io::Region<256>;\n+\n+ #[inline]\n+ fn null_ptr_from_size(size: ConfigSpaceSize) -> *mut Self::Region {\n+ core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut::<u8>(), size.into_raw())\n+ as *mut Self::Region\n+ }\n }\n \n impl ConfigSpaceKind for Extended {\n const SIZE: usize = 4096;\n+\n+ type Region = crate::io::Region<4096>;\n+\n+ #[inline]\n+ fn null_ptr_from_size(_: ConfigSpaceSize) -> *mut Self::Region {\n+ // Small optimization. For a extended config space, we already know that the size\n+ // is 4096.\n+ core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut::<u8>(), 4096) as *mut Self::Region\n+ }\n }\n \n /// The PCI configuration space of a device.\n@@ -87,28 +110,28 @@ pub struct ConfigSpace<'a, S: ConfigSpaceKind = Extended> {\n macro_rules! impl_config_space_io_capable {\n ($ty:ty, $read_fn:ident, $write_fn:ident) => {\n impl<'a, S: ConfigSpaceKind> IoCapable<$ty> for ConfigSpace<'a, S> {\n- unsafe fn io_read(&self, address: usize) -> $ty {\n+ unsafe fn io_read(&self, address: *mut $ty) -> $ty {\n+ // CAST: The offset is cast to `i32` because the C functions expect a 32-bit\n+ // signed offset parameter. PCI configuration space size is at most 4096 bytes,\n+ // so the value always fits within `i32` without truncation or sign change.\n+ let addr = address.addr() as i32;\n let mut val: $ty = 0;\n \n // Return value from C function is ignored in infallible accessors.\n- let _ret =\n- // SAFETY: By the type invariant `self.pdev` is a valid address.\n- // CAST: The offset is cast to `i32` because the C functions expect a 32-bit\n- // signed offset parameter. PCI configuration space size is at most 4096 bytes,\n- // so the value always fits within `i32` without truncation or sign change.\n- unsafe { bindings::$read_fn(self.pdev.as_raw(), address as i32, &mut val) };\n-\n+ // SAFETY: By the type invariant `self.pdev` is a valid address.\n+ let _ = unsafe { bindings::$read_fn(self.pdev.as_raw(), addr, &mut val) };\n val\n }\n \n- unsafe fn io_write(&self, value: $ty, address: usize) {\n+ unsafe fn io_write(&self, value: $ty, address: *mut $ty) {\n+ // CAST: The offset is cast to `i32` because the C functions expect a 32-bit\n+ // signed offset parameter. PCI configuration space size is at most 4096 bytes,\n+ // so the value always fits within `i32` without truncation or sign change.\n+ let addr = address.addr() as i32;\n+\n // Return value from C function is ignored in infallible accessors.\n- let _ret =\n- // SAFETY: By the type invariant `self.pdev` is a valid address.\n- // CAST: The offset is cast to `i32` because the C functions expect a 32-bit\n- // signed offset parameter. PCI configuration space size is at most 4096 bytes,\n- // so the value always fits within `i32` without truncation or sign change.\n- unsafe { bindings::$write_fn(self.pdev.as_raw(), address as i32, value) };\n+ // SAFETY: By the type invariant `self.pdev` is a valid address.\n+ let _ = unsafe { bindings::$write_fn(self.pdev.as_raw(), addr, value) };\n }\n }\n };\n@@ -120,23 +143,15 @@ unsafe fn io_write(&self, value: $ty, address: usize) {\n impl_config_space_io_capable!(u32, pci_read_config_dword, pci_write_config_dword);\n \n impl<'a, S: ConfigSpaceKind> Io for ConfigSpace<'a, S> {\n- /// Returns the base address of the I/O region. It is always 0 for configuration space.\n- #[inline]\n- fn addr(&self) -> usize {\n- 0\n- }\n+ type Type = S::Region;\n \n- /// Returns the maximum size of the configuration space.\n+ /// Returns the base address of the I/O region. It is always 0 for configuration space.\n #[inline]\n- fn maxsize(&self) -> usize {\n- self.pdev.cfg_size().into_raw()\n+ fn as_ptr(&self) -> *mut Self::Type {\n+ S::null_ptr_from_size(self.pdev.cfg_size())\n }\n }\n \n-impl<'a, S: ConfigSpaceKind> IoKnownSize for ConfigSpace<'a, S> {\n- const MIN_SIZE: usize = S::SIZE;\n-}\n-\n /// A PCI BAR to perform I/O-Operations on.\n ///\n /// I/O backend assumes that the device is little-endian and will automatically\n@@ -219,7 +234,7 @@ unsafe fn do_release(pdev: &Device, ioptr: usize, num: i32) {\n \n fn release(&self) {\n // SAFETY: The safety requirements are guaranteed by the type invariant of `self.pdev`.\n- unsafe { Self::do_release(&self.pdev, self.io.addr(), self.num) };\n+ unsafe { Self::do_release(&self.pdev, self.io.as_ptr().addr(), self.num) };\n }\n }\n \n@@ -267,6 +282,7 @@ pub fn iomap_region<'a>(\n }\n \n /// Returns the size of configuration space.\n+ #[inline]\n pub fn cfg_size(&self) -> ConfigSpaceSize {\n // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`.\n let size = unsafe { (*self.as_raw()).cfg_size };\n", "prefixes": [ "v2", "03/11" ] }