* Re: [PATCH 07/13] VFS: make lookup_one_qstr_excl() static.
From: Jeff Layton @ 2026-02-05 12:37 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-8-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> lookup_one_qstr_excl() is no longer used outside of namei.c, so
> make it static.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> Documentation/filesystems/porting.rst | 7 +++++++
> fs/namei.c | 5 ++---
> include/linux/namei.h | 3 ---
> 3 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
> index ed3ac56e3c76..ed86c95d9d01 100644
> --- a/Documentation/filesystems/porting.rst
> +++ b/Documentation/filesystems/porting.rst
> @@ -1340,3 +1340,10 @@ The ->setlease() file_operation must now be explicitly set in order to provide
> support for leases. When set to NULL, the kernel will now return -EINVAL to
> attempts to set a lease. Filesystems that wish to use the kernel-internal lease
> implementation should set it to generic_setlease().
> +
> +---
> +
> +**mandatory**
> +
> +lookup_one_qstr_excl() is no longer exported - use start_creating() or
> +similar.
> diff --git a/fs/namei.c b/fs/namei.c
> index 40af78ddfb1b..307b4d0866b8 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -1730,8 +1730,8 @@ static struct dentry *lookup_dcache(const struct qstr *name,
> * Will return -ENOENT if name isn't found and LOOKUP_CREATE wasn't passed.
> * Will return -EEXIST if name is found and LOOKUP_EXCL was passed.
> */
> -struct dentry *lookup_one_qstr_excl(const struct qstr *name,
> - struct dentry *base, unsigned int flags)
> +static struct dentry *lookup_one_qstr_excl(const struct qstr *name,
> + struct dentry *base, unsigned int flags)
> {
> struct dentry *dentry;
> struct dentry *old;
> @@ -1768,7 +1768,6 @@ struct dentry *lookup_one_qstr_excl(const struct qstr *name,
> }
> return dentry;
> }
> -EXPORT_SYMBOL(lookup_one_qstr_excl);
>
> /**
> * lookup_fast - do fast lockless (but racy) lookup of a dentry
> diff --git a/include/linux/namei.h b/include/linux/namei.h
> index 58600cf234bc..c7a7288cdd25 100644
> --- a/include/linux/namei.h
> +++ b/include/linux/namei.h
> @@ -54,9 +54,6 @@ extern int path_pts(struct path *path);
>
> extern int user_path_at(int, const char __user *, unsigned, struct path *);
>
> -struct dentry *lookup_one_qstr_excl(const struct qstr *name,
> - struct dentry *base,
> - unsigned int flags);
> extern int kern_path(const char *, unsigned, struct path *);
> struct dentry *kern_path_parent(const char *name, struct path *parent);
>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 06/13] nfsd: switch purge_old() to use start_removing_noperm()
From: Jeff Layton @ 2026-02-05 12:36 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-7-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> Rather than explicit locking, use the start_removing_noperm() and
> end_removing() wrappers.
> This was not done with other start_removing changes due to conflicting
> in-flight patches.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> fs/nfsd/nfs4recover.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
> index 441dfbfe2d2b..52fbe723a3c8 100644
> --- a/fs/nfsd/nfs4recover.c
> +++ b/fs/nfsd/nfs4recover.c
> @@ -351,16 +351,14 @@ purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
> if (nfs4_has_reclaimed_state(name, nn))
> goto out_free;
>
> - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
> - child = lookup_one(&nop_mnt_idmap, &QSTR(cname), parent);
> + child = start_removing_noperm(parent, &QSTR(cname));
> if (!IS_ERR(child)) {
> status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL);
> if (status)
> printk("failed to remove client recovery directory %pd\n",
> child);
> - dput(child);
> }
> - inode_unlock(d_inode(parent));
> + end_removing(child);
>
> out_free:
> kfree(name.data);
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 05/13] selinux: Use simple_start_creating() / simple_done_creating()
From: Jeff Layton @ 2026-02-05 12:36 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-6-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> Instead of explicitly locking the parent and performing a lookup in
> selinux, use simple_start_creating(), and then use
> simple_done_creating() to unlock.
>
> This extends the region that the directory is locked for, and also
> performs a lookup.
> The lock extension is of no real consequence.
> The lookup uses simple_lookup() and so always succeeds. Thus when
> d_make_persistent() is called the dentry will already be hashed.
> d_make_persistent() handles this case.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> security/selinux/selinuxfs.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 896acad1f5f7..97e02cd5a9dc 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -1930,15 +1930,16 @@ static const struct inode_operations swapover_dir_inode_operations = {
> static struct dentry *sel_make_swapover_dir(struct super_block *sb,
> unsigned long *ino)
> {
> - struct dentry *dentry = d_alloc_name(sb->s_root, ".swapover");
> + struct dentry *dentry;
> struct inode *inode;
>
> - if (!dentry)
> + inode = sel_make_inode(sb, S_IFDIR);
> + if (!inode)
> return ERR_PTR(-ENOMEM);
>
> - inode = sel_make_inode(sb, S_IFDIR);
> - if (!inode) {
> - dput(dentry);
> + dentry = simple_start_creating(sb->s_root, ".swapover");
> + if (!dentry) {
> + iput(inode);
> return ERR_PTR(-ENOMEM);
> }
>
> @@ -1946,11 +1947,9 @@ static struct dentry *sel_make_swapover_dir(struct super_block *sb,
> inode->i_ino = ++(*ino);
> /* directory inodes start off with i_nlink == 2 (for "." entry) */
> inc_nlink(inode);
> - inode_lock(sb->s_root->d_inode);
> d_make_persistent(dentry, inode);
> inc_nlink(sb->s_root->d_inode);
> - inode_unlock(sb->s_root->d_inode);
> - dput(dentry);
> + simple_done_creating(dentry);
> return dentry; // borrowed
> }
>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 02/13] VFS: move the start_dirop() kerndoc comment to before start_dirop()
From: Jeff Layton @ 2026-02-05 12:33 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-3-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> This kerneldoc comment was always meant for start_dirop(), not for
> __start_dirop() which is a static function and doesn't need
> documentation.
>
> It was in the wrong place and was then incorrectly renamed (instead of
> moved) and useless "documentation" was added for "@state" was provided.
>
> This patch reverts the name, removes the mention of @state, and moves
> the comment to where it belongs.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> fs/namei.c | 27 +++++++++++++--------------
> 1 file changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index b28ecb699f32..40af78ddfb1b 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -2841,20 +2841,6 @@ static int filename_parentat(int dfd, struct filename *name,
> return __filename_parentat(dfd, name, flags, parent, last, type, NULL);
> }
>
> -/**
> - * __start_dirop - begin a create or remove dirop, performing locking and lookup
> - * @parent: the dentry of the parent in which the operation will occur
> - * @name: a qstr holding the name within that parent
> - * @lookup_flags: intent and other lookup flags.
> - * @state: task state bitmask
> - *
> - * The lookup is performed and necessary locks are taken so that, on success,
> - * the returned dentry can be operated on safely.
> - * The qstr must already have the hash value calculated.
> - *
> - * Returns: a locked dentry, or an error.
> - *
> - */
> static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name,
> unsigned int lookup_flags,
> unsigned int state)
> @@ -2876,6 +2862,19 @@ static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name,
> return dentry;
> }
>
> +/**
> + * start_dirop - begin a create or remove dirop, performing locking and lookup
> + * @parent: the dentry of the parent in which the operation will occur
> + * @name: a qstr holding the name within that parent
> + * @lookup_flags: intent and other lookup flags.
> + *
> + * The lookup is performed and necessary locks are taken so that, on success,
> + * the returned dentry can be operated on safely.
> + * The qstr must already have the hash value calculated.
> + *
> + * Returns: a locked dentry, or an error.
> + *
> + */
> struct dentry *start_dirop(struct dentry *parent, struct qstr *name,
> unsigned int lookup_flags)
> {
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 01/13] fs/proc: Don't lock root inode when creating "self" and "thread-self"
From: Jeff Layton @ 2026-02-05 12:33 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-2-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> proc_setup_self() and proc_setup_thread_self() are only called from
> proc_fill_super() which is before the filesystem is "live". So there is
> no need to lock the root directory when adding "self" and "thread-self".
> This is clear from simple_fill_super() which provides similar
> functionality for other filesystems and does not lock anything.
>
> The locking is not harmful, except that it may be confusing to a reader.
> As part of a an effort to centralise all locking for directories for
> name-based operations (prior to changing some locking rules), it is
> simplest to remove the locking here.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> fs/proc/self.c | 3 ---
> fs/proc/thread_self.c | 3 ---
> 2 files changed, 6 deletions(-)
>
> diff --git a/fs/proc/self.c b/fs/proc/self.c
> index 62d2c0cfe35c..56adf1c68f7a 100644
> --- a/fs/proc/self.c
> +++ b/fs/proc/self.c
> @@ -35,11 +35,9 @@ unsigned self_inum __ro_after_init;
>
> int proc_setup_self(struct super_block *s)
> {
> - struct inode *root_inode = d_inode(s->s_root);
> struct dentry *self;
> int ret = -ENOMEM;
>
> - inode_lock(root_inode);
> self = d_alloc_name(s->s_root, "self");
> if (self) {
> struct inode *inode = new_inode(s);
> @@ -55,7 +53,6 @@ int proc_setup_self(struct super_block *s)
> }
> dput(self);
> }
> - inode_unlock(root_inode);
>
> if (ret)
> pr_err("proc_fill_super: can't allocate /proc/self\n");
> diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
> index d6113dbe58e0..61ac62c3fd9f 100644
> --- a/fs/proc/thread_self.c
> +++ b/fs/proc/thread_self.c
> @@ -35,11 +35,9 @@ unsigned thread_self_inum __ro_after_init;
>
> int proc_setup_thread_self(struct super_block *s)
> {
> - struct inode *root_inode = d_inode(s->s_root);
> struct dentry *thread_self;
> int ret = -ENOMEM;
>
> - inode_lock(root_inode);
> thread_self = d_alloc_name(s->s_root, "thread-self");
> if (thread_self) {
> struct inode *inode = new_inode(s);
> @@ -55,7 +53,6 @@ int proc_setup_thread_self(struct super_block *s)
> }
> dput(thread_self);
> }
> - inode_unlock(root_inode);
>
> if (ret)
> pr_err("proc_fill_super: can't allocate /proc/thread-self\n");
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: David Hildenbrand (Arm) @ 2026-02-05 12:30 UTC (permalink / raw)
To: Lorenzo Stoakes, Alice Ryhl
Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux
In-Reply-To: <4c399644-97d3-40a3-a596-e4c93b713bdd@lucifer.local>
On 2/5/26 13:24, Lorenzo Stoakes wrote:
> On Thu, Feb 05, 2026 at 12:19:22PM +0000, Alice Ryhl wrote:
>> On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote:
>>>
>>> Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs
>>> that are not VM_PFNMAP?
>>
>> The VMA is VM_MIXEDMAP, not VM_PFNMAP.
>
> OK this smells like David's cleanup could extend it to allow for
> VM_MIXEDMAP :) then we solve the export problem.
My thinking ... and while at it, gonna remove these functions to make
them a bit more ... consistent in naming.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:28 UTC (permalink / raw)
To: Miguel Ojeda
Cc: David Hildenbrand (arm), Alice Ryhl, Greg Kroah-Hartman,
Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara,
Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton,
Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel,
linux-kernel, linux-security-module, linux-mm, rust-for-linux,
Christoph Hellwig
In-Reply-To: <CANiq72=ybFtqsh18zkC3e1iyR-RoffcL_ZDr-fU7SjzJiFERHw@mail.gmail.com>
On Thu, Feb 05, 2026 at 01:24:09PM +0100, Miguel Ojeda wrote:
> On Thu, Feb 5, 2026 at 12:58 PM Lorenzo Stoakes
> <lorenzo.stoakes@oracle.com> wrote:
> >
> > What??
> >
> > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked
> > EXPORT_SYMBOL*() for use by other rust modules?
> >
> > It's important we keep this in sync, otherwise rust is overriding kernel policy.
>
> Currently, Rust GPL-exports every mangled symbol from the `kernel`
> crate. To call something you would need to be a Rust caller (not C --
> that is not supported at all, even if technically you could hack
> something up) and the Rust API would then need to give you access to
> it (i.e. you need to be able to pass the Rust language rules, e.g.
> being public etc.).
>
> In this case if we are talking about the `VmaRef` type, someone that
> can get a reference to a value of that type could then call the
> `zap_page_range_single` method. That in turns would try to call the C
> one, but that one is not exported, right? So it should be fine.
>
OK cool. Thanks for the explanation.
> In the future, for Rust, we may specify whether a particular crate
> exports or not (and perhaps even allow to export non-GPL, but
> originally it was decided to only export GPL stuff to be on the safe
> side; and perhaps in certain namespaces etc.).
We'd definitely need to keep this in sync with C exports, maybe we can find
a nice way of doing/checking this.
Generally we're _very_ conservative about exports, and actually it'd be
nice if maybe rust only provided GPL ones. The GPL is a good thing :) But I
guess we can figure that out later.
>
> Cheers,
> Miguel
Cheers, Lorenzo
^ permalink raw reply
* Re: [PATCH 10/13] ovl: change ovl_create_real() to get a new lock when re-opening created file.
From: Amir Goldstein @ 2026-02-05 12:26 UTC (permalink / raw)
To: NeilBrown
Cc: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
Chuck Lever, Jeff Layton, Miklos Szeredi, John Johansen,
Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-11-neilb@ownmail.net>
On Wed, Feb 4, 2026 at 6:09 AM NeilBrown <neilb@ownmail.net> wrote:
>
> From: NeilBrown <neil@brown.name>
>
> When ovl_create_real() is used to create a file on the upper filesystem
> it needs to return the resulting dentry - positive and hashed.
> It is usually the case the that dentry passed to the create function
> (e.g. vfs_create()) will be suitable but this is not guaranteed. The
> filesystem may unhash that dentry forcing a repeat lookup next time the
> name is wanted.
>
> So ovl_create_real() must be (and is) aware of this and prepared to
> perform that lookup to get a hash positive dentry.
>
> This is currently done under that same directory lock that provided
> exclusion for the create. Proposed changes to locking will make this
> not possible - as the name, rather than the directory, will be locked.
> The new APIs provided for lookup and locking do not and cannot support
> this pattern.
>
> The lock isn't needed. ovl_create_real() can drop the lock and then get
> a new lock for the lookup - then check that the lookup returned the
> correct inode. In a well-behaved configuration where the upper
> filesystem is not being modified by a third party, this will always work
> reliably, and if there are separate modification it will fail cleanly.
>
> So change ovl_create_real() to drop the lock and call
> ovl_start_creating_upper() to find the correct dentry. Note that
> start_creating doesn't fail if the name already exists.
>
> This removes the only remaining use of ovl_lookup_upper, so it is
> removed.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> fs/overlayfs/dir.c | 24 ++++++++++++++++++------
> fs/overlayfs/overlayfs.h | 7 -------
> 2 files changed, 18 insertions(+), 13 deletions(-)
>
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index ff3dbd1ca61f..ec08904d084d 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -219,21 +219,33 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent,
> err = -EIO;
> } else if (d_unhashed(newdentry)) {
> struct dentry *d;
> + struct name_snapshot name;
> /*
> * Some filesystems (i.e. casefolded) may return an unhashed
> - * negative dentry from the ovl_lookup_upper() call before
> + * negative dentry from the ovl_start_creating_upper() call before
> * ovl_create_real().
According to the new locking rules, if the hashed dentry itself is
the synchronization object, is it going to be allowed to
filesystem to unhash the dentry while the dentry still in the
"creating" scope? It is hard for me to wrap my head around this.
Or do we need this here because some filesystems (casefold in
particular) are not going to support parallel creations?
> * In that case, lookup again after making the newdentry
> * positive, so ovl_create_upper() always returns a hashed
> * positive dentry.
> + * As we have to drop the lock before the lookup a race
> + * could result in a lookup failure. In that case we return
> + * an error.
> */
> - d = ovl_lookup_upper(ofs, newdentry->d_name.name, parent,
> - newdentry->d_name.len);
> - dput(newdentry);
> - if (IS_ERR_OR_NULL(d))
> + take_dentry_name_snapshot(&name, newdentry);
> + end_creating_keep(newdentry);
> + d = ovl_start_creating_upper(ofs, parent, &name.name);
> + release_dentry_name_snapshot(&name);
OK. not saying no to this (yet) but I have to admit that it is pretty
ugly that the callers of ovl_create_real() want to create a specific
stable name, which is could be passed in as const char *name
and yet we end up doing this weird dance here just to keep the name
from newdentry.
Thanks,
Amir.
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:24 UTC (permalink / raw)
To: Alice Ryhl
Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <aYSKyr7StGpGKNqW@google.com>
On Thu, Feb 05, 2026 at 12:19:22PM +0000, Alice Ryhl wrote:
> On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote:
> > On 2/5/26 13:10, Lorenzo Stoakes wrote:
> > > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote:
> > > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> > > > >
> > > > > I don't expect anybody to set zap_details, but yeah, it could be abused.
> > > > > It could be abused right now from anywhere else in the kernel
> > > > > where we don't build as a module :)
> > > > >
> > > > > Apparently we export a similar function in rust where we just removed the last parameter.
> > > >
> > > > To clarify, said Rust function gets inlined into Rust Binder, so Rust
> > > > Binder calls the zap_page_range_single() symbol directly.
> > >
> > > Presumably only for things compiled into the kernel right?
> >
> > Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs
> > that are not VM_PFNMAP?
>
> The VMA is VM_MIXEDMAP, not VM_PFNMAP.
OK this smells like David's cleanup could extend it to allow for
VM_MIXEDMAP :) then we solve the export problem.
The two of these cause endless issues, it's really a mess...
>
> Alice
Cheers, Lorenzo
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Miguel Ojeda @ 2026-02-05 12:24 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: David Hildenbrand (arm), Alice Ryhl, Greg Kroah-Hartman,
Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara,
Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton,
Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel,
linux-kernel, linux-security-module, linux-mm, rust-for-linux,
Christoph Hellwig
In-Reply-To: <ab63390c-9e75-4a45-9bf4-4ceb112ef07f@lucifer.local>
On Thu, Feb 5, 2026 at 12:58 PM Lorenzo Stoakes
<lorenzo.stoakes@oracle.com> wrote:
>
> What??
>
> Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked
> EXPORT_SYMBOL*() for use by other rust modules?
>
> It's important we keep this in sync, otherwise rust is overriding kernel policy.
Currently, Rust GPL-exports every mangled symbol from the `kernel`
crate. To call something you would need to be a Rust caller (not C --
that is not supported at all, even if technically you could hack
something up) and the Rust API would then need to give you access to
it (i.e. you need to be able to pass the Rust language rules, e.g.
being public etc.).
In this case if we are talking about the `VmaRef` type, someone that
can get a reference to a value of that type could then call the
`zap_page_range_single` method. That in turns would try to call the C
one, but that one is not exported, right? So it should be fine.
In the future, for Rust, we may specify whether a particular crate
exports or not (and perhaps even allow to export non-GPL, but
originally it was decided to only export GPL stuff to be on the safe
side; and perhaps in certain namespaces etc.).
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH 03/13] libfs: change simple_done_creating() to use end_creating()
From: Jeff Layton @ 2026-02-05 12:19 UTC (permalink / raw)
To: NeilBrown, Christian Brauner, Alexander Viro, David Howells,
Jan Kara, Chuck Lever, Miklos Szeredi, Amir Goldstein,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley
Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-4-neilb@ownmail.net>
On Wed, 2026-02-04 at 15:57 +1100, NeilBrown wrote:
> From: NeilBrown <neil@brown.name>
>
> simple_done_creating() and end_creating() are identical.
> So change the former to use the latter. This further centralises
> unlocking of directories.
>
> Signed-off-by: NeilBrown <neil@brown.name>
> ---
> fs/libfs.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/fs/libfs.c b/fs/libfs.c
> index f1860dff86f2..db18b53fc189 100644
> --- a/fs/libfs.c
> +++ b/fs/libfs.c
> @@ -2318,7 +2318,6 @@ EXPORT_SYMBOL(simple_start_creating);
> /* parent must have been held exclusive since simple_start_creating() */
> void simple_done_creating(struct dentry *child)
> {
> - inode_unlock(child->d_parent->d_inode);
> - dput(child);
> + end_creating(child);
> }
> EXPORT_SYMBOL(simple_done_creating);
nit: seems like it would be better to turn this into a static inline
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Alice Ryhl @ 2026-02-05 12:19 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Lorenzo Stoakes, Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <8856c839-1a94-4e4d-9ded-d3b1627cd2cc@kernel.org>
On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote:
> On 2/5/26 13:10, Lorenzo Stoakes wrote:
> > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote:
> > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> > > >
> > > > I don't expect anybody to set zap_details, but yeah, it could be abused.
> > > > It could be abused right now from anywhere else in the kernel
> > > > where we don't build as a module :)
> > > >
> > > > Apparently we export a similar function in rust where we just removed the last parameter.
> > >
> > > To clarify, said Rust function gets inlined into Rust Binder, so Rust
> > > Binder calls the zap_page_range_single() symbol directly.
> >
> > Presumably only for things compiled into the kernel right?
>
> Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs
> that are not VM_PFNMAP?
The VMA is VM_MIXEDMAP, not VM_PFNMAP.
Alice
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:18 UTC (permalink / raw)
To: Alice Ryhl
Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <aYSH5KG36fVQFePL@google.com>
On Thu, Feb 05, 2026 at 12:07:00PM +0000, Alice Ryhl wrote:
> On Thu, Feb 05, 2026 at 11:29:04AM +0000, Lorenzo Stoakes wrote:
> > We either need a wrapper that eliminates this parameter (but then we're adding a
> > wrapper to this behaviour that is literally for one driver that is _temporarily_
> > being modularised which is weak justifiction), or use of a function that invokes
> > it that is currently exported.
>
> I have not talked with distros about it, but quite a few of them enable
> Binder because one or two applications want to use Binder to emulate
> Android. I imagine that even if Android itself goes back to built-in,
> distros would want it as a module so that you don't have to load it for
> every user, rather than for the few users that want to use waydroid or
> similar.
>
> A few examples:
> https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/5711a17344ec7cfd90443374a30d5cd3e9a9439e/config#L10993
> https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/arm64/config?ref_type=heads#L106
> https://gitlab.com/cki-project/kernel-ark/-/blob/os-build/redhat/configs/fedora/generic/x86/CONFIG_ANDROID_BINDER_IPC?ref_type=heads
I mean you should update the cover letter to make this clear and drop the whole
reference to things being temporary, this is a lot more strident than the cover
letter is.
In any case, that has nothing to do with whether or not we export internal
implementation details to a module.
Something being in-tree compiled gets to use actually far too many internal
interfaces that really should not have been exposed, we've been far too leniant
about that, and that's something I want to address (mm has mm/*.h internal-only
headers, not sure how we'll deal with that with rust though).
Sadly even with in-tree, every interface you make available leads to driver
abuse. So something compiled in-tree using X, Y or Z interface doesn't mean that
it's correct or even wise, and modularising forces you to rethink that.
folio_mkclean() is a great example, we were about to be able to make that
mm-internal then 2 more filesystems started using it oops :)
>
> Alice
Cheers, Lorenzo
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Alice Ryhl @ 2026-02-05 12:16 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <e7247f3e-8a88-4b46-91ba-cb73cce1346a@lucifer.local>
On Thu, Feb 05, 2026 at 12:10:38PM +0000, Lorenzo Stoakes wrote:
> On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote:
> > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> > > On 2/5/26 12:29, Lorenzo Stoakes wrote:
> > > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote:
> > > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item)
> > > > > {
> > > > > diff --git a/mm/memory.c b/mm/memory.c
> > > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644
> > > > > --- a/mm/memory.c
> > > > > +++ b/mm/memory.c
> > > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> > > > > zap_page_range_single_batched(&tlb, vma, address, size, details);
> > > > > tlb_finish_mmu(&tlb);
> > > > > }
> > > > > +EXPORT_SYMBOL(zap_page_range_single);
> > > >
> > > > Sorry but I don't want this exported at all.
> > > >
> > > > This is an internal implementation detail which allows fine-grained control of
> > > > behaviour via struct zap_details (which binder doesn't use, of course :)
> > >
> > > I don't expect anybody to set zap_details, but yeah, it could be abused.
> > > It could be abused right now from anywhere else in the kernel
> > > where we don't build as a module :)
> > >
> > > Apparently we export a similar function in rust where we just removed the last parameter.
> >
> > To clarify, said Rust function gets inlined into Rust Binder, so Rust
> > Binder calls the zap_page_range_single() symbol directly.
>
> Presumably only for things compiled into the kernel right?
No, building Rust Binder with =m triggers this error for me:
ERROR: modpost: "zap_page_range_single" [drivers/android/binder/rust_binder.ko] undefined!
Alice
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: David Hildenbrand (arm) @ 2026-02-05 12:13 UTC (permalink / raw)
To: Lorenzo Stoakes, Alice Ryhl
Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux
In-Reply-To: <e7247f3e-8a88-4b46-91ba-cb73cce1346a@lucifer.local>
On 2/5/26 13:10, Lorenzo Stoakes wrote:
> On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote:
>> On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
>>>
>>> I don't expect anybody to set zap_details, but yeah, it could be abused.
>>> It could be abused right now from anywhere else in the kernel
>>> where we don't build as a module :)
>>>
>>> Apparently we export a similar function in rust where we just removed the last parameter.
>>
>> To clarify, said Rust function gets inlined into Rust Binder, so Rust
>> Binder calls the zap_page_range_single() symbol directly.
>
> Presumably only for things compiled into the kernel right?
Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs
that are not VM_PFNMAP?
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:12 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux, Christoph Hellwig
In-Reply-To: <507d24e0-4563-4b33-864c-cd1a499fe517@kernel.org>
On Thu, Feb 05, 2026 at 01:03:35PM +0100, David Hildenbrand (arm) wrote:
> On 2/5/26 12:57, Lorenzo Stoakes wrote:
> > +cc Christoph for his input on exports here.
> >
> > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> > > On 2/5/26 12:29, Lorenzo Stoakes wrote:
> > > >
> > > > Same point as before about exporting symbols, but given the _obj variants are
> > > > exported already this one is more valid.
> > > >
> > > >
> > > > Sorry but I don't want this exported at all.
> > > >
> > > > This is an internal implementation detail which allows fine-grained control of
> > > > behaviour via struct zap_details (which binder doesn't use, of course :)
> > >
> > > I don't expect anybody to set zap_details, but yeah, it could be abused.
> > > It could be abused right now from anywhere else in the kernel
> > > where we don't build as a module :)
> > >
> > > Apparently we export a similar function in rust where we just removed the last parameter.
> >
> > What??
> >
> > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked
> > EXPORT_SYMBOL*() for use by other rust modules?
> >
> > It's important we keep this in sync, otherwise rust is overriding kernel policy.
> >
> > >
> > > I think zap_page_range_single() is only called with non-NULL from mm/memory.c.
> > >
> > > So the following makes likely sense even outside of the context of this series:
> > >
> >
> > Yeah this looks good so feel free to add a R-b from me tag when you send it
> > BUT...
> >
> > I'm still _very_ uncomfortable with exporting this just for binder which seems
> > to be doing effectively mm tasks itself in a way that makes me think it needs a
> > rework to not be doing that and to update core mm to add functionality if it's
> > needed.
> >
> > In any case, if we _do_ export this I think I'm going to insist on this being
> > EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module.
>
> Works for me.
:)
>
> Staring at it again, I think I landed in cleanup land.
>
> zap_vma_ptes() is exported and does the same thing as
> zap_page_range_single(), just with some additional safety checks.
Yeah saw that, except it insists only on VM_PFN VMAs which makes me question our
making this more generally available to OOT drivers.
>
> Fun.
>
>
> Let me cleanup. Good finger exercise after one month of almost-not coding :)
:) I am less interested in cleanups at this stage at least for a while so feel
free to fixup glaringly horrible things so I can vicariously enjoy it at
least...
>
> --
> Cheers,
>
> David
Cheers, Lorenzo
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:10 UTC (permalink / raw)
To: Alice Ryhl
Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <aYSFyH-1kkW92M2N@google.com>
On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote:
> On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> > On 2/5/26 12:29, Lorenzo Stoakes wrote:
> > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote:
> > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item)
> > > > {
> > > > diff --git a/mm/memory.c b/mm/memory.c
> > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644
> > > > --- a/mm/memory.c
> > > > +++ b/mm/memory.c
> > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> > > > zap_page_range_single_batched(&tlb, vma, address, size, details);
> > > > tlb_finish_mmu(&tlb);
> > > > }
> > > > +EXPORT_SYMBOL(zap_page_range_single);
> > >
> > > Sorry but I don't want this exported at all.
> > >
> > > This is an internal implementation detail which allows fine-grained control of
> > > behaviour via struct zap_details (which binder doesn't use, of course :)
> >
> > I don't expect anybody to set zap_details, but yeah, it could be abused.
> > It could be abused right now from anywhere else in the kernel
> > where we don't build as a module :)
> >
> > Apparently we export a similar function in rust where we just removed the last parameter.
>
> To clarify, said Rust function gets inlined into Rust Binder, so Rust
> Binder calls the zap_page_range_single() symbol directly.
Presumably only for things compiled into the kernel right?
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:07 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux
In-Reply-To: <d309b3f6-8959-4767-b262-7fdb957669aa@kernel.org>
On Thu, Feb 05, 2026 at 01:06:10PM +0100, David Hildenbrand (arm) wrote:
> On 2/5/26 13:01, Lorenzo Stoakes wrote:
> > On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote:
> >
> > Dude you have to capitalise that 'a' in Arm it's driving me crazy ;)
> >
> > Then again should it be ARM? OK this is tricky
>
> Yeah, I should likely adjust that at some point. For the time being, I enjoy
> driving you crazy :P
:D
>
> >
> > [snip]
> >
> > >
> > > The following should compile :)
> >
> > Err... yeah. OK my R-b obviously depends on the code being compiling + working
> > :P But still feel free to add when you break it out + _test_ it ;)
>
> Better to add your R-b when I send it out officially :)
Haha yeah maybe...
>
> --
> Cheers,
>
> David
^ permalink raw reply
* Re: [PATCH 1/5] export file_close_fd and task_work_add
From: Alice Ryhl @ 2026-02-05 12:07 UTC (permalink / raw)
To: Jan Kara
Cc: Christian Brauner, Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Paul Moore, James Morris, Serge E. Hallyn,
Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin,
Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux, Christoph Hellwig
In-Reply-To: <luj2ggjo47mvjzhzavoy72ro6kaoj46cicudjrc6646vs3s7q5@wzc7aabgdlkl>
On Thu, Feb 05, 2026 at 12:52:37PM +0100, Jan Kara wrote:
>
> Agreed. And just to demonstrate the point binder's use would become the
> first of such bugs because it is prone to the module being removed while
> the task work is in flight and thus do_close_fd() code can be freed by the
> time it gets executed.
Good point ...
> Generally, making some code modular usually requires more effort than just
> flipping the Kconfig to tristate. You usually need to make sure all objects
> and queued work is flushed before the module can be removed. Not sure how
> much of this is taken care of by Rust though...
>
> Honza
> --
> Jan Kara <jack@suse.com>
> SUSE Labs, CR
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Alice Ryhl @ 2026-02-05 12:07 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <02801464-f4cb-4e38-8269-f8b9cf0a5965@lucifer.local>
On Thu, Feb 05, 2026 at 11:29:04AM +0000, Lorenzo Stoakes wrote:
> We either need a wrapper that eliminates this parameter (but then we're adding a
> wrapper to this behaviour that is literally for one driver that is _temporarily_
> being modularised which is weak justifiction), or use of a function that invokes
> it that is currently exported.
I have not talked with distros about it, but quite a few of them enable
Binder because one or two applications want to use Binder to emulate
Android. I imagine that even if Android itself goes back to built-in,
distros would want it as a module so that you don't have to load it for
every user, rather than for the few users that want to use waydroid or
similar.
A few examples:
https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/5711a17344ec7cfd90443374a30d5cd3e9a9439e/config#L10993
https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/arm64/config?ref_type=heads#L106
https://gitlab.com/cki-project/kernel-ark/-/blob/os-build/redhat/configs/fedora/generic/x86/CONFIG_ANDROID_BINDER_IPC?ref_type=heads
Alice
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: David Hildenbrand (arm) @ 2026-02-05 12:06 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux
In-Reply-To: <4a36c1e7-e51a-4c06-8f7c-728b278af972@lucifer.local>
On 2/5/26 13:01, Lorenzo Stoakes wrote:
> On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote:
>
> Dude you have to capitalise that 'a' in Arm it's driving me crazy ;)
>
> Then again should it be ARM? OK this is tricky
Yeah, I should likely adjust that at some point. For the time being, I
enjoy driving you crazy :P
>
> [snip]
>
>>
>> The following should compile :)
>
> Err... yeah. OK my R-b obviously depends on the code being compiling + working
> :P But still feel free to add when you break it out + _test_ it ;)
Better to add your R-b when I send it out officially :)
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: David Hildenbrand (arm) @ 2026-02-05 12:03 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux, Christoph Hellwig
In-Reply-To: <ab63390c-9e75-4a45-9bf4-4ceb112ef07f@lucifer.local>
On 2/5/26 12:57, Lorenzo Stoakes wrote:
> +cc Christoph for his input on exports here.
>
> On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
>> On 2/5/26 12:29, Lorenzo Stoakes wrote:
>>>
>>> Same point as before about exporting symbols, but given the _obj variants are
>>> exported already this one is more valid.
>>>
>>>
>>> Sorry but I don't want this exported at all.
>>>
>>> This is an internal implementation detail which allows fine-grained control of
>>> behaviour via struct zap_details (which binder doesn't use, of course :)
>>
>> I don't expect anybody to set zap_details, but yeah, it could be abused.
>> It could be abused right now from anywhere else in the kernel
>> where we don't build as a module :)
>>
>> Apparently we export a similar function in rust where we just removed the last parameter.
>
> What??
>
> Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked
> EXPORT_SYMBOL*() for use by other rust modules?
>
> It's important we keep this in sync, otherwise rust is overriding kernel policy.
>
>>
>> I think zap_page_range_single() is only called with non-NULL from mm/memory.c.
>>
>> So the following makes likely sense even outside of the context of this series:
>>
>
> Yeah this looks good so feel free to add a R-b from me tag when you send it
> BUT...
>
> I'm still _very_ uncomfortable with exporting this just for binder which seems
> to be doing effectively mm tasks itself in a way that makes me think it needs a
> rework to not be doing that and to update core mm to add functionality if it's
> needed.
>
> In any case, if we _do_ export this I think I'm going to insist on this being
> EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module.
Works for me.
Staring at it again, I think I landed in cleanup land.
zap_vma_ptes() is exported and does the same thing as
zap_page_range_single(), just with some additional safety checks.
Fun.
Let me cleanup. Good finger exercise after one month of almost-not coding :)
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 12:01 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux
In-Reply-To: <d122f9be-48d6-40b1-9da8-cec445bd8daf@kernel.org>
On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote:
Dude you have to capitalise that 'a' in Arm it's driving me crazy ;)
Then again should it be ARM? OK this is tricky
[snip]
>
> The following should compile :)
Err... yeah. OK my R-b obviously depends on the code being compiling + working
:P But still feel free to add when you break it out + _test_ it ;)
Cheers, Lorenzo
>
> From b1c35afb1b819a42f4ec1119564b3b37cceb9968 Mon Sep 17 00:00:00 2001
> From: "David Hildenbrand (arm)" <david@kernel.org>
> Date: Thu, 5 Feb 2026 12:42:09 +0100
> Subject: [PATCH] mm/memory: remove "zap_details" parameter from
> zap_page_range_single()
>
> Nobody except memory.c should really set that parameter to non-NULL. So
> let's just drop it and make unmap_mapping_range_vma() use
> zap_page_range_single_batched() instead.
>
> Signed-off-by: David Hildenbrand (arm) <david@kernel.org>
> ---
> arch/s390/mm/gmap_helpers.c | 2 +-
> drivers/android/binder_alloc.c | 2 +-
> include/linux/mm.h | 5 ++---
> kernel/bpf/arena.c | 3 +--
> kernel/events/core.c | 2 +-
> mm/madvise.c | 3 +--
> mm/memory.c | 16 ++++++++++------
> net/ipv4/tcp.c | 5 ++---
> rust/kernel/mm/virt.rs | 2 +-
> 9 files changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c
> index d41b19925a5a..859f5570c3dc 100644
> --- a/arch/s390/mm/gmap_helpers.c
> +++ b/arch/s390/mm/gmap_helpers.c
> @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo
> if (!vma)
> return;
> if (!is_vm_hugetlb_page(vma))
> - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL);
> + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr);
> vmaddr = vma->vm_end;
> }
> }
> diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> index 979c96b74cad..b0201bc6893a 100644
> --- a/drivers/android/binder_alloc.c
> +++ b/drivers/android/binder_alloc.c
> @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
> if (vma) {
> trace_binder_unmap_user_start(alloc, index);
> - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL);
> + zap_page_range_single(vma, page_addr, PAGE_SIZE);
> trace_binder_unmap_user_end(alloc, index);
> }
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f0d5be9dc736..5764991546bb 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2621,11 +2621,10 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr,
> void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
> unsigned long size);
> void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> - unsigned long size, struct zap_details *details);
> + unsigned long size);
> static inline void zap_vma_pages(struct vm_area_struct *vma)
> {
> - zap_page_range_single(vma, vma->vm_start,
> - vma->vm_end - vma->vm_start, NULL);
> + zap_page_range_single(vma, vma->vm_start, vma->vm_end - vma->vm_start);
> }
> void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas,
> struct vm_area_struct *start_vma, unsigned long start,
> diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
> index 872dc0e41c65..242c931d3740 100644
> --- a/kernel/bpf/arena.c
> +++ b/kernel/bpf/arena.c
> @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt)
> struct vma_list *vml;
> list_for_each_entry(vml, &arena->vma_list, head)
> - zap_page_range_single(vml->vma, uaddr,
> - PAGE_SIZE * page_cnt, NULL);
> + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt);
> }
> static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt)
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 8cca80094624..1dfb33c39c2f 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma)
> #ifdef CONFIG_MMU
> /* Clear any partial mappings on error. */
> if (err)
> - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL);
> + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE);
> #endif
> return err;
> diff --git a/mm/madvise.c b/mm/madvise.c
> index b617b1be0f53..abcbfd1f0662 100644
> --- a/mm/madvise.c
> +++ b/mm/madvise.c
> @@ -1200,8 +1200,7 @@ static long madvise_guard_install(struct madvise_behavior *madv_behavior)
> * OK some of the range have non-guard pages mapped, zap
> * them. This leaves existing guard pages in place.
> */
> - zap_page_range_single(vma, range->start,
> - range->end - range->start, NULL);
> + zap_page_range_single(vma, range->start, range->end - range->start);
> }
> /*
> diff --git a/mm/memory.c b/mm/memory.c
> index da360a6eb8a4..82985da5f7e6 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb,
> * @vma: vm_area_struct holding the applicable pages
> * @address: starting address of pages to zap
> * @size: number of bytes to zap
> - * @details: details of shared cache invalidation
> *
> * The range must fit into one VMA.
> */
> void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> - unsigned long size, struct zap_details *details)
> + unsigned long size)
> {
> struct mmu_gather tlb;
> tlb_gather_mmu(&tlb, vma->vm_mm);
> - zap_page_range_single_batched(&tlb, vma, address, size, details);
> + zap_page_range_single_batched(&tlb, vma, address, size, NULL);
> tlb_finish_mmu(&tlb);
> }
> @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
> !(vma->vm_flags & VM_PFNMAP))
> return;
> - zap_page_range_single(vma, address, size, NULL);
> + zap_page_range_single(vma, address, size);
> }
> EXPORT_SYMBOL_GPL(zap_vma_ptes);
> @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add
> * maintain page reference counts, and callers may free
> * pages due to the error. So zap it early.
> */
> - zap_page_range_single(vma, addr, size, NULL);
> + zap_page_range_single(vma, addr, size);
> return error;
> }
> @@ -4187,7 +4186,12 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma,
> unsigned long start_addr, unsigned long end_addr,
> struct zap_details *details)
> {
> - zap_page_range_single(vma, start_addr, end_addr - start_addr, details);
> + struct mmu_gather tlb;
> +
> + tlb_gather_mmu(&tlb, vma->vm_mm);
> + zap_page_range_single_batched(&tlb, vma, start_addr,
> + end_addr - start_addr, details);
> + tlb_finish_mmu(&tlb);
> }
> static inline void unmap_mapping_range_tree(struct rb_root_cached *root,
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index d5319ebe2452..9e92c71389f3 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma,
> maybe_zap_len = total_bytes_to_map - /* All bytes to map */
> *length + /* Mapped or pending */
> (pages_remaining * PAGE_SIZE); /* Failed map. */
> - zap_page_range_single(vma, *address, maybe_zap_len, NULL);
> + zap_page_range_single(vma, *address, maybe_zap_len);
> err = 0;
> }
> @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk,
> total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1);
> if (total_bytes_to_map) {
> if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT))
> - zap_page_range_single(vma, address, total_bytes_to_map,
> - NULL);
> + zap_page_range_single(vma, address, total_bytes_to_map);
> zc->length = total_bytes_to_map;
> zc->recv_skip_hint = 0;
> } else {
> diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
> index da21d65ccd20..b8e59e4420f3 100644
> --- a/rust/kernel/mm/virt.rs
> +++ b/rust/kernel/mm/virt.rs
> @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) {
> // sufficient for this method call. This method has no requirements on the vma flags. The
> // address range is checked to be within the vma.
> unsafe {
> - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut())
> + bindings::zap_page_range_single(self.as_ptr(), address, size)
> };
> }
> --
> 2.43.0
>
>
> --
> Cheers,
>
> David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Lorenzo Stoakes @ 2026-02-05 11:57 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, James Morris,
Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng,
Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team,
linux-fsdevel, linux-kernel, linux-security-module, linux-mm,
rust-for-linux, Christoph Hellwig
In-Reply-To: <21d90844-1cb1-46ab-a2bb-62f2478b7dfb@kernel.org>
+cc Christoph for his input on exports here.
On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> On 2/5/26 12:29, Lorenzo Stoakes wrote:
> > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote:
> > > These are the functions needed by Binder's shrinker.
> > >
> > > Binder uses zap_page_range_single in the shrinker path to remove an
> > > unused page from the mmap'd region. Note that pages are only removed
> > > from the mmap'd region lazily when shrinker asks for it.
> > >
> > > Binder uses list_lru_add/del to keep track of the shrinker lru list, and
> > > it can't use _obj because the list head is not stored inline in the page
> > > actually being lru freed, so page_to_nid(virt_to_page(item)) on the list
> > > head computes the nid of the wrong page.
> > >
> > > Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> > > ---
> > > mm/list_lru.c | 2 ++
> > > mm/memory.c | 1 +
> > > 2 files changed, 3 insertions(+)
> > >
> > > diff --git a/mm/list_lru.c b/mm/list_lru.c
> > > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644
> > > --- a/mm/list_lru.c
> > > +++ b/mm/list_lru.c
> > > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid,
> > > unlock_list_lru(l, false);
> > > return false;
> > > }
> > > +EXPORT_SYMBOL_GPL(list_lru_add);
> > >
> > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item)
> > > {
> > > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid,
> > > unlock_list_lru(l, false);
> > > return false;
> > > }
> > > +EXPORT_SYMBOL_GPL(list_lru_del);
> >
> > Same point as before about exporting symbols, but given the _obj variants are
> > exported already this one is more valid.
> >
> > >
> > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item)
> > > {
> > > diff --git a/mm/memory.c b/mm/memory.c
> > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644
> > > --- a/mm/memory.c
> > > +++ b/mm/memory.c
> > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> > > zap_page_range_single_batched(&tlb, vma, address, size, details);
> > > tlb_finish_mmu(&tlb);
> > > }
> > > +EXPORT_SYMBOL(zap_page_range_single);
> >
> > Sorry but I don't want this exported at all.
> >
> > This is an internal implementation detail which allows fine-grained control of
> > behaviour via struct zap_details (which binder doesn't use, of course :)
>
> I don't expect anybody to set zap_details, but yeah, it could be abused.
> It could be abused right now from anywhere else in the kernel
> where we don't build as a module :)
>
> Apparently we export a similar function in rust where we just removed the last parameter.
What??
Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked
EXPORT_SYMBOL*() for use by other rust modules?
It's important we keep this in sync, otherwise rust is overriding kernel policy.
>
> I think zap_page_range_single() is only called with non-NULL from mm/memory.c.
>
> So the following makes likely sense even outside of the context of this series:
>
Yeah this looks good so feel free to add a R-b from me tag when you send it
BUT...
I'm still _very_ uncomfortable with exporting this just for binder which seems
to be doing effectively mm tasks itself in a way that makes me think it needs a
rework to not be doing that and to update core mm to add functionality if it's
needed.
In any case, if we _do_ export this I think I'm going to insist on this being
EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module.
Thanks, Lorenzo
> From d2a2d20994456b9a66008b7fef12e379e76fc9f8 Mon Sep 17 00:00:00 2001
> From: "David Hildenbrand (arm)" <david@kernel.org>
> Date: Thu, 5 Feb 2026 12:42:09 +0100
> Subject: [PATCH] tmp
>
> Signed-off-by: David Hildenbrand (arm) <david@kernel.org>
> ---
> arch/s390/mm/gmap_helpers.c | 2 +-
> drivers/android/binder_alloc.c | 2 +-
> include/linux/mm.h | 4 ++--
> kernel/bpf/arena.c | 3 +--
> kernel/events/core.c | 2 +-
> mm/memory.c | 15 +++++++++------
> net/ipv4/tcp.c | 5 ++---
> rust/kernel/mm/virt.rs | 2 +-
> 8 files changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c
> index d41b19925a5a..859f5570c3dc 100644
> --- a/arch/s390/mm/gmap_helpers.c
> +++ b/arch/s390/mm/gmap_helpers.c
> @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo
> if (!vma)
> return;
> if (!is_vm_hugetlb_page(vma))
> - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL);
> + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr);
> vmaddr = vma->vm_end;
> }
> }
> diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> index 979c96b74cad..b0201bc6893a 100644
> --- a/drivers/android/binder_alloc.c
> +++ b/drivers/android/binder_alloc.c
> @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
> if (vma) {
> trace_binder_unmap_user_start(alloc, index);
> - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL);
> + zap_page_range_single(vma, page_addr, PAGE_SIZE);
> trace_binder_unmap_user_end(alloc, index);
> }
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f0d5be9dc736..b7cc6ef49917 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2621,11 +2621,11 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr,
> void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
> unsigned long size);
> void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> - unsigned long size, struct zap_details *details);
> + unsigned long size);
> static inline void zap_vma_pages(struct vm_area_struct *vma)
> {
> zap_page_range_single(vma, vma->vm_start,
> - vma->vm_end - vma->vm_start, NULL);
> + vma->vm_end - vma->vm_start);
> }
> void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas,
> struct vm_area_struct *start_vma, unsigned long start,
> diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
> index 872dc0e41c65..242c931d3740 100644
> --- a/kernel/bpf/arena.c
> +++ b/kernel/bpf/arena.c
> @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt)
> struct vma_list *vml;
> list_for_each_entry(vml, &arena->vma_list, head)
> - zap_page_range_single(vml->vma, uaddr,
> - PAGE_SIZE * page_cnt, NULL);
> + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt);
> }
> static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt)
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 8cca80094624..1dfb33c39c2f 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma)
> #ifdef CONFIG_MMU
> /* Clear any partial mappings on error. */
> if (err)
> - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL);
> + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE);
> #endif
> return err;
> diff --git a/mm/memory.c b/mm/memory.c
> index da360a6eb8a4..4f8dcdcd20f3 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb,
> * @vma: vm_area_struct holding the applicable pages
> * @address: starting address of pages to zap
> * @size: number of bytes to zap
> - * @details: details of shared cache invalidation
> *
> * The range must fit into one VMA.
> */
> void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> - unsigned long size, struct zap_details *details)
> + unsigned long size)
> {
> struct mmu_gather tlb;
> tlb_gather_mmu(&tlb, vma->vm_mm);
> - zap_page_range_single_batched(&tlb, vma, address, size, details);
> + zap_page_range_single_batched(&tlb, vma, address, size, NULL);
> tlb_finish_mmu(&tlb);
> }
> @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address,
> !(vma->vm_flags & VM_PFNMAP))
> return;
> - zap_page_range_single(vma, address, size, NULL);
> + zap_page_range_single(vma, address, size);
> }
> EXPORT_SYMBOL_GPL(zap_vma_ptes);
> @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add
> * maintain page reference counts, and callers may free
> * pages due to the error. So zap it early.
> */
> - zap_page_range_single(vma, addr, size, NULL);
> + zap_page_range_single(vma, addr, size);
> return error;
> }
> @@ -4187,7 +4186,11 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma,
> unsigned long start_addr, unsigned long end_addr,
> struct zap_details *details)
> {
> - zap_page_range_single(vma, start_addr, end_addr - start_addr, details);
> + struct mmu_gather tlb;
> +
> + tlb_gather_mmu(&tlb, vma->vm_mm);
> + zap_page_range_single_batched(&tlb, vma, address, size, details);
> + tlb_finish_mmu(&tlb);
> }
> static inline void unmap_mapping_range_tree(struct rb_root_cached *root,
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index d5319ebe2452..9e92c71389f3 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma,
> maybe_zap_len = total_bytes_to_map - /* All bytes to map */
> *length + /* Mapped or pending */
> (pages_remaining * PAGE_SIZE); /* Failed map. */
> - zap_page_range_single(vma, *address, maybe_zap_len, NULL);
> + zap_page_range_single(vma, *address, maybe_zap_len);
> err = 0;
> }
> @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk,
> total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1);
> if (total_bytes_to_map) {
> if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT))
> - zap_page_range_single(vma, address, total_bytes_to_map,
> - NULL);
> + zap_page_range_single(vma, address, total_bytes_to_map);
> zc->length = total_bytes_to_map;
> zc->recv_skip_hint = 0;
> } else {
> diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
> index da21d65ccd20..b8e59e4420f3 100644
> --- a/rust/kernel/mm/virt.rs
> +++ b/rust/kernel/mm/virt.rs
> @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) {
> // sufficient for this method call. This method has no requirements on the vma flags. The
> // address range is checked to be within the vma.
> unsafe {
> - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut())
> + bindings::zap_page_range_single(self.as_ptr(), address, size)
> };
> }
> --
> 2.43.0
>
>
> --
> Cheers,
>
> David
^ permalink raw reply
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del
From: Alice Ryhl @ 2026-02-05 11:58 UTC (permalink / raw)
To: David Hildenbrand (arm)
Cc: Lorenzo Stoakes, Greg Kroah-Hartman, Carlos Llamas,
Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module,
linux-mm, rust-for-linux
In-Reply-To: <21d90844-1cb1-46ab-a2bb-62f2478b7dfb@kernel.org>
On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote:
> On 2/5/26 12:29, Lorenzo Stoakes wrote:
> > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote:
> > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item)
> > > {
> > > diff --git a/mm/memory.c b/mm/memory.c
> > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644
> > > --- a/mm/memory.c
> > > +++ b/mm/memory.c
> > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
> > > zap_page_range_single_batched(&tlb, vma, address, size, details);
> > > tlb_finish_mmu(&tlb);
> > > }
> > > +EXPORT_SYMBOL(zap_page_range_single);
> >
> > Sorry but I don't want this exported at all.
> >
> > This is an internal implementation detail which allows fine-grained control of
> > behaviour via struct zap_details (which binder doesn't use, of course :)
>
> I don't expect anybody to set zap_details, but yeah, it could be abused.
> It could be abused right now from anywhere else in the kernel
> where we don't build as a module :)
>
> Apparently we export a similar function in rust where we just removed the last parameter.
To clarify, said Rust function gets inlined into Rust Binder, so Rust
Binder calls the zap_page_range_single() symbol directly.
Alice
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox