{"id":2220256,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2220256/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260406165120.166928-4-wenzhaoliao@ruc.edu.cn/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.1/projects/28/?format=json","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":"<20260406165120.166928-4-wenzhaoliao@ruc.edu.cn>","date":"2026-04-06T16:51:17","name":"[RFC,v3,3/6] rust: page: add helpers for page-backed ping state","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"de6d5511728809bb670c4b947ad14781db272ac0","submitter":{"id":93071,"url":"http://patchwork.ozlabs.org/api/1.1/people/93071/?format=json","name":"Wenzhao Liao","email":"wenzhaoliao@ruc.edu.cn"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260406165120.166928-4-wenzhaoliao@ruc.edu.cn/mbox/","series":[{"id":498880,"url":"http://patchwork.ozlabs.org/api/1.1/series/498880/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=498880","date":"2026-04-06T16:51:15","name":"Rust goldfish_address_space driver (ioctl-only subset)","version":3,"mbox":"http://patchwork.ozlabs.org/series/498880/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2220256/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2220256/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-51976-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=ruc.edu.cn header.i=@ruc.edu.cn header.a=rsa-sha256\n header.s=default header.b=cUnJcBHG;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c09:e001:a7::12fc:5321; helo=sto.lore.kernel.org;\n envelope-from=linux-pci+bounces-51976-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=ruc.edu.cn header.i=@ruc.edu.cn\n header.b=\"cUnJcBHG\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=103.209.128.214","smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=ruc.edu.cn","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=ruc.edu.cn"],"Received":["from sto.lore.kernel.org (sto.lore.kernel.org\n [IPv6:2600:3c09:e001:a7::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fqJsq62nLz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 07 Apr 2026 05:14:23 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sto.lore.kernel.org (Postfix) with ESMTP id 8B672300DCEA\n\tfor <incoming@patchwork.ozlabs.org>; Mon,  6 Apr 2026 19:14:19 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 35831396595;\n\tMon,  6 Apr 2026 19:14:18 +0000 (UTC)","from mail-m128214.netease.com (mail-m128214.netease.com\n [103.209.128.214])\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 2130F38C433;\n\tMon,  6 Apr 2026 19:14:12 +0000 (UTC)","from lwz.tail698a0e.ts.net\n (gy-adaptive-ssl-proxy-1-entmail-virt204.gy.ntes [36.112.3.244])\n\tby smtp.qiye.163.com (Hmail) with ESMTP id 39aaefbdd;\n\tTue, 7 Apr 2026 00:51:34 +0800 (GMT+08:00)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775502858; cv=none;\n b=CNvCJpiD5ydppmTOhssG1SNtONC7xACZAwqRhcf/6GUWy5UVNI/Gg4QvEAaksVwCyYopSaS9wouRRxQjMDx9xnXHK6AHKT+dN2X//PSxPz/5HYR2NNZdP9DyhEpCUk1S2VlaUgd8ijjWvEKNvlGQg3AG7/fNdT9vRH/tnP0hVj4=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775502858; c=relaxed/simple;\n\tbh=KnDk22NqfK2A5VmoRBMw4hkb6fV0LQGmL7Q7xj9UxpE=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=qgDGGJyi1gut72bPIrcqyFuURJxV67xKp/NeQJCYUh/Fn3/LOKspIn0YuRSiftnzOfaUBo8/dPv0aY5eztM/OIS9czSuMOrpE6DI8QEkoj1W3N4shqfnUVwhqG6HyLLnApQKMUeg/qednaKtcrwBGTLyOsA7cV4fex/l4kdkokU=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=ruc.edu.cn;\n spf=pass smtp.mailfrom=ruc.edu.cn;\n dkim=pass (1024-bit key) header.d=ruc.edu.cn header.i=@ruc.edu.cn\n header.b=cUnJcBHG; arc=none smtp.client-ip=103.209.128.214","From":"Wenzhao Liao <wenzhaoliao@ruc.edu.cn>","To":"rust-for-linux@vger.kernel.org,\n\tlinux-pci@vger.kernel.org","Cc":"ojeda@kernel.org,\n\tdakr@kernel.org,\n\tbhelgaas@google.com,\n\tkwilczynski@kernel.org,\n\tarnd@arndb.de,\n\tgregkh@linuxfoundation.org,\n\tlinux-kernel@vger.kernel.org,\n\tlinux-api@vger.kernel.org","Subject":"[RFC PATCH v3 3/6] rust: page: add helpers for page-backed ping state","Date":"Mon,  6 Apr 2026 12:51:17 -0400","Message-Id":"<20260406165120.166928-4-wenzhaoliao@ruc.edu.cn>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20260406165120.166928-1-wenzhaoliao@ruc.edu.cn>","References":"<cover.1775456181.git.wenzhaoliao@ruc.edu.cn>\n <20260406165120.166928-1-wenzhaoliao@ruc.edu.cn>","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","Content-Transfer-Encoding":"8bit","X-HM-Tid":"0a9d63b4eb5a03a2kunm562d3b0d647e7c","X-HM-MType":"10","X-HM-Spam-Status":"e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly\n\ttZV1koWUFITzdXWS1ZQUlXWQ8JGhUIEh9ZQVlCTRgaVkJOSh4eTksZSUsaSVYeHw5VEwETFhoSFy\n\tQUDg9ZV1kYEgtZQVlITVVKSklVSFVJT09ZV1kWGg8SFR0UWUFZT0tIVUpLSEpOTE5VSktLVUpCS0\n\ttZBg++","DKIM-Signature":"a=rsa-sha256;\n\tb=cUnJcBHGiOx97/kgEgPi7Kd1EEfqAQImO7E/GBbnA46rDS77dufPinwtyGC8Gy8oWi02nrZ1qBHWhqJLQBRwmPUniLy/xWqWeBZg3pOWN0bSHsN5ppdXQhEqmCTuSnYJfyCZYvdkLgqwrP4jk1Dx3NNmJnAqJUVe1YKzkCJlMsY=;\n c=relaxed/relaxed; s=default; d=ruc.edu.cn; v=1;\n\tbh=kKwjlPbz8irjEUZ4cgjU35rxHOQIvjj9A2j4f+K6xtA=;\n\th=date:mime-version:subject:message-id:from;"},"content":"Add the minimal safe page helpers needed by the goldfish ping buffer: physical address discovery plus bounded read, write, and zeroing operations.\n\nThe driver uses these helpers to manage its per-file ping page entirely from safe Rust while keeping the raw page mapping and pointer handling inside the page abstraction.\n\nSigned-off-by: Wenzhao Liao <wenzhaoliao@ruc.edu.cn>\n---\n rust/helpers/page.c |  5 +++++\n rust/kernel/page.rs | 52 +++++++++++++++++++++++----------------------\n 2 files changed, 32 insertions(+), 25 deletions(-)","diff":"diff --git a/rust/helpers/page.c b/rust/helpers/page.c\nindex f8463fbed2a2..05824bdc4fd8 100644\n--- a/rust/helpers/page.c\n+++ b/rust/helpers/page.c\n@@ -20,6 +20,11 @@ __rust_helper void rust_helper_kunmap_local(const void *addr)\n \tkunmap_local(addr);\n }\n \n+__rust_helper phys_addr_t rust_helper_page_to_phys(struct page *page)\n+{\n+\treturn page_to_phys(page);\n+}\n+\n #ifndef NODE_NOT_IN_PAGE_FLAGS\n __rust_helper int rust_helper_page_to_nid(const struct page *page)\n {\ndiff --git a/rust/kernel/page.rs b/rust/kernel/page.rs\nindex adecb200c654..e8336d1bcc12 100644\n--- a/rust/kernel/page.rs\n+++ b/rust/kernel/page.rs\n@@ -7,7 +7,7 @@\n     bindings,\n     error::code::*,\n     error::Result,\n-    uaccess::UserSliceReader,\n+    io::PhysAddr,\n };\n use core::{\n     marker::PhantomData,\n@@ -198,6 +198,13 @@ pub fn nid(&self) -> i32 {\n         unsafe { bindings::page_to_nid(self.as_ptr()) }\n     }\n \n+    /// Returns the physical address of the start of this page.\n+    #[inline]\n+    pub fn phys_addr(&self) -> PhysAddr {\n+        // SAFETY: `self.as_ptr()` is a live `struct page` owned by this `Page`.\n+        unsafe { bindings::page_to_phys(self.as_ptr()) }\n+    }\n+\n     /// Runs a piece of code with this page mapped to an address.\n     ///\n     /// The page is unmapped when this call returns.\n@@ -337,30 +344,25 @@ pub unsafe fn fill_zero_raw(&self, offset: usize, len: usize) -> Result {\n         })\n     }\n \n-    /// Copies data from userspace into this page.\n-    ///\n-    /// This method will perform bounds checks on the page offset. If `offset .. offset+len` goes\n-    /// outside of the page, then this call returns [`EINVAL`].\n-    ///\n-    /// Like the other `UserSliceReader` methods, data races are allowed on the userspace address.\n-    /// However, they are not allowed on the page you are copying into.\n-    ///\n-    /// # Safety\n-    ///\n-    /// Callers must ensure that this call does not race with a read or write to the same page that\n-    /// overlaps with this write.\n-    pub unsafe fn copy_from_user_slice_raw(\n-        &self,\n-        reader: &mut UserSliceReader,\n-        offset: usize,\n-        len: usize,\n-    ) -> Result {\n-        self.with_pointer_into_page(offset, len, move |dst| {\n-            // SAFETY: If `with_pointer_into_page` calls into this closure, then it has performed a\n-            // bounds check and guarantees that `dst` is valid for `len` bytes. Furthermore, we have\n-            // exclusive access to the slice since the caller guarantees that there are no races.\n-            reader.read_raw(unsafe { core::slice::from_raw_parts_mut(dst.cast(), len) })\n-        })\n+    /// Maps the page and reads from it into the given buffer.\n+    pub fn read_slice(&self, dst: &mut [u8], offset: usize) -> Result {\n+        // SAFETY: `dst` is a valid mutable slice for `dst.len()` bytes. Safe Rust also prevents\n+        // callers from obtaining a mutable reference to this `Page` while this shared borrow\n+        // exists, so concurrent writes through the safe API cannot overlap with this read.\n+        unsafe { self.read_raw(dst.as_mut_ptr(), offset, dst.len()) }\n+    }\n+\n+    /// Maps the page and writes the given buffer into it.\n+    pub fn write_slice(&mut self, src: &[u8], offset: usize) -> Result {\n+        // SAFETY: `src` is a valid immutable slice for `src.len()` bytes, and `&mut self`\n+        // guarantees unique access to the page through the safe API.\n+        unsafe { self.write_raw(src.as_ptr(), offset, src.len()) }\n+    }\n+\n+    /// Zeroes a range within the page.\n+    pub fn fill_zero(&mut self, offset: usize, len: usize) -> Result {\n+        // SAFETY: `&mut self` guarantees unique access to the page through the safe API.\n+        unsafe { self.fill_zero_raw(offset, len) }\n     }\n }\n \n","prefixes":["RFC","v3","3/6"]}