| author | |
| committer | |
| log | df5bbb5b95137384384a758145f6eedcca51867c |
| tree | 37b34ab6785ddd58152da86a2d56f9f37236bd06 |
| parent | f212e3716b7f687d552fdad5f15cd1f736039910 |
| parent | bcf65eb51085c0fa1a9380172cdea55811d9fe97 |
| signature |
8 files changed, 49 insertions(+), 57 deletions(-)
lib/std/Io/RwLock.zig-2| ... | @@ -284,8 +284,6 @@ test "concurrent access" { | ... | @@ -284,8 +284,6 @@ test "concurrent access" { |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | test "lock canceling" { | 286 | test "lock canceling" { |
| 287 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 288 | |||
| 289 | const io = testing.io; | 287 | const io = testing.io; |
| 290 | 288 | ||
| 291 | var rl: Io.RwLock = .init; | 289 | var rl: Io.RwLock = .init; |
lib/std/Io/Threaded/test.zig-2| ... | @@ -149,8 +149,6 @@ test "async with array return type" { | ... | @@ -149,8 +149,6 @@ test "async with array return type" { |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | test "cancel blocked read from pipe" { | 151 | test "cancel blocked read from pipe" { |
| 152 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 153 | |||
| 154 | const global = struct { | 152 | const global = struct { |
| 155 | fn readFromPipe(io: Io, pipe: Io.File) !void { | 153 | fn readFromPipe(io: Io, pipe: Io.File) !void { |
| 156 | var buf: [1]u8 = undefined; | 154 | var buf: [1]u8 = undefined; |
lib/std/Io/net/test.zig-2| ... | @@ -356,8 +356,6 @@ test "decompress compressed DNS name" { | ... | @@ -356,8 +356,6 @@ test "decompress compressed DNS name" { |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | test "cancel accept" { | 358 | test "cancel accept" { |
| 359 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 360 | |||
| 361 | const io = testing.io; | 359 | const io = testing.io; |
| 362 | const localhost: net.IpAddress = .{ .ip4 = .loopback(0) }; | 360 | const localhost: net.IpAddress = .{ .ip4 = .loopback(0) }; |
| 363 | 361 |
lib/std/Io/test.zig-4| ... | @@ -232,8 +232,6 @@ fn count(a: usize, b: usize, result: *usize) void { | ... | @@ -232,8 +232,6 @@ fn count(a: usize, b: usize, result: *usize) void { |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | test "Group.cancel" { | 234 | test "Group.cancel" { |
| 235 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 236 | |||
| 237 | const global = struct { | 235 | const global = struct { |
| 238 | fn sleep(io: Io, result: *usize) Io.Cancelable!void { | 236 | fn sleep(io: Io, result: *usize) Io.Cancelable!void { |
| 239 | defer result.* = 1; | 237 | defer result.* = 1; |
| ... | @@ -326,8 +324,6 @@ test "Group materializes error.Cancel" { | ... | @@ -326,8 +324,6 @@ test "Group materializes error.Cancel" { |
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | test "Group task receives cancelation unknowingly" { | 326 | test "Group task receives cancelation unknowingly" { |
| 329 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 330 | |||
| 331 | const S = struct { | 327 | const S = struct { |
| 332 | io: Io, | 328 | io: Io, |
| 333 | err: ?Io.Cancelable!void, | 329 | err: ?Io.Cancelable!void, |
lib/std/Thread.zig+32-37| ... | @@ -1146,6 +1146,13 @@ const LinuxThreadImpl = struct { | ... | @@ -1146,6 +1146,13 @@ const LinuxThreadImpl = struct { |
| 1146 | parent_tid: i32 = undefined, | 1146 | parent_tid: i32 = undefined, |
| 1147 | mapped: []align(std.heap.page_size_min) u8, | 1147 | mapped: []align(std.heap.page_size_min) u8, |
| 1148 | 1148 | ||
| 1149 | // On SPARC, the kernel needs to be able to restore the current register window from the | ||
| 1150 | // stack when returning from a syscall. That presents a bit of a problem in `freeAndExit` | ||
| 1151 | // since we're deallocating the stack! The good news is that, since we do not care about | ||
| 1152 | // the contents of the incoming and local registers at that point, we can just tell the | ||
| 1153 | // kernel that our stack is this undefined global buffer. | ||
| 1154 | var sparc_exit_stack: [192]u8 align(16) = undefined; | ||
| 1155 | |||
| 1149 | /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`). | 1156 | /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`). |
| 1150 | /// Ported over from musl libc's pthread detached implementation: | 1157 | /// Ported over from musl libc's pthread detached implementation: |
| 1151 | /// https://github.com/ifduyue/musl/search?q=__unmapself | 1158 | /// https://github.com/ifduyue/musl/search?q=__unmapself |
| ... | @@ -1365,51 +1372,39 @@ const LinuxThreadImpl = struct { | ... | @@ -1365,51 +1372,39 @@ const LinuxThreadImpl = struct { |
| 1365 | [len] "{r5}" (self.mapped.len), | 1372 | [len] "{r5}" (self.mapped.len), |
| 1366 | ), | 1373 | ), |
| 1367 | .sparc => asm volatile ( | 1374 | .sparc => asm volatile ( |
| 1368 | \\ # See sparc64 comments below. | 1375 | \\ // See sparc64 comments below. |
| 1369 | \\ 1: | 1376 | \\ t 0x3 // ST_FLUSH_WINDOWS |
| 1370 | \\ cmp %%fp, 0 | 1377 | \\ mov %%g3, %%sp |
| 1371 | \\ beq 2f | 1378 | \\ mov %%g1, %%o0 |
| 1372 | \\ nop | 1379 | \\ mov %%g2, %%o1 |
| 1373 | \\ ba 1b | 1380 | \\ mov 73, %%g1 // SYS_munmap |
| 1374 | \\ restore | 1381 | \\ t 0x10 |
| 1375 | \\ 2: | 1382 | \\ mov 1, %%g1 // SYS_exit |
| 1376 | \\ mov %%g1, %%o0 // ptr | 1383 | \\ mov 0, %%o0 |
| 1377 | \\ mov %%g2, %%o1 // len | 1384 | \\ t 0x10 |
| 1378 | \\ mov 73, %%g1 // SYS_munmap | ||
| 1379 | \\ t 0x3 // ST_FLUSH_WINDOWS | ||
| 1380 | \\ t 0x10 | ||
| 1381 | \\ mov 1, %%g1 // SYS_exit | ||
| 1382 | \\ mov 0, %%o0 | ||
| 1383 | \\ t 0x10 | ||
| 1384 | : | 1385 | : |
| 1385 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), | 1386 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), |
| 1386 | [len] "{g2}" (self.mapped.len), | 1387 | [len] "{g2}" (self.mapped.len), |
| 1388 | [stack] "{g3}" (&sparc_exit_stack), | ||
| 1387 | : .{ .memory = true }), | 1389 | : .{ .memory = true }), |
| 1388 | .sparc64 => asm volatile ( | 1390 | .sparc64 => asm volatile ( |
| 1389 | \\ # SPARCs really don't like it when active stack frames | 1391 | \\ // Ensure that the kernel only has to flush the current register window. |
| 1390 | \\ # is unmapped (it will result in a segfault), so we | 1392 | \\ flushw |
| 1391 | \\ # force-deactivate it by running `restore` until | 1393 | \\ // Set up a fake stack for the syscall to restore l/i registers from. Local |
| 1392 | \\ # all frames are cleared. | 1394 | \\ // and incoming registers must be treated as effectively garbage past this |
| 1393 | \\ 1: | 1395 | \\ // instruction! |
| 1394 | \\ cmp %%fp, 0 | 1396 | \\ sub %%g3, 2047, %%sp |
| 1395 | \\ beq 2f | 1397 | \\ mov %%g1, %%o0 |
| 1396 | \\ nop | 1398 | \\ mov %%g2, %%o1 |
| 1397 | \\ ba 1b | 1399 | \\ mov 73, %%g1 // SYS_munmap |
| 1398 | \\ restore | 1400 | \\ t 0x6d |
| 1399 | \\ 2: | 1401 | \\ mov 1, %%g1 // SYS_exit |
| 1400 | \\ mov %%g1, %%o0 // ptr | 1402 | \\ mov 0, %%o0 |
| 1401 | \\ mov %%g2, %%o1 // len | 1403 | \\ t 0x6d |
| 1402 | \\ mov 73, %%g1 // SYS_munmap | ||
| 1403 | \\ # Flush register window contents to prevent background | ||
| 1404 | \\ # memory access before unmapping the stack. | ||
| 1405 | \\ flushw | ||
| 1406 | \\ t 0x6d | ||
| 1407 | \\ mov 1, %%g1 // SYS_exit | ||
| 1408 | \\ mov 0, %%o0 | ||
| 1409 | \\ t 0x6d | ||
| 1410 | : | 1404 | : |
| 1411 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), | 1405 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), |
| 1412 | [len] "{g2}" (self.mapped.len), | 1406 | [len] "{g2}" (self.mapped.len), |
| 1407 | [stack] "{g3}" (&sparc_exit_stack), | ||
| 1413 | : .{ .memory = true }), | 1408 | : .{ .memory = true }), |
| 1414 | .loongarch32, .loongarch64 => asm volatile ( | 1409 | .loongarch32, .loongarch64 => asm volatile ( |
| 1415 | \\ ori $a7, $zero, 215 # SYS_munmap | 1410 | \\ ori $a7, $zero, 215 # SYS_munmap |
lib/std/heap/PageAllocator.zig+1| ... | @@ -24,6 +24,7 @@ pub const vtable: Allocator.VTable = .{ | ... | @@ -24,6 +24,7 @@ pub const vtable: Allocator.VTable = .{ |
| 24 | /// that don't provide a hint (for security reasons, but it serves our needs | 24 | /// that don't provide a hint (for security reasons, but it serves our needs |
| 25 | /// too). | 25 | /// too). |
| 26 | const enable_hints = switch (builtin.target.os.tag) { | 26 | const enable_hints = switch (builtin.target.os.tag) { |
| 27 | .linux => !builtin.target.cpu.arch.isSPARC(), // https://bugzilla.kernel.org/show_bug.cgi?id=221820 | ||
| 27 | .openbsd => false, | 28 | .openbsd => false, |
| 28 | else => true, | 29 | else => true, |
| 29 | }; | 30 | }; |
lib/std/os/linux/sparc.zig+8-5| ... | @@ -260,13 +260,16 @@ pub fn clone() callconv(.naked) u32 { | ... | @@ -260,13 +260,16 @@ pub fn clone() callconv(.naked) u32 { |
| 260 | 260 | ||
| 261 | pub const restore = restore_rt; | 261 | pub const restore = restore_rt; |
| 262 | 262 | ||
| 263 | // Need to use C ABI here instead of naked | 263 | pub fn restore_rt() callconv(.naked) noreturn { |
| 264 | // to prevent an infinite loop when calling rt_sigreturn. | 264 | asm volatile ( |
| 265 | pub fn restore_rt() callconv(.c) void { | 265 | \\ nop |
| 266 | return asm volatile ("t 0x10" | 266 | \\ nop |
| 267 | ); | ||
| 268 | asm volatile ( | ||
| 269 | \\ t 0x10 | ||
| 267 | : | 270 | : |
| 268 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), | 271 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), |
| 269 | : .{ .memory = true, .xcc = true, .o0 = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | 272 | ); |
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | pub const VDSO = struct { | 275 | pub const VDSO = struct { |
lib/std/os/linux/sparc64.zig+8-5| ... | @@ -259,13 +259,16 @@ pub fn clone() callconv(.naked) u64 { | ... | @@ -259,13 +259,16 @@ pub fn clone() callconv(.naked) u64 { |
| 259 | 259 | ||
| 260 | pub const restore = restore_rt; | 260 | pub const restore = restore_rt; |
| 261 | 261 | ||
| 262 | // Need to use C ABI here instead of naked | 262 | pub fn restore_rt() callconv(.naked) noreturn { |
| 263 | // to prevent an infinite loop when calling rt_sigreturn. | 263 | asm volatile ( |
| 264 | pub fn restore_rt() callconv(.c) void { | 264 | \\ nop |
| 265 | return asm volatile ("t 0x6d" | 265 | \\ nop |
| 266 | ); | ||
| 267 | asm volatile ( | ||
| 268 | \\ t 0x6d | ||
| 266 | : | 269 | : |
| 267 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), | 270 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), |
| 268 | : .{ .memory = true, .xcc = true, .o0 = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | 271 | ); |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | pub const VDSO = struct { | 274 | pub const VDSO = struct { |