* Re: [PATCH v12 05/15] arm64: rqspinlock: Remove private copy of smp_cond_load_acquire_timewait()
From: bot+bpf-ci @ 2026-06-08 8:53 UTC (permalink / raw)
To: ankur.a.arora, linux-kernel, linux-arch, linux-arm-kernel,
linux-pm, bpf
Cc: arnd, catalin.marinas, will, peterz, akpm, mark.rutland, harisokn,
cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai,
rdunlap, david.laight.linux, broonie, joao.m.martins,
boris.ostrovsky, konrad.wilk, ashok.bhat, ankur.a.arora, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
In-Reply-To: <20260608080440.127491-6-ankur.a.arora@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 3202 bytes --]
> diff --git a/arch/arm64/include/asm/rqspinlock.h b/arch/arm64/include/asm/rqspinlock.h
> index 9ea0a74e5892..a385603436e9 100644
> --- a/arch/arm64/include/asm/rqspinlock.h
> +++ b/arch/arm64/include/asm/rqspinlock.h
> @@ -3,91 +3,6 @@
> #define _ASM_RQSPINLOCK_H
>
> #include <asm/barrier.h>
> -
> -/*
> - * Hardcode res_smp_cond_load_acquire implementations for arm64 to a custom
> - * version based on [0]. In rqspinlock code, our conditional expression involves
> - * checking the value _and_ additionally a timeout. However, on arm64, the
> - * WFE-based implementation may never spin again if no stores occur to the
> - * locked byte in the lock word. As such, we may be stuck forever if
> - * event-stream based unblocking is not available on the platform for WFE spin
> - * loops (arch_timer_evtstrm_available).
> - *
[ ... ]
> -#endif
> -
> -#define res_smp_cond_load_acquire(v, c) smp_cond_load_acquire_timewait(v, c, 0, 1)
> -
> #include <asm-generic/rqspinlock.h>
With res_smp_cond_load_acquire removed here, does arm64 now fall back to
the generic definition in kernel/bpf/rqspinlock.c?
#ifndef res_smp_cond_load_acquire
#define res_smp_cond_load_acquire(v, c) smp_cond_load_acquire(v, c)
#endif
On arm64, smp_cond_load_acquire() uses __cmpwait_relaxed(), which issues a
WFE that wakes only on a store to the monitored cache line or on an
event-stream tick.
The consumer is resilient_queued_spin_lock_slowpath():
kernel/bpf/rqspinlock.c:
res_smp_cond_load_acquire(&lock->locked,
!VAL || RES_CHECK_TIMEOUT(ts, ret, _Q_LOCKED_MASK));
The RES_CHECK_TIMEOUT() escape is part of cond_expr, so it is only
re-evaluated when smp_cond_load_acquire() returns from its WFE.
On platforms where arch_timer_evtstrm_available() is false, if the current
lock owner is stuck or dead and issues no further store to lock->locked,
can the WFE ever wake, and can the RES_CHECK_TIMEOUT timeout ever fire?
This looks like the exact case the removed comment described:
> - * checking the value _and_ additionally a timeout. However, on arm64, the
> - * WFE-based implementation may never spin again if no stores occur to the
> - * locked byte in the lock word. As such, we may be stuck forever if
> - * event-stream based unblocking is not available on the platform for WFE spin
> - * loops (arch_timer_evtstrm_available).
The removed private copy avoided this by falling back to a cpu_relax()-based
spinwait that always re-checks the timeout when the event stream is
unavailable.
Forward search of the series shows this is resolved by the later commit
7abb03c21db2 ("bpf/rqspinlock: Use smp_cond_load_acquire_timeout()"), which
switches rqspinlock to smp_cond_load_acquire_timeout(); on arm64 that uses
a waiting implementation handling the timeout and event-stream-absent case.
Should the change-over happen in the same commit, or is the window where a
kernel built or bisected at this commit can block indefinitely acceptable?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27125050324
^ permalink raw reply
* Re: [PATCH v12 02/15] arm64: barrier: Support smp_cond_load_relaxed_timeout()
From: bot+bpf-ci @ 2026-06-08 8:53 UTC (permalink / raw)
To: ankur.a.arora, linux-kernel, linux-arch, linux-arm-kernel,
linux-pm, bpf
Cc: arnd, catalin.marinas, will, peterz, akpm, mark.rutland, harisokn,
cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai,
rdunlap, david.laight.linux, broonie, joao.m.martins,
boris.ostrovsky, konrad.wilk, ashok.bhat, ankur.a.arora, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
In-Reply-To: <20260608080440.127491-3-ankur.a.arora@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 1930 bytes --]
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fe60738e5943..fa676428ec3f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1606,6 +1606,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
> config ARCH_DEFAULT_CRASH_DUMP
> def_bool y
>
> +config ARCH_HAS_CPU_RELAX
> + def_bool y
> +
ARCH_HAS_CPU_RELAX isn't private to the barrier code. Before this it was
defined only by arch/x86, and the generic kernel already keys cpuidle
behavior off it in two places that arm64 builds.
In drivers/cpuidle/Makefile:
obj-$(CONFIG_ARCH_HAS_CPU_RELAX) += poll_state.o
and in drivers/acpi/processor_idle.c:
#define ACPI_IDLE_STATE_START (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
...
if (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX)) {
cpuidle_poll_state_init(drv);
count = 1;
}
On arm64, ACPI_PROCESSOR is "default y" and depends on ARM64, and it
selects ACPI_PROCESSOR_IDLE which selects CPU_IDLE. So on an ACPI arm64
system this now builds poll_state.o and makes acpi_processor_setup_cstates()
register a POLL idle state as C-state index 0, shifting the firmware
C-states up by one.
The commit message describes this symbol only as indicating "an optimized
implementation of cpu_poll_relax()", and the generic patch describes it as
"a cpu_poll_relax() implementation that is expected to be cheaper". Neither
mentions the cpuidle/ACPI poll_state side effect.
Is enabling the cpuidle polling idle state on arm64 intended here, or is
ARCH_HAS_CPU_RELAX only meant to feed smp_cond_load_relaxed_timeout()? If
the latter, would a dedicated symbol (or decoupling poll_state/ACPI from
ARCH_HAS_CPU_RELAX) avoid the unintended idle-path change?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27125050324
^ permalink raw reply
* Re: [PATCH v12 10/15] bpf/rqspinlock: Use smp_cond_load_acquire_timeout()
From: bot+bpf-ci @ 2026-06-08 9:04 UTC (permalink / raw)
To: ankur.a.arora, linux-kernel, linux-arch, linux-arm-kernel,
linux-pm, bpf
Cc: arnd, catalin.marinas, will, peterz, akpm, mark.rutland, harisokn,
cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai,
rdunlap, david.laight.linux, broonie, joao.m.martins,
boris.ostrovsky, konrad.wilk, ashok.bhat, ankur.a.arora, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
In-Reply-To: <20260608080440.127491-11-ankur.a.arora@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 3229 bytes --]
> bpf/rqspinlock: Use smp_cond_load_acquire_timeout()
>
> Switch out the conditional load interfaces used by rqspinlock
> to smp_cond_read_acquire_timeout() and its wrapper,
> atomic_cond_read_acquire_timeout().
>
> Both these handle the timeout and amortize as needed, so use the
> non-amortized RES_CHECK_TIMEOUT.
>
> RES_CHECK_TIMEOUT does double duty here -- presenting the current
> clock value, the timeout/deadlock error from clock_deadlock() to
> the cond-load and, returning the error value via ret.
>
> For correctness, we need to ensure that the error case of the
> cond-load interface always agrees with that in clock_deadlock().
>
> For the most part, this is fine because there's no independent clock,
> or double reads from the clock in cond-load -- either of which could
> lead to its internal state going out of sync from that of
> clock_deadlock().
>
> There is, however, an edge case where clock_deadlock() checks for:
>
> if (time > ts->timeout_end)
> return -ETIMEDOUT;
>
> while smp_cond_load_acquire_timeout() checks for:
>
> __time_now = (time_expr_ns);
> if (__time_now <= 0 || __time_now >= __time_end) {
> VAL = READ_ONCE(*__PTR);
> break;
> }
>
> This runs into a problem when (__time_now == __time_end) since
> clock_deadlock() does not treat it as a timeout condition but
> the second clause in the conditional above does.
> So, add an equality check in clock_deadlock().
>
> Finally, redefine SMP_TIMEOUT_POLL_COUNT to be 16k to be similar to
> the spin-count used in the amortized version. We only do this for
> non-arm64 as that uses a waiting implementation.
>
> Cc: bpf@vger.kernel.org
> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Besides switching to the new cond-load interface, this commit also
changes the boundary comparison in clock_deadlock() from:
if (time > ts->timeout_end)
return -ETIMEDOUT;
to:
if (time >= ts->timeout_end)
return -ETIMEDOUT;
so that time == timeout_end is now treated as a timeout, matching the
__time_now >= __time_end check in smp_cond_load_acquire_timeout().
The time > ts->timeout_end check, and the timeout_end field itself, were
first introduced in the then-named check_timeout() helper by:
commit 14c48ee81452 ("rqspinlock: Add support for timeouts")
Should this commit carry a Fixes: tag for that boundary change?
Fixes: 14c48ee81452 ("rqspinlock: Add support for timeouts")
This is offered tentatively: under the previous res_smp_cond_load_acquire
interface the '>' comparison was internally consistent, and the boundary
divergence only becomes observable once this commit switches to the
'__time_now >= __time_end' interface. So this may read more as a
self-contained adjustment than a fix for a pre-existing bug.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27125050324
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Jann Horn @ 2026-06-08 15:02 UTC (permalink / raw)
To: Mateusz Guzik, Christian Brauner
Cc: Li Chen, Kees Cook, Alexander Viro, linux-fsdevel, linux-api,
linux-kernel, linux-mm, linux-arch, linux-doc, linux-kselftest,
x86, Arnd Bergmann, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Jan Kara,
Jonathan Corbet, Shuah Khan
In-Reply-To: <vealb52tv5suireenkke4lul2l3wbnaul2rp3ea545ly5wa5ty@yk3aksvp7skt>
On Thu, May 28, 2026 at 2:55 PM Mateusz Guzik <mjguzik@gmail.com> wrote:
> This problem is dear to my heart and I have been pondering it on and off
> for some time now. The entire fork + exec idiom is terrible and needs to
> be retired.
It seems to me like vfork+exec is a decent UAPI building block, on
which you can build nice-looking userspace APIs, though I agree that
this is not an ideal direct interface for application code.
> Additionally there is a known problem where transiently copied file
> descriptors on fork + exec cause a headache in multithreaded programs
> doing something like this in parallel. I only did cursory reading, it
> seems your patchset keeps the same problem in place.
I think we almost have UAPI that would let you avoid this issue?
You can use clone() with CLONE_FILES, then unshare the FD table with
close_range(3, UINT_MAX, CLOSE_RANGE_UNSHARE). That is not currently
implemented to be atomic with stuff that happens on other threads, but
if we changed that, and it doesn't provide a good way to carry some
FDs across, but it feels to me like this could be fixed with a variant
of close_range() that removes O_CLOEXEC FDs except ones listed in an
array.
> There are numerous impactful ways to speed up execs both in terms of
> single-threaded cost and their multicore scalability, most of which
> would be immediately usable by all programs without an opt-in. imo these
> needs to be exhausted before something like a "template" can be
> considered.
(I think probably a large part of this would be stuff that happens in
userspace, like dynamic linking.)
> Per the above, the primary win would stem from *NOT* messing with mm.
As you write below, I think we have that with CLONE_MM? The C function
vfork() is kind of a terrible API because of its returns-twice
behavior, but I think if process cloning with CLONE_VM|CLONE_VFORK was
wrapped by libc in a way similar to clone() (with the child executing
a separate handler function), or if it was used in the implementation
of some higher-level process-spawning API, it would be a perfectly
fine API?
Or am I misunderstanding what you mean by "messing with mm"?
> As in, whatever the interface, it needs to create an "empty" target
> process (for lack of a better term).
>
> In terms of userspace-visible APIs, a clean solution escapes me.
I think we already have relatively good API for this - you can use
clone() to create something that initially shares almost all the state
that a thread would, and then incrementally unshare resources and go
through execve().
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: John Ericson @ 2026-06-08 23:06 UTC (permalink / raw)
To: Li Chen, Christian Brauner
Cc: Kees Cook, Al Viro, linux-fsdevel, linux-api, LKML, linux-mm,
linux-arch, linux-doc, linux-kselftest, x86, Arnd Bergmann,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Jan Kara, Jonathan Corbet,
Shuah Khan
In-Reply-To: <19e8113d290.893abab26142069.5024234139508454104@linux.beauty>
Hi all,
I am happy to see this thread appear. I emailed Christian and others ~5 years
ago about this in this thread[1]; it would be great to see it finally happen!
I very much agree that the new process spawning should be pidfd based. I also
want to emphasize that the crux of the matter is that code needed to set up the
initial unscheduled process --- which I do think should be "real state" and
more than a mere template --- is currently chopped up between clone and exec.
So the real meat of the implementation would be factoring out a bunch of stuff
so it can be reused in both the legacy clone+exec and modern code paths.
I'll say a bit more about this "real state" vs "mere template" distinction,
which is that the latter is effectively some sort of ad-hoc operation batching
language, and always runs the risk of falling behind what the kernel actually
supports. The "real state" approach, where we have honest-to-goodness process
state, just in some partially initialized fashion and thus it's not yet
scheduled, always supports everything the kernel supports in principle.
Yes, alternative syscalls that specify which "embryonic" process (as opposed to
always the current active process) need to be created, but that is less bad
than trying to stuff things into flags etc. for a single existing system call,
and also one can imagine a world (as described in
https://catern.com/rsys21.pdf) where the exact "which process?" parameter
starts getting added to new process modifying machinery by *default*, with a
sentinel value analogous to `AT_FDCWD` used to mean "the current process" for
the legacy used-between-fork-and-exec usecase.
---
Anyways, years ago, after taking a glance at the relevant code in Linux and
FreeBSD, I figured that it would be easier for me personally to first implement
this functionality in FreeBSD, and then, once I had a feel for some of the
refactoring, take a stab at it in Linux. This is because Linux's feature set,
especially things like `binfmt_misc`, makes its clone and exec quite a bit more
complex, and thus the (IMO) necessary heavy refactoring quite a bit more
extensive too.
I never got around to it in the 5 years, but these days, with LLMs, doing an
"exploratory refactor" (to get a sketch of a patch that is fodder for discussion
not yet fit for actual submission) is much easier. So inspired by this thread, I
took a few hours to do the exploratory FreeBSD refactor in [2]. The man page for
the new syscalls, [3], might be a good place to start reading. (This, being from
a FreeBSD patch, describes the change in terms of "proc fds", but the switch to
Linux's "pidfds" should be self-explanatory. The former after all inspired the
latter.)
Hope discussion of such a patch isn't too off topic here, but there is an
interesting thing to note that would also apply to a Linux implementation. It
took *more* factored out helper functions than I thought. The current count is
over 15(!) --- there didn't seem to be a way to build both the old and new way
of doing things with fewer, coarser building blocks. Now, granted, maybe
someone more familiar with either kernel than me could do a better job, but I
think it will still be a number of functions. This indicates just how much
untangling there is to do. And the number will surely be much higher for Linux.
[1]: https://lore.kernel.org/all/f8457e20-c3cc-6e56-96a4-3090d7da0cb6@JohnEricson.me/
[2]: https://github.com/obsidiansystems/freebsd-src/commit/better-proc-spawn
239dcdefe6ad244e58d998155b527375e5293ff7 for posterity
[3]: https://raw.githubusercontent.com/obsidiansystems/freebsd-src/refs/heads/better-proc-spawn/lib/libsys/proc_new.2
On Sun, May 31, 2026, at 10:47 PM, Li Chen wrote:
> Hi Christian,
>
> Thanks a lot for your great review!
>
> ---- On Thu, 28 May 2026 19:02:53 +0800 Christian Brauner <brauner@kernel.org> wrote ---
> > On Thu, May 28, 2026 at 05:52:21PM +0800, Li Chen wrote:
> > > Hi,
> > >
> > > This is an early RFC for an idea that is probably still rough in both the
> > > UAPI and implementation details. Sorry for the rough edges; I am sending
> > > it now to check whether this direction is worth pursuing and to get
> > > feedback on the kernel/userspace boundary.
> >
> > The idea of having a builder api for exec isn't all that crazy. But it
> > should simply be built on top of pidfds and thus pidfs itself instead.
> > It has all the basic infrastructure in place already.
>
> Yes, that makes a lot more sense. I was staring too hard at the "hot
> executable" part and made the cache/template the API, which was probably
> the wrong thing to expose. Sorry about that.
>
> > Any implementation
> > should also allow userspace to implement posix_spawn() on top of it.
>
> That's so cool, and this is a really useful point. I had not thought about this as
> something that could sit under posix_spawn(), but that makes the target
> much clearer. It should be a generic exec/spawn builder first, and the
> agent use case should just be one user of it.
>
> > fd = pidfd_open(0, PIDFD_EMPTY /* or better name */)
> >
> > pidfd_config(fd, ...) // modeled similar to fsconfig()
>
> Reusing pidfd_open() with an empty target is nice because it keeps the API close
> to pidfds, but I wonder if a separate entry point such as
> pidfd_spawn_open() or pidfd_create() would make the "new process
> builder" case a bit more explicit? Either way, the configuration side
> being fsconfig-like makes sense to me.
Yeah check out my syscalls [3] on that front. It's important to design the
workflow / state machine in a good way. Performance/efficiency, security (share
less state/privileges by default!), and extensibility (where will newer
concepts, like a new type of namespace, fit in?) are all competing concerns,
but I think they mostly pull in the same direction. (Only no ambient authority,
back compat, and extensibility exist in some tension.)
> Thanks again for pointing me in this direction. It helps a lot.
>
> Regards,
> Li
Glad you are sold on pidfds, and more broadly, best of luck! You'll be a hero
to everyone else that has wanted this over the years :)
John
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Andy Lutomirski @ 2026-06-09 0:01 UTC (permalink / raw)
To: Christian Brauner
Cc: Li Chen, Kees Cook, Alexander Viro, linux-fsdevel, linux-api,
linux-kernel, linux-mm, linux-arch, linux-doc, linux-kselftest,
x86, Arnd Bergmann, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Jan Kara,
Jonathan Corbet, Shuah Khan
In-Reply-To: <20260528-madig-fachrichtung-fehlinformation-61117ba640da@brauner>
On Thu, May 28, 2026 at 4:05 AM Christian Brauner <brauner@kernel.org> wrote:
>
> On Thu, May 28, 2026 at 05:52:21PM +0800, Li Chen wrote:
> > Hi,
> >
> > This is an early RFC for an idea that is probably still rough in both the
> > UAPI and implementation details. Sorry for the rough edges; I am sending
> > it now to check whether this direction is worth pursuing and to get
> > feedback on the kernel/userspace boundary.
>
> The idea of having a builder api for exec isn't all that crazy. But it
> should simply be built on top of pidfds and thus pidfs itself instead.
> It has all the basic infrastructure in place already. Any implementation
> should also allow userspace to implement posix_spawn() on top of it.
>
> fd = pidfd_open(0, PIDFD_EMPTY /* or better name */)
>
> pidfd_config(fd, ...) // modeled similar to fsconfig()
>
After contemplating this for a bit... why pidfd? Doesn't a pidfd
refer to an actual process that is, or at least was, running? This
new thing is a process that we are contemplating spawning. I can
imagine that basically all pidfd APIs would be a bit confused by the
nonexistence of the process in question.
^ permalink raw reply
* Re: [PATCH v2 1/5] arch: select HAVE_ARCH_BITREVERSE conditionally on BITREVERSE
From: Jinjie Ruan @ 2026-06-09 1:26 UTC (permalink / raw)
To: Yury Norov, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yury Norov, Rasmus Villemoes, Arnd Bergmann,
Eric Biggers, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Andrew Morton, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, linux-kernel, linux-riscv, linux-arch, netdev,
bpf
In-Reply-To: <20260506175207.110893-2-ynorov@nvidia.com>
On 5/7/2026 1:52 AM, Yury Norov wrote:
> Architectures may have bit reversal instructions, but if the API not
> needed, the corresponding option should not be selected because it may
> lead to generating the unneeded code.
>
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> arch/arm/Kconfig | 2 +-
> arch/arm64/Kconfig | 2 +-
> arch/loongarch/Kconfig | 2 +-
> arch/mips/Kconfig | 2 +-
> lib/Kconfig | 1 +
> 5 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 71fc5dd4123f..0e963e54fe06 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -83,7 +83,7 @@ config ARM
> select HARDIRQS_SW_RESEND
> select HAS_IOPORT
> select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
> - select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
> + select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 && BITREVERSE
I think there is a semantic confusion:
HAVE_ARCH_BITREVERSE indicates that the architecture itself has an
efficient bit‑reverse implementation (e.g., the RBIT instruction on
ARMv7). It is a hardware capability declaration and should not depend on
a higher‑level feature option like BITREVERSE.
> select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && (!PREEMPT_RT || !SMP)
> select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL
> select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fe60738e5943..f5bb62c2ba9c 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -150,7 +150,7 @@ config ARM64
> select HAVE_ACPI_APEI if (ACPI && EFI)
> select HAVE_ALIGNED_STRUCT_PAGE
> select HAVE_ARCH_AUDITSYSCALL
> - select HAVE_ARCH_BITREVERSE
> + select HAVE_ARCH_BITREVERSE if BITREVERSE
[..]
> bool
> default n
> + depends on BITREVERSE
> help
> This option enables the use of hardware bit-reversal instructions on
> architectures which support such operations.
^ permalink raw reply
* Re: [PATCH v2 4/5] arch/riscv: Add bitrev.h file to support rev8 and brev8
From: Jinjie Ruan @ 2026-06-09 1:38 UTC (permalink / raw)
To: Yury Norov, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yury Norov, Rasmus Villemoes, Arnd Bergmann,
Eric Biggers, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Andrew Morton, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, linux-kernel, linux-riscv, linux-arch, netdev,
bpf
Cc: David Laight
In-Reply-To: <20260506175207.110893-5-ynorov@nvidia.com>
On 5/7/2026 1:52 AM, Yury Norov wrote:
> From: Jinjie Ruan <ruanjinjie@huawei.com>
>
> The RISC-V Bit-manipulation Extension for Cryptography (Zbkb) provides
> the 'brev8' instruction, which reverses the bits within each byte.
> Combined with the 'rev8' instruction (from Zbb or Zbkb), which reverses
> the byte order of a register, we can efficiently implement 16-bit,
> 32-bit, and (on RV64) 64-bit bit reversal.
>
> This is significantly faster than the default software table-lookup
> implementation in lib/bitrev.c, as it replaces memory accesses and
> multiple arithmetic operations with just two or three hardware
> instructions.
>
> Select HAVE_ARCH_BITREVERSE as well as GENERIC_BITREVERSE,
> and provide <asm/bitrev.h> to utilize these instructions when
> the Zbkb extension is available at runtime via the alternatives
> mechanism.
>
> [Yury: select the options conditionally on BITREVERSE]
>
> Link: https://docs.riscv.org/reference/isa/unpriv/b-st-ext.html
> Suggested-by: David Laight <david.laight.linux@gmail.com>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> arch/riscv/Kconfig | 2 ++
> arch/riscv/include/asm/bitrev.h | 51 +++++++++++++++++++++++++++++++++
> 2 files changed, 53 insertions(+)
> create mode 100644 arch/riscv/include/asm/bitrev.h
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index d235396c4514..a708583f785d 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -104,6 +104,7 @@ config RISCV
> select FUNCTION_ALIGNMENT_8B if DYNAMIC_FTRACE_WITH_CALL_OPS
> select GENERIC_ARCH_TOPOLOGY
> select GENERIC_ATOMIC64 if !64BIT
> + select GENERIC_BITREVERSE if HAVE_ARCH_BITREVERSE
Maybe 'select GENERIC_BITREVERSE if BITREVERSE' ?
> select GENERIC_CLOCKEVENTS_BROADCAST if SMP
> select GENERIC_CPU_DEVICES
> select GENERIC_CPU_VULNERABILITIES
> @@ -128,6 +129,7 @@ config RISCV
> select HAS_IOPORT if MMU
> select HAVE_ALIGNED_STRUCT_PAGE
> select HAVE_ARCH_AUDITSYSCALL
> + select HAVE_ARCH_BITREVERSE if RISCV_ISA_ZBKB && BITREVERSE
> select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
> select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
> select HAVE_ARCH_JUMP_LABEL
> diff --git a/arch/riscv/include/asm/bitrev.h b/arch/riscv/include/asm/bitrev.h
> new file mode 100644
> index 000000000000..4b9b8d34cc3b
> --- /dev/null
> +++ b/arch/riscv/include/asm/bitrev.h
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_BITREV_H
> +#define __ASM_BITREV_H
> +
> +#include <linux/types.h>
> +#include <asm/cpufeature-macros.h>
> +#include <asm/hwcap.h>
> +#include <asm-generic/bitops/__bitrev.h>
> +
> +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
> +{
> + unsigned long result;
> +
> + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
> + return generic___bitrev32(x);
> +
> + asm volatile(
> + ".option push\n"
> + ".option arch,+zbkb\n"
> + "rev8 %0, %1\n"
> + "brev8 %0, %0\n"
> + ".option pop"
> + : "=r" (result) : "r" ((long)x)
> + );
> +
> + return result >> (__riscv_xlen - 32);
> +}
> +
> +static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
> +{
> + return __arch_bitrev32(x) >> 16;
> +}
> +
> +static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
> +{
> + unsigned long result;
> +
> + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB))
> + return generic___bitrev8(x);
> +
> + asm volatile(
> + ".option push\n"
> + ".option arch,+zbkb\n"
> + "brev8 %0, %1\n"
> + ".option pop"
> + : "=r" (result) : "r" ((long)x)
> + );
> +
> + return result;
> +}
> +#endif
^ permalink raw reply
* Re: [PATCH v2 2/5] lib/bitrev: Introduce GENERIC_BITREVERSE
From: Jinjie Ruan @ 2026-06-09 1:53 UTC (permalink / raw)
To: Yury Norov, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yury Norov, Rasmus Villemoes, Arnd Bergmann,
Eric Biggers, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Andrew Morton, Alexei Starovoitov,
Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, linux-kernel, linux-riscv, linux-arch, netdev,
bpf
In-Reply-To: <20260506175207.110893-3-ynorov@nvidia.com>
On 5/7/2026 1:52 AM, Yury Norov wrote:
> The generic bit reversal implementation is controlled by
> !HAVE_ARCH_BITREVERSE. This makes it difficult for architectures to
> provide a hardware-accelerated implementation while being able to
> fall back to the generic version if needed.
>
> This patch adds GENERIC_BITREVERSE, so bitreverse API is controlled by
> BITREVERSE, GENERIC_BITREVERSE and HAVE_ARCH_BITREVERSE options. The
> relationship between them is described as follows:
>
> - BITREVERSE is selected by user code; it's required to generate the API;
> - Architectures may select HAVE_ARCH_BITREVERSE and provide an arch
> implementation in arch/$(ARCH)/include/asm/bitrev.h.
> - if HAVE_ARCH_BITREVERSE isn't set, BITREVERSE selects GENERIC_BITREVERSE;
> - if GENERIC_BITREVERSE is set and HAVE_ARCH_BITREVERSE is not, the kernel
> provides generic implementation only, and wires bitrevXX() to it.
> - if HAVE_ARCH_BITREVERSE is set and GENERIC_BITREVERSE is not, the arch
> code provides __arch_bitrevXX(), and it is wired to bitrevXX();
> - if both GENERIC_BITREVERSE and HAVE_ARCH_BITREVERSE are selected, the kernel
> generates generic___bitrev(), but wires bitrev() to the __arch_bitrev().
>
> The last option allows architectures to use generic___bitrev() as a
> fallback option.
>
> Drivers and core code should never select GENERIC_BITREVERSE or
> HAVE_ARCH_BITREVERSE explicitly.
>
> Architectures that require generic bitreverse API as a fallback should
> explicitly enable GENERIC_BITREVERSE together with HAVE_ARCH_BITREVERSE.
>
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> lib/Kconfig | 12 ++++++++++++
> lib/Makefile | 2 +-
> lib/bitrev.c | 3 ---
> 3 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/lib/Kconfig b/lib/Kconfig
> index d8e7e89ae320..a33988adfaa3 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -54,6 +54,7 @@ config PACKING_KUNIT_TEST
>
> config BITREVERSE
> tristate
> + select GENERIC_BITREVERSE if !HAVE_ARCH_BITREVERSE
>
> config HAVE_ARCH_BITREVERSE
> bool
> @@ -63,6 +64,17 @@ config HAVE_ARCH_BITREVERSE
> This option enables the use of hardware bit-reversal instructions on
> architectures which support such operations.
>
> +config GENERIC_BITREVERSE
> + tristate
> + depends on BITREVERSE
> + help
> + Generic bit reversal implementation. Drivers should never enable
> + it explicitly. Instead, enable BITREVERSE.
The later riscv implementation force GENERIC_BITREVERSE even when
HAVE_ARCH_BITREVERSE=y but triggers a Kconfig unmet direct dependency
warning as below:
warning: (RISCV) selects GENERIC_BITREVERSE which has unmet direct
dependencies (BITREVERSE)
This happens because select ignores depends on clauses and can force a
tristate symbol to y even when its dependency BITREVERSE is only =m. The
warning is a symptom of an invalid dependency chain.
Link:
https://lore.kernel.org/all/20260506214943.1AAE8C2BCB0@smtp.kernel.org/
> +
> + Architectures may want to select it as a fall-back option for
> + HAVE_ARCH_BITREVERSE, when the hardware-accelerated bit reverse
> + instruction set is optional, like RISC-V ZBKB extension.
> +
> config ARCH_HAS_STRNCPY_FROM_USER
> bool
>
> diff --git a/lib/Makefile b/lib/Makefile
> index f33a24bf1c19..23e07d19d01c 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -145,7 +145,7 @@ obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
> obj-$(CONFIG_LIST_HARDENED) += list_debug.o
> obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
>
> -obj-$(CONFIG_BITREVERSE) += bitrev.o
> +obj-$(CONFIG_GENERIC_BITREVERSE) += bitrev.o
> obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o
> obj-$(CONFIG_PACKING) += packing.o
> obj-$(CONFIG_PACKING_KUNIT_TEST) += packing_test.o
> diff --git a/lib/bitrev.c b/lib/bitrev.c
> index 81b56e0a7f32..05088231f31f 100644
> --- a/lib/bitrev.c
> +++ b/lib/bitrev.c
> @@ -1,5 +1,4 @@
> // SPDX-License-Identifier: GPL-2.0-only
> -#ifndef CONFIG_HAVE_ARCH_BITREVERSE
> #include <linux/types.h>
> #include <linux/module.h>
> #include <linux/bitrev.h>
> @@ -43,5 +42,3 @@ const u8 byte_rev_table[256] = {
> 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
> };
> EXPORT_SYMBOL_GPL(byte_rev_table);
> -
> -#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Florian Weimer @ 2026-06-09 6:08 UTC (permalink / raw)
To: Jann Horn
Cc: Mateusz Guzik, Christian Brauner, Li Chen, Kees Cook,
Alexander Viro, linux-fsdevel, linux-api, linux-kernel, linux-mm,
linux-arch, linux-doc, linux-kselftest, x86, Arnd Bergmann,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Jan Kara, Jonathan Corbet,
Shuah Khan
In-Reply-To: <CAG48ez38OEE8ZPLyU6nr9=cYx-hMsdoh5WRrv-GMZGMDKyyOTA@mail.gmail.com>
* Jann Horn:
>> Per the above, the primary win would stem from *NOT* messing with mm.
>
> As you write below, I think we have that with CLONE_MM? The C function
> vfork() is kind of a terrible API because of its returns-twice
> behavior, but I think if process cloning with CLONE_VM|CLONE_VFORK was
> wrapped by libc in a way similar to clone() (with the child executing
> a separate handler function), or if it was used in the implementation
> of some higher-level process-spawning API, it would be a perfectly
> fine API?
No, there is still a problem with SIGTSTP handling because we cannot
atomically unmask the signal during execve. We need to unblock SIGTSTP
before execve in the new process, but this means that it can get
suspended by SIGTSTP. Consequently, the execve never happens and the
original process is stuck in vfork:
posix_spawn: parent can get stuck in uninterruptible sleep if child
receives SIGTSTP early enough
<https://inbox.sourceware.org/libc-help/2921668c-773e-465d-9480-0abb6f979bf9@www.fastmail.com/>
More on the low-level side, it's difficult to make sure that execve gets
a consistent snapshot of the environ vector. Both vfork and execve need
to be async-signal-safe. Any locking or memory allocation (except for
the stack …) persists in the original process after vfork returns. The
environ vector can be large, so making a copy on the stack is not ideal.
It's even harder for getenv/setenv/unsetenv implementations that use
locking instead of software transactional memory.
In general, I prefer the vfork+execve API over things like posix_spawn
because eventually, you have dependencies between the syslets, or need
control flow. This introduces a lot of complexity. Conceptually,
vfork+execve is much simpler, and in many ways quite safe (even mutexes
work as long as they do not need a correct TID).
Thanks,
Florian
^ permalink raw reply
* [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Gabriele Monaco @ 2026-06-09 9:49 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Arnd Bergmann, bpf,
linux-arch, linux-kernel
Cc: Gabriele Monaco
raw_res_spin_unlock_irqrestore() calls raw_res_spin_unlock() and then
restores interrupts, this means preemption is enabled when interrupts
are still disabled (as part of raw_res_spin_unlock()) so this cannot
trigger an actual preemption.
This is inconsistent with other spinlock implementations
(raw_spin_unlock_irqrestore() and bpf_res_spin_unlock_irqrestore()
itself).
Adjust the macro to ensure interrupts are enabled before enabling
preemption, allowing to schedule at that point. Make the same
modification in the error path of raw_res_spin_lock_irqsave().
Fixes: 101acd2e78b1 ("rqspinlock: Add macros for rqspinlock usage")
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/asm-generic/rqspinlock.h | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/rqspinlock.h b/include/asm-generic/rqspinlock.h
index 151d267a49..4d46643f46 100644
--- a/include/asm-generic/rqspinlock.h
+++ b/include/asm-generic/rqspinlock.h
@@ -243,12 +243,20 @@ static __always_inline void res_spin_unlock(rqspinlock_t *lock)
({ \
int __ret; \
local_irq_save(flags); \
- __ret = raw_res_spin_lock(lock); \
- if (__ret) \
+ preempt_disable(); \
+ __ret = res_spin_lock(lock); \
+ if (__ret) { \
local_irq_restore(flags); \
+ preempt_enable(); \
+ } \
__ret; \
})
-#define raw_res_spin_unlock_irqrestore(lock, flags) ({ raw_res_spin_unlock(lock); local_irq_restore(flags); })
+#define raw_res_spin_unlock_irqrestore(lock, flags) \
+ ({ \
+ res_spin_unlock(lock); \
+ local_irq_restore(flags); \
+ preempt_enable(); \
+ })
#endif /* __ASM_GENERIC_RQSPINLOCK_H */
base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Arnd Bergmann @ 2026-06-09 11:22 UTC (permalink / raw)
To: Gabriele Monaco, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, bpf,
Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <20260609094941.56122-1-gmonaco@redhat.com>
On Tue, Jun 9, 2026, at 11:49, Gabriele Monaco wrote:
> raw_res_spin_unlock_irqrestore() calls raw_res_spin_unlock() and then
> restores interrupts, this means preemption is enabled when interrupts
> are still disabled (as part of raw_res_spin_unlock()) so this cannot
> trigger an actual preemption.
> This is inconsistent with other spinlock implementations
> (raw_spin_unlock_irqrestore() and bpf_res_spin_unlock_irqrestore()
> itself).
>
> Adjust the macro to ensure interrupts are enabled before enabling
> preemption, allowing to schedule at that point. Make the same
> modification in the error path of raw_res_spin_lock_irqsave().
>
> Fixes: 101acd2e78b1 ("rqspinlock: Add macros for rqspinlock usage")
Should this be Cc:stable@vger.kernel.org to get backported?
Did you see this cause measurable performance problems,
or did you find it through inspection?
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
Acked-by: Arnd Bergmann <arnd@arndb.de> # asm-generic
This should probably get merged through the BPF tree, but I've
added the kernel/locking maintainers to Cc as well, since I
feel it's more useful to have them look at it than me.
Maybe it would be good to update (as a separate patch) the
MAINTAINERS file so the locking subsystem also includes the
headers currently missing:
arch/*/include/asm/*spinlock*.h
arch/*/include/asm/*rwlock*.h
include/asm-generic/*spinlock*.h
include/asm-generic/*rwlock*.h
Arnd
(full patch quoted below)
> ---
> include/asm-generic/rqspinlock.h | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/include/asm-generic/rqspinlock.h
> b/include/asm-generic/rqspinlock.h
> index 151d267a49..4d46643f46 100644
> --- a/include/asm-generic/rqspinlock.h
> +++ b/include/asm-generic/rqspinlock.h
> @@ -243,12 +243,20 @@ static __always_inline void
> res_spin_unlock(rqspinlock_t *lock)
> ({ \
> int __ret; \
> local_irq_save(flags); \
> - __ret = raw_res_spin_lock(lock); \
> - if (__ret) \
> + preempt_disable(); \
> + __ret = res_spin_lock(lock); \
> + if (__ret) { \
> local_irq_restore(flags); \
> + preempt_enable(); \
> + } \
> __ret; \
> })
>
> -#define raw_res_spin_unlock_irqrestore(lock, flags) ({
> raw_res_spin_unlock(lock); local_irq_restore(flags); })
> +#define raw_res_spin_unlock_irqrestore(lock, flags) \
> + ({ \
> + res_spin_unlock(lock); \
> + local_irq_restore(flags); \
> + preempt_enable(); \
> + })
>
> #endif /* __ASM_GENERIC_RQSPINLOCK_H */
>
> base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
> --
> 2.54.0
^ permalink raw reply
* Re: [PATCH v4 6/8] string: introduce memcpy_streaming() helpers
From: Li Zhe @ 2026-06-09 12:01 UTC (permalink / raw)
To: bp
Cc: akpm, apopple, arnd, dave.hansen, david, kees, linux-arch,
linux-hardening, linux-kernel, linux-mm, lizhe.67, mingo, rppt,
tglx, x86
In-Reply-To: <20260607190804.GAaiXBlGO2eRcfs1oB@fat_crate.local>
On Sun, 7 Jun 2026 12:08:04 -0700, bp@alien8.de wrote:
> On Wed, Jun 03, 2026 at 04:01:50PM +0800, Li Zhe wrote:
> > Introduce a generic memcpy_streaming() interface for write-once copy
> > sites that can fall back to memcpy() when no architecture-specific
> > optimization is available, or when an architecture-specific backend
> > cannot safely handle a given transfer.
> >
> > Add memcpy_streaming_drain() alongside it so callers can separate the
> > copy primitive from any required ordering point. On x86, use
> > memcpy_flushcache() and sfence only for aligned transfers that can stay
> > entirely on the non-temporal store path; otherwise fall back to memcpy()
>
> So you throwing "streaming", "non-temporal" and "flush-cache" wildly around
> here and this is adding unnecessary confusion where it shouldn't. I'd suggest
> you stick to "non-temporal" which you can abbreviate short'n'sweet to "nt" and
> that's it. Keep it simple.
Thanks for the review. Will switch to nt-based naming in next revision.
> > so the generic API does not expose flushcache semantics on cached
> > head/tail fragments.
> >
> > Callers are responsible for invoking memcpy_streaming_drain() before
> > later normal stores that must be ordered after the streaming copy.
> >
> > Signed-off-by: Li Zhe <lizhe.67@bytedance.com>
> > ---
> > arch/x86/include/asm/string_64.h | 32 ++++++++++++++++++++++++++++++++
> > include/linux/string.h | 20 ++++++++++++++++++++
> > 2 files changed, 52 insertions(+)
> >
> > diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
> > index 4635616863f5..aee63108577f 100644
> > --- a/arch/x86/include/asm/string_64.h
> > +++ b/arch/x86/include/asm/string_64.h
>
> There's arch/x86/include/asm/string.h. Why are those here, in the _64 variant?
The current placement was meant to reflect that the x86 implementation
here is really just a thin wrapper around the existing
memcpy_flushcache() backend, and that backend is x86_64-only today.
On x86, CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE is selected only for X86_64,
so a 32-bit build would still need to fall back to the generic
memcpy()-based implementation anyway. Keeping it in string_64.h made
that backend dependency explicit.
That said, I see your layering point. If arch/x86/include/asm/string.h
is the preferred place for the arch-visible wrapper, I can move the
wrapper there in the next revision while keeping the x86_64-specific
implementation details in string_64.h.
> > @@ -4,6 +4,7 @@
> >
> > #ifdef __KERNEL__
> > #include <linux/jump_label.h>
> > +#include <linux/align.h>
> >
> > /* Written 2002 by Andi Kleen */
> >
> > @@ -100,6 +101,37 @@ static __always_inline void memcpy_flushcache(void *dst, const void *src, size_t
> > }
> > __memcpy_flushcache(dst, src, cnt);
> > }
> > +
> > +/*
> > + * Only map memcpy_streaming() to memcpy_flushcache() when the destination
> > + * is already 8-byte aligned and the size can be handled without cached
> > + * head/tail fragments in __memcpy_flushcache().
> > + */
> > +static __always_inline bool memcpy_flushcache_nt_safe(const void *dst,
> > + size_t cnt)
>
> This is checking alignment. Then call it that.
>
> > +{
> > + unsigned long d = (unsigned long)dst;
>
> Useless.
>
> > +
> > + return cnt && IS_ALIGNED(d, 8) && IS_ALIGNED(cnt, 4);
> > +}
>
> AFAICT, this helper is used only once. Zap it completely.
Agreed. That helper is over-factored in its current form.
I'll fold the alignment test into the callsite and drop the temporary
variable in the next revision.
> > +
> > +#define __HAVE_ARCH_MEMCPY_STREAMING 1
> > +static __always_inline void memcpy_streaming(void *dst, const void *src,
>
> memcpy_nt()
>
> > + size_t cnt)
> > +{
> > + if (!cnt)
> > + return;
> > +
> > + if (memcpy_flushcache_nt_safe(dst, cnt))
>
> That branch can cost. Why is that alignment checking so necessary? Why can't
> you simply DTRT by handling the misaligned parts like __memcpy_flushcache().
>
> What does this bring you? None of that is explained in the commit message so
> why do I want this patch at all?
>
> The commit message is basically telling me what the patch does but I can kinda
> read that from the diff itself. What it is not telling me is *why* it exists.
The extra alignment gating was meant to keep this helper narrower than
__memcpy_flushcache(), so patch 8 would not inherit the mixed cached
head/tail handling from that implementation.
Thinking about it more, I agree that this is hard to justify for a
generic helper. For this series, what really matters is that the
struct page copies in patch 8 can use the existing x86
memcpy_flushcache() fastpaths where that is beneficial; I do not need
patch 6 to impose extra selection policy on unrelated callers.
I'll simplify and rework this part in the next revision, rewrite the
changelog to explain the actual motivation more clearly, and respin
patches 6-8 accordingly.
Thanks,
Zhe
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Gabriele Monaco @ 2026-06-09 13:04 UTC (permalink / raw)
To: Arnd Bergmann, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, bpf,
Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <d40ba64d-78d9-45f5-99b9-4bfb1fc27f6c@app.fastmail.com>
On Tue, 2026-06-09 at 13:22 +0200, Arnd Bergmann wrote:
> Should this be Cc:stable@vger.kernel.org to get backported?
Not sure if the Fixes: is enough to trigger the automation, I rarely
remember to Cc:stable@vger.kernel.org and they're usually picked.
In case I guess I'd need to re-submit the patch right?
> Did you see this cause measurable performance problems,
> or did you find it through inspection?
I noticed it while debugging an ENOMEM issue in the test_maps BPF
selftest on PREEMPT_RT and this was an obvious cuplrit (irq_work not
scheduled during a stress run). Turns out the problem is still there
after this fix though.
>
> > Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
>
> Acked-by: Arnd Bergmann <arnd@arndb.de> # asm-generic
Thanks,
Gabriele
>
> This should probably get merged through the BPF tree, but I've
> added the kernel/locking maintainers to Cc as well, since I
> feel it's more useful to have them look at it than me.
>
> Maybe it would be good to update (as a separate patch) the
> MAINTAINERS file so the locking subsystem also includes the
> headers currently missing:
>
> arch/*/include/asm/*spinlock*.h
> arch/*/include/asm/*rwlock*.h
> include/asm-generic/*spinlock*.h
> include/asm-generic/*rwlock*.h
>
> Arnd
>
> (full patch quoted below)
>
> > ---
> > include/asm-generic/rqspinlock.h | 14 +++++++++++---
> > 1 file changed, 11 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/asm-generic/rqspinlock.h
> > b/include/asm-generic/rqspinlock.h
> > index 151d267a49..4d46643f46 100644
> > --- a/include/asm-generic/rqspinlock.h
> > +++ b/include/asm-generic/rqspinlock.h
> > @@ -243,12 +243,20 @@ static __always_inline void
> > res_spin_unlock(rqspinlock_t *lock)
> > ({ \
> > int __ret; \
> > local_irq_save(flags); \
> > - __ret = raw_res_spin_lock(lock); \
> > - if (__ret) \
> > + preempt_disable(); \
> > + __ret = res_spin_lock(lock); \
> > + if (__ret) { \
> > local_irq_restore(flags); \
> > + preempt_enable(); \
> > + } \
> > __ret; \
> > })
> >
> > -#define raw_res_spin_unlock_irqrestore(lock, flags) ({
> > raw_res_spin_unlock(lock); local_irq_restore(flags); })
> > +#define raw_res_spin_unlock_irqrestore(lock, flags) \
> > + ({ \
> > + res_spin_unlock(lock); \
> > + local_irq_restore(flags); \
> > + preempt_enable(); \
> > + })
> >
> > #endif /* __ASM_GENERIC_RQSPINLOCK_H */
> >
> > base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
> > --
> > 2.54.0
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Arnd Bergmann @ 2026-06-09 13:08 UTC (permalink / raw)
To: Gabriele Monaco, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, bpf,
Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <defc6b1339dea2f64f936902dd6e1f850cff9f4e.camel@redhat.com>
On Tue, Jun 9, 2026, at 15:04, Gabriele Monaco wrote:
> On Tue, 2026-06-09 at 13:22 +0200, Arnd Bergmann wrote:
>> Should this be Cc:stable@vger.kernel.org to get backported?
>
> Not sure if the Fixes: is enough to trigger the automation, I rarely
> remember to Cc:stable@vger.kernel.org and they're usually picked.
There is always human interaction. If you just have 'Fixes',
this means someone will have to look at the patch carefully
and make a decision, since a lot of bugfix patches either don't
apply to old kernels or don't fall under the rules for stable
backports.
If the patch gets tagged Cc:, this means it is expected to be
backported and needs less manual work.
> In case I guess I'd need to re-submit the patch right?
It can be added by whoever picks up the patch.
>> Did you see this cause measurable performance problems,
>> or did you find it through inspection?
>
> I noticed it while debugging an ENOMEM issue in the test_maps BPF
> selftest on PREEMPT_RT and this was an obvious cuplrit (irq_work not
> scheduled during a stress run). Turns out the problem is still there
> after this fix though.
Ok
Arnd
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Peter Zijlstra @ 2026-06-09 14:35 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Gabriele Monaco, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, bpf,
Linux-Arch, linux-kernel, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long
In-Reply-To: <d40ba64d-78d9-45f5-99b9-4bfb1fc27f6c@app.fastmail.com>
On Tue, Jun 09, 2026 at 01:22:35PM +0200, Arnd Bergmann wrote:
> On Tue, Jun 9, 2026, at 11:49, Gabriele Monaco wrote:
> > raw_res_spin_unlock_irqrestore() calls raw_res_spin_unlock() and then
> > restores interrupts, this means preemption is enabled when interrupts
> > are still disabled (as part of raw_res_spin_unlock()) so this cannot
> > trigger an actual preemption.
> > This is inconsistent with other spinlock implementations
> > (raw_spin_unlock_irqrestore() and bpf_res_spin_unlock_irqrestore()
> > itself).
> >
> > Adjust the macro to ensure interrupts are enabled before enabling
> > preemption, allowing to schedule at that point. Make the same
> > modification in the error path of raw_res_spin_lock_irqsave().
> >
> > Fixes: 101acd2e78b1 ("rqspinlock: Add macros for rqspinlock usage")
Yeah, this is right. spinlocks always get one preempt_disable, in
addition they might also get irq or bh disable.
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Kumar Kartikeya Dwivedi @ 2026-06-09 14:42 UTC (permalink / raw)
To: Gabriele Monaco, Arnd Bergmann, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman,
Kumar Kartikeya Dwivedi, bpf, Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <defc6b1339dea2f64f936902dd6e1f850cff9f4e.camel@redhat.com>
On Tue Jun 9, 2026 at 3:04 PM CEST, Gabriele Monaco wrote:
> On Tue, 2026-06-09 at 13:22 +0200, Arnd Bergmann wrote:
>> Should this be Cc:stable@vger.kernel.org to get backported?
>
> Not sure if the Fixes: is enough to trigger the automation, I rarely
> remember to Cc:stable@vger.kernel.org and they're usually picked.
>
> In case I guess I'd need to re-submit the patch right?
>
>> Did you see this cause measurable performance problems,
>> or did you find it through inspection?
>
> I noticed it while debugging an ENOMEM issue in the test_maps BPF
> selftest on PREEMPT_RT and this was an obvious cuplrit (irq_work not
> scheduled during a stress run). Turns out the problem is still there
> after this fix though.
I would imagine this to be the least of your problems, I think there's a bunch
of blockers for complete selftests passing with PREEMPT_RT support in BPF.
>
>>
>> > Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
>>
>> Acked-by: Arnd Bergmann <arnd@arndb.de> # asm-generic
The patch makes sense to me as well.
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Li Chen @ 2026-06-09 14:43 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Christian Brauner, Kees Cook, Alexander Viro, linux-fsdevel,
linux-api, linux-kernel, linux-mm, linux-arch, linux-doc,
linux-kselftest, x86, Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Jan Kara,
Jonathan Corbet, Shuah Khan
In-Reply-To: <CALCETrWJQpLR4n1cpichBk8=uExSKLWTMGU3BufGdk_WE_p5UA@mail.gmail.com>
Hi Andy,
---- On Tue, 09 Jun 2026 08:01:57 +0800 Andy Lutomirski <luto@kernel.org> wrote ---
> On Thu, May 28, 2026 at 4:05 AM Christian Brauner <brauner@kernel.org> wrote:
> >
> > On Thu, May 28, 2026 at 05:52:21PM +0800, Li Chen wrote:
> > > Hi,
> > >
> > > This is an early RFC for an idea that is probably still rough in both the
> > > UAPI and implementation details. Sorry for the rough edges; I am sending
> > > it now to check whether this direction is worth pursuing and to get
> > > feedback on the kernel/userspace boundary.
> >
> > The idea of having a builder api for exec isn't all that crazy. But it
> > should simply be built on top of pidfds and thus pidfs itself instead.
> > It has all the basic infrastructure in place already. Any implementation
> > should also allow userspace to implement posix_spawn() on top of it.
> >
> > fd = pidfd_open(0, PIDFD_EMPTY /* or better name */)
> >
> > pidfd_config(fd, ...) // modeled similar to fsconfig()
> >
>
> After contemplating this for a bit... why pidfd? Doesn't a pidfd
> refer to an actual process that is, or at least was, running? This
> new thing is a process that we are contemplating spawning. I can
> imagine that basically all pidfd APIs would be a bit confused by the
> nonexistence of the process in question.
>
Yes, I think that is a real concern.
In my current local WIP I tried to keep that distinction explicit.
pidfd_spawn_open() returns a pidfs-backed builder fd, not a normal pidfd
referring to a process. The builder fd is allocated as an anonymous pidfs
file with builder-specific file operations:
file = pidfs_alloc_anon_file("[pidfd_spawn]",
&pidfd_spawn_builder_fops, builder,
O_RDWR);
and the normal pidfd helpers still reject it because it does not use the
ordinary pidfd file operations:
struct pid *pidfd_pid(const struct file *file)
{
if (file->f_op != &pidfs_file_operations)
return ERR_PTR(-EBADF);
return file_inode(file)->i_private;
}
So the current split is:
builder_fd = pidfd_spawn_open(...); /* builder object */
pidfd_config(builder_fd, ...);
child_pidfd = pidfd_spawn_run(builder_fd, ...); /* real pidfd */
Only the last fd is a normal pidfd for an actual child process. The
builder fd is only accepted by the builder operations.
This avoids having to define what waitid(P_PIDFD), pidfd_send_signal(),
pidfd_getfd(), poll(), etc. mean before the process exists. The downside
is that it adds a separate open-style entry point and is less uniform than
the pidfd_open(0, PIDFD_EMPTY) spelling Christian sketched.
If people think there is a better way to represent the pre-spawn builder
state, or if the preference is to integrate it directly into pidfd_open()
with an explicit empty/future-pidfd state, I would be happy to discuss
that.
Regards,
Li
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Gabriele Monaco @ 2026-06-09 16:17 UTC (permalink / raw)
To: Kumar Kartikeya Dwivedi, Arnd Bergmann, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, bpf,
Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <DJ4LJ3T8PYRG.3TG272FHH78RM@gmail.com>
On Tue, 2026-06-09 at 16:42 +0200, Kumar Kartikeya Dwivedi wrote:
> On Tue Jun 9, 2026 at 3:04 PM CEST, Gabriele Monaco wrote:
> > On Tue, 2026-06-09 at 13:22 +0200, Arnd Bergmann wrote:
> >
> > > Did you see this cause measurable performance problems,
> > > or did you find it through inspection?
> >
> > I noticed it while debugging an ENOMEM issue in the test_maps BPF
> > selftest on PREEMPT_RT and this was an obvious cuplrit (irq_work
> > not scheduled during a stress run). Turns out the problem is still
> > there after this fix though.
>
> I would imagine this to be the least of your problems, I think
> there's a bunch of blockers for complete selftests passing with
> PREEMPT_RT support in BPF.
>
Well, I'm starting to believe that too..
At the moment on well tuned machines we are only observing ENOMEM
issues in the test_maps and only when it's literally hogging the
allocator (preallocation is off and 100 treads do updates in parallel).
What else are you expecting to fail under PREEMPT_RT?
> > > > Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> > >
> > > Acked-by: Arnd Bergmann <arnd@arndb.de> # asm-generic
>
> The patch makes sense to me as well.
>
> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Thanks,
Gabriele
^ permalink raw reply
* Re: [PATCH] rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule
From: Alexei Starovoitov @ 2026-06-09 16:57 UTC (permalink / raw)
To: Gabriele Monaco, Arnd Bergmann, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman,
Kumar Kartikeya Dwivedi, bpf, Linux-Arch, linux-kernel
Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long
In-Reply-To: <defc6b1339dea2f64f936902dd6e1f850cff9f4e.camel@redhat.com>
On Tue Jun 9, 2026 at 6:04 AM PDT, Gabriele Monaco wrote:
> On Tue, 2026-06-09 at 13:22 +0200, Arnd Bergmann wrote:
>> Should this be Cc:stable@vger.kernel.org to get backported?
>
> Not sure if the Fixes: is enough to trigger the automation, I rarely
> remember to Cc:stable@vger.kernel.org and they're usually picked.
>
> In case I guess I'd need to re-submit the patch right?
Yes. For whatever reason the patch didn't reach the patchwork.
Please resubmit with [PATCH bpf-next] subject, so that CI can test it properly.
And collect Acks.
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: John Ericson @ 2026-06-09 17:27 UTC (permalink / raw)
To: Li Chen, Andy Lutomirski
Cc: Christian Brauner, Kees Cook, Al Viro, linux-fsdevel, linux-api,
LKML, linux-mm, linux-arch, linux-doc, linux-kselftest, x86,
Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Jan Kara, Jonathan Corbet,
Shuah Khan
In-Reply-To: <19eacd64508.26b92c022125848.262962729296162879@linux.beauty>
On Tue, Jun 9, 2026, at 10:43 AM, Li Chen wrote:
> Hi Andy,
>
> ---- On Tue, 09 Jun 2026 08:01:57 +0800 Andy Lutomirski <luto@kernel.org> wrote ---
> > [...]
> >
> > After contemplating this for a bit... why pidfd? Doesn't a pidfd
> > refer to an actual process that is, or at least was, running? This
> > new thing is a process that we are contemplating spawning. I can
> > imagine that basically all pidfd APIs would be a bit confused by the
> > nonexistence of the process in question.
> >
>
> Yes, I think that is a real concern.
>
> In my current local WIP I tried to keep that distinction explicit.
> pidfd_spawn_open() returns a pidfs-backed builder fd, not a normal pidfd
> referring to a process. The builder fd is allocated as an anonymous pidfs
> file with builder-specific file operations:
>
> file = pidfs_alloc_anon_file("[pidfd_spawn]",
> &pidfd_spawn_builder_fops, builder,
> O_RDWR);
>
What does your builder fd point to, explicitly? For example in my other reply I
talked about how it was "real" process state. In my FreeBSD patch, for example,
I found there was already a status for a process "in exec", and I figured that
was clean to reuse for one of these "embryonic" processes that also hadn't
started running. I would reckon that Linux probably has some similar notions.
> and the normal pidfd helpers still reject it because it does not use the
> ordinary pidfd file operations:
>
> struct pid *pidfd_pid(const struct file *file)
> {
> if (file->f_op != &pidfs_file_operations)
> return ERR_PTR(-EBADF);
> return file_inode(file)->i_private;
> }
>
> So the current split is:
>
> builder_fd = pidfd_spawn_open(...); /* builder object */
> pidfd_config(builder_fd, ...);
> child_pidfd = pidfd_spawn_run(builder_fd, ...); /* real pidfd */
>
> Only the last fd is a normal pidfd for an actual child process. The builder
> fd is only accepted by the builder operations.
>
> This avoids having to define what waitid(P_PIDFD), pidfd_send_signal(),
> pidfd_getfd(), poll(), etc. mean before the process exists.
I wouldn't be so sure this is necessary/good. For example, I think it could
make sense to wait on a process that has yet to be started; one just waits for
both the process to start and the process to exit. Obviously a blocking syscall
in the thread that is spawning the process is not useful, but the asynchronous
poll variation seems fine.
As long as there is real process state here, it shouldn't be too hard to
implement.
> The downside is that it adds a separate open-style entry point and is less
> uniform than the pidfd_open(0, PIDFD_EMPTY) spelling Christian sketched.
I do think there is no point having two file descriptors. The file descriptor
that previously referred to the builder/embryonic process then can refer to the
real process, right?
> If people think there is a better way to represent the pre-spawn builder
> state, or if the preference is to integrate it directly into pidfd_open()
> with an explicit empty/future-pidfd state, I would be happy to discuss that.
Hope the above answers your question? I suppose my ideas lean more on the
"future" than "empty" side --- there is indeed a thread in the thread group,
with real VM/namespace/file descriptor etc. state. Moreover, state gets
initialized before the process is started, so the actual start is a pretty
lightweight step of just letting the scheduler know the now-ready process can
be scheduled. The only thing that distinguishes the embryonic process from a
real one is simply that it isn't running --- i.e. isn't (yet) available to be
scheduled --- so the pidfds holders are free to poke at its state.
Cheers,
John
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Jann Horn @ 2026-06-09 17:53 UTC (permalink / raw)
To: Florian Weimer
Cc: Mateusz Guzik, Christian Brauner, Li Chen, Kees Cook,
Alexander Viro, linux-fsdevel, linux-api, linux-kernel, linux-mm,
linux-arch, linux-doc, linux-kselftest, x86, Arnd Bergmann,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Jan Kara, Jonathan Corbet,
Shuah Khan
In-Reply-To: <lhubjdk1c1m.fsf@oldenburg.str.redhat.com>
On Tue, Jun 9, 2026 at 8:08 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Jann Horn:
>
> >> Per the above, the primary win would stem from *NOT* messing with mm.
> >
> > As you write below, I think we have that with CLONE_MM? The C function
> > vfork() is kind of a terrible API because of its returns-twice
> > behavior, but I think if process cloning with CLONE_VM|CLONE_VFORK was
> > wrapped by libc in a way similar to clone() (with the child executing
> > a separate handler function), or if it was used in the implementation
> > of some higher-level process-spawning API, it would be a perfectly
> > fine API?
>
> No, there is still a problem with SIGTSTP handling because we cannot
> atomically unmask the signal during execve. We need to unblock SIGTSTP
> before execve in the new process, but this means that it can get
> suspended by SIGTSTP. Consequently, the execve never happens and the
> original process is stuck in vfork:
>
> posix_spawn: parent can get stuck in uninterruptible sleep if child
> receives SIGTSTP early enough
> <https://inbox.sourceware.org/libc-help/2921668c-773e-465d-9480-0abb6f979bf9@www.fastmail.com/>
>
> More on the low-level side, it's difficult to make sure that execve gets
> a consistent snapshot of the environ vector. Both vfork and execve need
> to be async-signal-safe. Any locking or memory allocation (except for
> the stack …) persists in the original process after vfork returns. The
I think that's not entirely accurate; if you call set_robust_list() on
a futex list, then call execve(), the futexes should be released once
the process switches to a new MM, in
begin_new_exec -> exec_mmap -> exec_mm_release -> futex_exec_release
-> futex_cleanup -> exit_robust_list.
So in theory you could use clone() with CLONE_VM and without
CLONE_VFORK, and let the parent either wait for a futex that is
released on exec, or somehow asynchronously check later whether the
futex is still held... probably not the nicest building block but
maybe workable? Though I guess it would fit more nicely if there was a
"munmap() this range on exec" API...
> environ vector can be large, so making a copy on the stack is not ideal.
> It's even harder for getenv/setenv/unsetenv implementations that use
> locking instead of software transactional memory.
Makes sense, that kind of sounds like a pain inherent in being able to
execute from signal handler context...
^ permalink raw reply
* [RFC PATCH 0/6] arm64: hyperv: Add Realm support for Hyper-V
From: Kameron Carr @ 2026-06-09 18:10 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, longli
Cc: catalin.marinas, will, mark.rutland, lpieralisi, sudeep.holla,
arnd, thuth, linux-hyperv, linux-arm-kernel, linux-kernel,
linux-arch, mhklinux
From: Kameron Carr <kameroncarr@microsoft.com>
Realms (CoCo VMs on ARM) require host calls to be routed through the RMM
(Realm Management Monitor) via the RSI (Realm Service Interface). This
series implements most of the necessary changes to support Realms on
Hyper-V.
One required change is not included in this series. The two buffers
allocated via vzalloc() in netvsc_init_buf() cannot be decrypted in
vmbus_establish_gpadl(). Currently only linearly mapped memory can be
decrypted. See my RFC patch [1]. I will implement the accompanying netvsc
changes based on the feedback I receive on that patch.
This patch series was tested by booting a Realm on Cobalt 200 running
Windows. I decreased the buffer size and used kzalloc() in
netvsc_init_buf() in my testing as a workaround for the issue mentioned
above.
[1] https://lore.kernel.org/all/20260521205834.1012925-1-kameroncarr@linux.microsoft.com/
Kameron Carr (6):
arm64: rsi: Add RSI host call structure and helper function
firmware: smccc: Detect hypervisor via RSI host call in CCA Realms
arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
Drivers: hv: Mark shared memory as decrypted for CCA Realms
arm64: hyperv: Route hypercalls through RSI host call in CCA Realms
arm64: hyperv: Implement hv_is_isolation_supported() for CCA Realms
arch/arm64/hyperv/hv_core.c | 175 ++++++++++++++++++++++++------
arch/arm64/hyperv/mshyperv.c | 88 ++++++++++++++-
arch/arm64/include/asm/mshyperv.h | 3 +
arch/arm64/include/asm/rsi_cmds.h | 9 ++
arch/arm64/include/asm/rsi_smc.h | 6 +
drivers/firmware/smccc/smccc.c | 41 ++++++-
drivers/hv/hv_common.c | 9 +-
include/asm-generic/mshyperv.h | 1 +
8 files changed, 294 insertions(+), 38 deletions(-)
base-commit: 7a035678fc2bdee81881170764ef08a91a076147
--
2.45.4
^ permalink raw reply
* [RFC PATCH 1/6] arm64: rsi: Add RSI host call structure and helper function
From: Kameron Carr @ 2026-06-09 18:10 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, longli
Cc: catalin.marinas, will, mark.rutland, lpieralisi, sudeep.holla,
arnd, thuth, linux-hyperv, linux-arm-kernel, linux-kernel,
linux-arch, mhklinux
In-Reply-To: <20260609181030.2378391-1-kameroncarr@linux.microsoft.com>
Add struct rsi_host_call to rsi_smc.h, which represents the host call
data structure used by the Realm Management Monitor (RMM) for the
RSI_HOST_CALL interface. The structure contains a 16-bit immediate field
and 31 general-purpose register values, aligned to 256 bytes as required
by the CCA RMM specification.
Add rsi_host_call() static inline wrapper in rsi_cmds.h that invokes
SMC_RSI_HOST_CALL with the physical address of the host call structure.
This will be used by Hyper-V guest code to route hypercalls through the
RSI interface when running inside an Arm CCA Realm.
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
arch/arm64/include/asm/rsi_cmds.h | 9 +++++++++
arch/arm64/include/asm/rsi_smc.h | 6 ++++++
2 files changed, 15 insertions(+)
diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi_cmds.h
index 2c8763876dfb7..83b4b1f598454 100644
--- a/arch/arm64/include/asm/rsi_cmds.h
+++ b/arch/arm64/include/asm/rsi_cmds.h
@@ -159,4 +159,13 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
return res.a0;
}
+static inline long rsi_host_call(phys_addr_t host_call_struct)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_RSI_HOST_CALL, host_call_struct, 0, 0, 0, 0, 0, 0,
+ &res);
+ return res.a0;
+}
+
#endif /* __ASM_RSI_CMDS_H */
diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_smc.h
index e19253f96c940..ffea93340ed7f 100644
--- a/arch/arm64/include/asm/rsi_smc.h
+++ b/arch/arm64/include/asm/rsi_smc.h
@@ -142,6 +142,12 @@ struct realm_config {
*/
} __aligned(0x1000);
+struct rsi_host_call {
+ u16 immediate;
+ u64 gprs[31];
+} __aligned(256);
+static_assert(sizeof(struct rsi_host_call) == 256);
+
#endif /* __ASSEMBLER__ */
/*
--
2.45.4
^ permalink raw reply related
* [RFC PATCH 2/6] firmware: smccc: Detect hypervisor via RSI host call in CCA Realms
From: Kameron Carr @ 2026-06-09 18:10 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, longli
Cc: catalin.marinas, will, mark.rutland, lpieralisi, sudeep.holla,
arnd, thuth, linux-hyperv, linux-arm-kernel, linux-kernel,
linux-arch, mhklinux
In-Reply-To: <20260609181030.2378391-1-kameroncarr@linux.microsoft.com>
Modify arm_smccc_hypervisor_has_uuid() to check is_realm_world() and
use rsi_host_call() to query the hypervisor vendor UUID when inside a
Realm. The realm path is factored into a helper,
arm_smccc_realm_get_hypervisor_uuid(), that owns a file-static
rsi_host_call buffer (uuid_hc) serialized by a spinlock.
The RSI-specific includes, file-static state and helper are guarded
with CONFIG_ARM64 because <asm/rsi.h> does not exist on 32-bit ARM.
For non-Realm environments, the existing arm_smccc_1_1_invoke() path
is unchanged.
Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
---
drivers/firmware/smccc/smccc.c | 41 +++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index bdee057db2fd3..6b465e65472b0 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -12,6 +12,12 @@
#include <linux/platform_device.h>
#include <asm/archrandom.h>
+#ifdef CONFIG_ARM64
+#include <linux/cleanup.h>
+#include <linux/spinlock.h>
+#include <asm/rsi.h>
+#endif
+
static u32 smccc_version = ARM_SMCCC_VERSION_1_0;
static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
@@ -67,12 +73,45 @@ s32 arm_smccc_get_soc_id_revision(void)
}
EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
+#ifdef CONFIG_ARM64
+static struct rsi_host_call uuid_hc;
+static DEFINE_SPINLOCK(uuid_hc_lock);
+
+/*
+ * Helper function to get the hypervisor UUID via an RsiHostCall.
+ */
+static bool arm_smccc_realm_get_hypervisor_uuid(struct arm_smccc_res *res)
+{
+ guard(spinlock_irqsave)(&uuid_hc_lock);
+
+ memset(&uuid_hc, 0, sizeof(uuid_hc));
+ uuid_hc.gprs[0] = ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID;
+
+ if (rsi_host_call(__pa_symbol(&uuid_hc)) != RSI_SUCCESS)
+ return false;
+
+ res->a0 = uuid_hc.gprs[0];
+ res->a1 = uuid_hc.gprs[1];
+ res->a2 = uuid_hc.gprs[2];
+ res->a3 = uuid_hc.gprs[3];
+ return true;
+}
+#endif
+
bool arm_smccc_hypervisor_has_uuid(const uuid_t *hyp_uuid)
{
struct arm_smccc_res res = {};
uuid_t uuid;
- arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
+#ifdef CONFIG_ARM64
+ if (is_realm_world()) {
+ if (!arm_smccc_realm_get_hypervisor_uuid(&res))
+ return false;
+ } else
+#endif
+ arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID,
+ &res);
+
if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
return false;
--
2.45.4
^ permalink raw reply related
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