News: 0001646091

  ARM Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life (Terry Pratchett, Jingo)

Reworked System Call Entry Handling Slated For Linux 7.3

([Linux Kernel] 6 Hours Ago Big Rework)


Stemming from looking at a proposed Linux kernel patch to alter the Linux kernel's system call number handling, veteran Linux kernel developer Thomas Gleixner went down a rabbit hole of the kernel's system call entry handling to make a number of clean-ups and improvements to the code. That rework to the system call entry handling is now expected to land for the Linux 7.3 kernel cycle.

When going through the system call entry handling code for Linux, he realized some CPU architectures supported by the Linux kernel weren't treating kernel stack randomization in the same manner. Some architectures like PowerPC got their stack randomization "wrong" and "suboptimal".

Gleixner ended up adapting all architectures to use the generic syscall entry code following the same scheme and with correct stack randomization as early as possible. Plus he ended up addressing some "x86 oddities" in the code. And in the end his system call heavy workload benchmarking and micro-benchmarks reflect a small performance gain from the rework. So in the end it seems to be a nice win for this rework of the syscall entry handling.

Gleixner elaborated on [1]the patch series from June:

"That discussion made me look deeper into the related code and as usual there were a lot of other things to discover.

1) Stack randomization

add_random_kstack_offset() can only be invoked after enter_from_user_mode() established proper state as it calls into instrumentable code.

PowerPC got that wrong and the other architectures either invoke it after enter_from_user_mode() or after syscall_enter_from_user_mode().

The latter is suboptimal as the randomization takes place after all the user mode entry work. Aside of that add_random_kstack_offset() uses get/put_cpu_var(), which makes it usable in preemptible code, but when invoked in the interrupt disabled region that's pointless overhead.

2) As discussed in the above thread just changing the function signature of syscall_enter_from_user_mode[_work]() so they take a pointer argument for the syscall and then return 0 on success is not really intuitive either. Aside of that this breaks the implicit assumption of the tracer when setting the syscall number to -1.

3) The x86 entry code has some historically accumulated oddities

The following series addresses this by:

1) Providing new [syscall_]enter_from_user_mode() variants, which include stack randomization and utilize a new add_random_kstack_offset_irqsoff() variant, which avoids the get/put_cpu_var() overhead and converting all usage sites over

2) Picking up Jinjie's seccomp patch from:

https://lore.kernel.org/lkml/ [2][email protected]

and addressing the feedback (renaming the seccomp functions)

3) Making the ptrace and tracer related functions return a boolean value to indicate syscall permission

4) Addressing the x86 oddities

5) Converting the tree over to the new scheme

With that all architectures using the generic syscall entry code follow the same scheme, apply stack randomization at the correct and earliest possible place and skip syscall processing depending on the boolean return value of syscall_enter_from_user_mode[_work]().

There should be no functional changes, at least there are none intended.

The resulting text size for the syscall entry code on x8664 is slightly smaller than before these changes.

Testing syscall heavy workloads and micro benchmarks shows a small performance gain for the general rework, but the last patch, which changes the logic to be more understandable has no measurable impact in either direction."

With those patches now working their way into [3]tip/tip.git's core/entry Git branch as of yesterday, it's expected that the material will be submitted for the upcoming Linux 7.3 merge window.



[1] https://lore.kernel.org/all/20260707181957.433213175@kernel.org/

[2] https://www.phoronix.com/cdn-cgi/l/email-protection

[3] https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/?h=core/entry



There was once a programmer who was attached to the court of the
warlord of Wu. The warlord asked the programmer: "Which is easier to design:
an accounting package or an operating system?"
"An operating system," replied the programmer.
The warlord uttered an exclamation of disbelief. "Surely an
accounting package is trivial next to the complexity of an operating
system," he said.
"Not so," said the programmer, "when designing an accounting package,
the programmer operates as a mediator between people having different ideas:
how it must operate, how its reports must appear, and how it must conform to
the tax laws. By contrast, an operating system is not limited my outside
appearances. When designing an operating system, the programmer seeks the
simplest harmony between machine and ideas. This is why an operating system
is easier to design."
The warlord of Wu nodded and smiled. "That is all good and well, but
which is easier to debug?"
The programmer made no reply.
-- Geoffrey James, "The Tao of Programming"