This is an automated email from the ASF dual-hosted git repository. jerpelea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit cd1e88f9db1c2d6ad91b7cc64f1e17b4f9606486 Author: Marco Casaroli <[email protected]> AuthorDate: Sun Nov 1 11:31:50 2026 +0100 arch/x86_64: Give the system call parameters in their registers. sys_call6() loads the system call number and the six parameters into RAX, RDI, RSI, RDX, R10, R8 and R9 with one move each, from operands that the compiler may put in any register ("rm"). None of the six registers is an output or a clobber, so with optimization the compiler can keep a parameter in one of them, and a move before it overwrites it. Then the kernel gets a wrong parameter. For example qemu-intel64:knsh_romfs with CONFIG_DEBUG_FULLOPT: the kernel faults on address 0x27 when init starts. Without optimization every operand is on the stack, so this did not show. Put each value in its register with a register variable and pass them as operands of the syscall instruction. The kernel can change them, so they are outputs too. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- arch/x86_64/include/syscall.h | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/arch/x86_64/include/syscall.h b/arch/x86_64/include/syscall.h index 87acd968925..b4e5d3da235 100644 --- a/arch/x86_64/include/syscall.h +++ b/arch/x86_64/include/syscall.h @@ -162,9 +162,17 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6) { - uint64_t ret; - - /* Registers modified by syscall instruction: + register uint64_t rax __asm__("rax") = nbr; + register uint64_t rdi __asm__("rdi") = parm1; + register uint64_t rsi __asm__("rsi") = parm2; + register uint64_t rdx __asm__("rdx") = parm3; + register uint64_t r10 __asm__("r10") = parm4; + register uint64_t r8 __asm__("r8") = parm5; + register uint64_t r9 __asm__("r9") = parm6; + + /* Each parameter is in its register before the syscall instruction. + * The kernel can change them, so they are outputs too. + * Registers modified by the syscall instruction: * RCX = RIP * R11 = RFLAGS * RIP = IA32_LSTAR (x86_64_syscall_entry) @@ -172,23 +180,14 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, __asm__ volatile ( - "movl %1, %%eax\n" - "movq %2, %%rdi\n" - "movq %3, %%rsi\n" - "movq %4, %%rdx\n" - "movq %5, %%r10\n" - "movq %6, %%r8\n" - "movq %7, %%r9\n" "syscall\n" - "movq %%rax, %0\n" - : "=r"(ret) - : "rm"(nbr), "rm"(parm1), "rm"(parm2), - "rm"(parm3), "rm"(parm4), "rm"(parm5), - "rm"(parm6) + : "+r"(rax), "+r"(rdi), "+r"(rsi), "+r"(rdx), "+r"(r10), "+r"(r8), + "+r"(r9) + : : "memory", "rcx", "r11" ); - return ret; + return rax; } #ifdef __cplusplus
