]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use timer_settime64 on 32-bit Linux
authorabdullahkiani007 <abdullahkiani931@gmail.com>
Sat, 18 Oct 2025 14:43:53 +0000 (14:43 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 21 Oct 2025 16:35:47 +0000 (09:35 -0700)
Linux introduced new syscalls to fix the year 2038 issue.
To still be able to use the old ones, the Kconfig option
COMPAT_32BIT_TIME would be necessary.

Use the new 64-bit syscall for timer_settime by default.
Add a fallback to use the 32-bit syscall when the
64-bit version returns _ENOSYS.

Fixes #75133

Change-Id: Iccb8831b67f665067ee526e93c3ff2f4f5392edf
GitHub-Last-Rev: 6c3d62d60e5ff02ebe61e56e06d6365e530ec39e
GitHub-Pull-Request: golang/go#75957
Reviewed-on: https://go-review.googlesource.com/c/go/+/712642
Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jorropo <jorropo.pgm@gmail.com>

src/runtime/defs_linux_386.go
src/runtime/defs_linux_arm.go
src/runtime/defs_linux_mipsx.go
src/runtime/os_linux.go
src/runtime/os_linux_settime32.go [new file with mode: 0644]
src/runtime/os_linux_settime64.go [new file with mode: 0644]
src/runtime/sys_linux_386.s
src/runtime/sys_linux_arm.s
src/runtime/sys_linux_mipsx.s

index e902d8175c3b0dee71c4886162b6eb17cee59349..c6c7d7d6d880c0a6105831adc2b30d5256a7c042 100644 (file)
@@ -237,10 +237,14 @@ type ucontext struct {
        uc_sigmask  uint32
 }
 
-type itimerspec struct {
+type itimerspec32 struct {
        it_interval timespec32
        it_value    timespec32
 }
+type itimerspec struct {
+       it_interval timespec
+       it_value    timespec
+}
 
 type itimerval struct {
        it_interval timeval
index 35c4faf96405d372867d79fddf5b6ef990ce4094..ff879fad89faa1418e3dff612534cb99c2d06108 100644 (file)
@@ -169,11 +169,16 @@ func (tv *timeval) set_usec(x int32) {
        tv.tv_usec = x
 }
 
-type itimerspec struct {
+type itimerspec32 struct {
        it_interval timespec32
        it_value    timespec32
 }
 
+type itimerspec struct {
+       it_interval timespec
+       it_value    timespec
+}
+
 type itimerval struct {
        it_interval timeval
        it_value    timeval
index cec504c885662b734b70198b5e6f26026b4b6871..5b10b910dbebf29dfb0995d56bbc10bea6eacf34 100644 (file)
@@ -152,11 +152,16 @@ type siginfo struct {
        _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
 }
 
-type itimerspec struct {
+type itimerspec32 struct {
        it_interval timespec32
        it_value    timespec32
 }
 
+type itimerspec struct {
+       it_interval timespec
+       it_value    timespec
+}
+
 type itimerval struct {
        it_interval timeval
        it_value    timeval
index 080dd9653232ed79289e25d9df7ccd64e22939d1..1b7d5731cc32abce861433f788b36fe6020148c1 100644 (file)
@@ -435,9 +435,6 @@ func setitimer(mode int32, new, old *itimerval)
 //go:noescape
 func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
 
-//go:noescape
-func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
-
 //go:noescape
 func timer_delete(timerid int32) int32
 
diff --git a/src/runtime/os_linux_settime32.go b/src/runtime/os_linux_settime32.go
new file mode 100644 (file)
index 0000000..6df7f21
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && (386 || arm || mips || mipsle)
+
+package runtime
+
+import "internal/runtime/atomic"
+
+var timer32bitOnly atomic.Bool
+
+//go:noescape
+func timer_settime32(timerid int32, flags int32, new, old *itimerspec32) int32
+
+//go:noescape
+func timer_settime64(timerid int32, flags int32, new, old *itimerspec) int32
+
+//go:nosplit
+func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 {
+       if !timer32bitOnly.Load() {
+               ret := timer_settime64(timerid, flags, new, old)
+               // timer_settime64 is only supported on Linux 5.0+
+               if ret != -_ENOSYS {
+                       return ret
+               }
+               timer32bitOnly.Store(true)
+       }
+
+       var newts,oldts itimerspec32
+       var new32,old32 *itimerspec32
+
+       if new != nil {
+               newts.it_interval.setNsec(new.it_interval.tv_sec*1e9 + new.it_interval.tv_nsec)
+               newts.it_value.setNsec(new.it_value.tv_sec*1e9 + new.it_value.tv_nsec)
+               new32 = &newts
+       }
+
+       if old != nil {
+               oldts.it_interval.setNsec(old.it_interval.tv_sec*1e9 + old.it_interval.tv_nsec)
+               oldts.it_value.setNsec(old.it_value.tv_sec*1e9 + old.it_value.tv_nsec)
+               old32 = &oldts
+       }
+
+       // Fall back to 32-bit timer
+       return timer_settime32(timerid, flags, new32, old32)
+}
diff --git a/src/runtime/os_linux_settime64.go b/src/runtime/os_linux_settime64.go
new file mode 100644 (file)
index 0000000..60650da
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !(386 || arm || mips || mipsle)
+
+package runtime
+
+//go:noescape
+func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
index 1c3f1ff3e6e575af14e96f4b753e6c75842823a8..f664d8ace7f997fb57d24fcf89caa2c0454cbfa4 100644 (file)
@@ -54,6 +54,7 @@
 #define SYS_exit_group         252
 #define SYS_timer_create       259
 #define SYS_timer_settime      260
+#define SYS_timer_settime64    409
 #define SYS_timer_delete       263
 #define SYS_clock_gettime      265
 #define SYS_tgkill             270
@@ -209,7 +210,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
        MOVL    AX, ret+12(FP)
        RET
 
-TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
+// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME
+TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
        MOVL    $SYS_timer_settime, AX
        MOVL    timerid+0(FP), BX
        MOVL    flags+4(FP), CX
@@ -219,6 +221,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
        MOVL    AX, ret+16(FP)
        RET
 
+TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
+       MOVL    $SYS_timer_settime64, AX
+       MOVL    timerid+0(FP), BX
+       MOVL    flags+4(FP), CX
+       MOVL    new+8(FP), DX
+       MOVL    old+12(FP), SI
+       INVOKE_SYSCALL
+       MOVL    AX, ret+16(FP)
+       RET
+
 TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
        MOVL    $SYS_timer_delete, AX
        MOVL    timerid+0(FP), BX
index 44b56ccb9f009463de3d2cadc288f0c4bd915101..f19e293d0fc3e034273ea36661774d4123b19cad 100644 (file)
@@ -44,6 +44,7 @@
 #define SYS_clock_gettime (SYS_BASE + 263)
 #define SYS_timer_create (SYS_BASE + 257)
 #define SYS_timer_settime (SYS_BASE + 258)
+#define SYS_timer_settime64 (SYS_BASE + 409)
 #define SYS_timer_delete (SYS_BASE + 261)
 #define SYS_pipe2 (SYS_BASE + 359)
 #define SYS_access (SYS_BASE + 33)
@@ -231,8 +232,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
        SWI     $0
        MOVW    R0, ret+12(FP)
        RET
-
-TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
+// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME.
+TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
        MOVW    timerid+0(FP), R0
        MOVW    flags+4(FP), R1
        MOVW    new+8(FP), R2
@@ -242,6 +243,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
        MOVW    R0, ret+16(FP)
        RET
 
+TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
+       MOVW    timerid+0(FP), R0
+       MOVW    flags+4(FP), R1
+       MOVW    new+8(FP), R2
+       MOVW    old+12(FP), R3
+       MOVW    $SYS_timer_settime64, R7
+       SWI     $0
+       MOVW    R0, ret+16(FP)
+       RET
+
 TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
        MOVW    timerid+0(FP), R0
        MOVW    $SYS_timer_delete, R7
index 6f11841efc73e2ba73e8b1676d1de470defdcb00..bc3f84fbb9591e49219fbfdade5ea739f7b65c54 100644 (file)
@@ -39,6 +39,7 @@
 #define SYS_exit_group         4246
 #define SYS_timer_create       4257
 #define SYS_timer_settime      4258
+#define SYS_timer_settime64    4409
 #define SYS_timer_delete       4261
 #define SYS_clock_gettime      4263
 #define SYS_tgkill             4266
@@ -197,7 +198,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
        MOVW    R2, ret+12(FP)
        RET
 
-TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
+// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME
+TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
        MOVW    timerid+0(FP), R4
        MOVW    flags+4(FP), R5
        MOVW    new+8(FP), R6
@@ -207,6 +209,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
        MOVW    R2, ret+16(FP)
        RET
 
+TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
+       MOVW    timerid+0(FP), R4
+       MOVW    flags+4(FP), R5
+       MOVW    new+8(FP), R6
+       MOVW    old+12(FP), R7
+       MOVW    $SYS_timer_settime64, R2
+       SYSCALL
+       MOVW    R2, ret+16(FP)
+       RET
+
 TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
        MOVW    timerid+0(FP), R4
        MOVW    $SYS_timer_delete, R2