authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-06-04 00:36:25+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-06-04 00:54:35+02:00
log52d33b6ae41e86e81423d0dcb3e072de7be53789
tree94c7e5224f1e3bbea6c4cbe9a478f0128fa2c707
parentd1865477fb675a1bf60cbbe5c98bd12fb7cbbb8f
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.os.linux.sparc64: work around kernel bug with uncommitted stack in clone()

https://sourceware.org/bugzilla/show_bug.cgi?id=31394

1 files changed, 16 insertions(+), 2 deletions(-)

lib/std/os/linux/sparc64.zig+16-2
...@@ -196,17 +196,28 @@ pub fn clone() callconv(.naked) u64 {...@@ -196,17 +196,28 @@ pub fn clone() callconv(.naked) u64 {
196 // g1 o0, o1, o2, o3, o4196 // g1 o0, o1, o2, o3, o4
197 asm volatile (197 asm volatile (
198 \\ save %%sp, -192, %%sp198 \\ save %%sp, -192, %%sp
199 \\
200 \\ // clone() on SPARC can fail with EFAULT if %%sp points to uncommitted memory, so flush
201 \\ // all register windows up to this point to ensure that the kernel has enough committed
202 \\ // memory for its stack frame.
203 \\ save %%sp, -192, %%sp
204 \\ flushw
205 \\ restore
206 \\
199 \\ # Save the func pointer and the arg pointer207 \\ # Save the func pointer and the arg pointer
200 \\ mov %%i0, %%g2208 \\ mov %%i0, %%g2
201 \\ mov %%i3, %%g3209 \\ mov %%i3, %%g3
210 \\
202 \\ # Shuffle the arguments211 \\ # Shuffle the arguments
203 \\ mov 217, %%g1 // SYS_clone212 \\ mov 217, %%g1 // SYS_clone
204 \\ mov %%i2, %%o0213 \\ mov %%i2, %%o0
214 \\
205 \\ # Add some extra space for the initial frame215 \\ # Add some extra space for the initial frame
206 \\ sub %%i1, 176 + 2047, %%o1216 \\ sub %%i1, 192 + 2047, %%o1
217 \\
207 \\ mov %%i4, %%o2218 \\ mov %%i4, %%o2
208 \\ mov %%i5, %%o3219 \\ mov %%i5, %%o3
209 \\ ldx [%%fp + 0x8af], %%o4220 \\ ldx [%%fp + 176 + 2047], %%o4
210 \\ t 0x6d221 \\ t 0x6d
211 \\ bcs,pn %%xcc, 1f222 \\ bcs,pn %%xcc, 1f
212 \\ nop223 \\ nop
...@@ -214,15 +225,18 @@ pub fn clone() callconv(.naked) u64 {...@@ -214,15 +225,18 @@ pub fn clone() callconv(.naked) u64 {
214 \\ # process is the child (=1) or the parent (=0).225 \\ # process is the child (=1) or the parent (=0).
215 \\ brnz %%o1, 2f226 \\ brnz %%o1, 2f
216 \\ nop227 \\ nop
228 \\
217 \\ # Parent process, return the child pid229 \\ # Parent process, return the child pid
218 \\ mov %%o0, %%i0230 \\ mov %%o0, %%i0
219 \\ ret231 \\ ret
220 \\ restore232 \\ restore
233 \\
221 \\1:234 \\1:
222 \\ # The syscall failed235 \\ # The syscall failed
223 \\ sub %%g0, %%o0, %%i0236 \\ sub %%g0, %%o0, %%i0
224 \\ ret237 \\ ret
225 \\ restore238 \\ restore
239 \\
226 \\2:240 \\2:
227 \\ # Child process241 \\ # Child process
228 );242 );