code wiki / (root) / nx_gpu_sync_gate.nx

nx_gpu_sync_gate.nx source

↩ module page · 81 lines · 4805 B

1// nx_gpu_sync_gate.nx -- the sovereign GPU fence (nx_gpu_sync gpu_sync_fence) on the real device, driven directly. 2// 3// gpu GP7, the FENCE half: a monitored fence created on the discrete 5080 through raw /dev/dxg, signalled from the 4// CPU and waited on synchronously -- the round trip completes only when the signals advanced the real fence. 5// Teeth: the device resolves; the fence round-trips; an invalid sync-object type is REFUSED (the create is 6// type-sensitive, not a blind success); three tampers are rejected (a bogus handle, a zero object count, a non-dxg 7// fd); and a POSITIVE CONTROL after the tampers still round-trips, so this is not a guard that refuses everything. 8// THE THIRD STATE: the subject is a physical device most hosts lack (the NAS that builds this has no /dev/dxg). 9// Absent hardware is a gv_need precondition -> SKIP, never RED; a RED from this gate means the fence path broke. 10// The BARRIER half of GP7 is not claimed here (see nx_gpu_sync.nx); the board carries that scope. 11// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 (or 3 = SKIP where there is no /dev/dxg) 12import "nx_syscalls.nx" 13import "nx_dxg.nx" 14import "nx_gpu_sync.nx" 15import "nx_gate_verdict.nx" 16 17const GG_BAD_TYPE: i64 = 99 18const GG_BOGUS_SO: i64 = 0xdeadbeef 19 20func main() -> i64 { 21 let ctr: *i64 = gv_ctr() 22 gv_head("nx_gpu_sync_gate -- GP7 fence half: a monitored fence on the discrete 5080 through raw /dev/dxg, created, CPU-signalled, CPU-waited" as *u8) 23 24 let fd: i64 = dxg_open() 25 var have: i64 = 0 26 if fd >= 0 { have = 1 } 27 if gv_need("a /dev/dxg device to submit to (absent on every host but the GPU laptop)" as *u8, have, ctr) == 0 { 28 return gv_verdict("nx_gpu_sync_gate" as *u8, ctr, "subject absent: no /dev/dxg on this host" as *u8) 29 } 30 31 let dev: *i64 = sys_mmap(16) as *i64 32 let dr: i64 = gpu_sync_device(fd, dev) 33 gv_puts(" device resolve rc=" as *u8); gv_num(dr); gv_puts("\n" as *u8) 34 gv_check("T1-the-discrete-adapter-resolves-to-a-device-handle" as *u8, dr == 0, ctr) 35 if dr != 0 { 36 sys_close(fd) 37 return gv_verdict("nx_gpu_sync_gate" as *u8, ctr, "the device did not resolve; nothing below could run" as *u8) 38 } 39 let device: i64 = dev[0] 40 41 let so: *i64 = sys_mmap(16) as *i64 42 let fva: *i64 = sys_mmap(16) as *i64 43 let rt: i64 = gpu_sync_fence(fd, device, so, fva) 44 gv_puts(" fence round trip rc=" as *u8); gv_num(rt); gv_puts(" sync_object_nonzero=" as *u8) 45 var so_nz: i64 = 0 46 if so[0] != 0 { so_nz = 1 } 47 gv_num(so_nz); gv_puts(" fence_page_mapped=" as *u8) 48 var fva_nz: i64 = 0 49 if fva[0] != 0 { fva_nz = 1 } 50 gv_num(fva_nz); gv_puts("\n" as *u8) 51 gv_check("T2-the-monitored-fence-round-trips-create-signal-1-signal-2-wait-2" as *u8, rt == 0, ctr) 52 gv_check("T3-the-create-returned-a-real-sync-object-handle" as *u8, so_nz == 1, ctr) 53 gv_check("T4-the-create-mapped-a-kernel-fence-page-into-this-process" as *u8, fva_nz == 1, ctr) 54 55 // the create is type-sensitive: an invalid type must be refused 56 let bso: *i64 = sys_mmap(16) as *i64 57 let bfva: *i64 = sys_mmap(16) as *i64 58 let cr_bad: i64 = dxg_create_so(fd, device, GG_BAD_TYPE, bso, bfva) 59 gv_check("neg-control-T5-an-invalid-sync-object-type-is-refused-by-the-device" as *u8, cr_bad < 0, ctr) 60 61 // tampers: each from a different real rule, each must differ from the round trip's 0 62 let t1: i64 = dxg_wait_cpu(fd, device, GG_BOGUS_SO, 1) 63 let t2: i64 = dxg_signal_cpu(fd, device, so[0], 0, 1) 64 let nfd: i64 = sys_openat_rd("/dev/null" as *u8) 65 var t3: i64 = 0 66 if nfd >= 0 { t3 = dxg_wait_cpu(nfd, device, so[0], GS_FENCE_STEP2); sys_close(nfd) } 67 gv_puts(" tampers: wait-bogus-handle=" as *u8); gv_num(t1); gv_puts(" signal-count-0=" as *u8); gv_num(t2); gv_puts(" wait-on-non-dxg-fd=" as *u8); gv_num(t3); gv_puts("\n" as *u8) 68 gv_check("neg-control-T6-a-wait-on-a-bogus-handle-is-refused-not-blocked" as *u8, t1 < 0, ctr) 69 gv_check("neg-control-T7-a-signal-with-object-count-zero-is-refused" as *u8, t2 < 0, ctr) 70 gv_check("neg-control-T8-a-wait-on-a-non-dxg-fd-is-refused" as *u8, t3 < 0, ctr) 71 72 // positive control after the refusals: the channel still round-trips (not a guard that refuses everything) 73 let so2: *i64 = sys_mmap(16) as *i64 74 let fva2: *i64 = sys_mmap(16) as *i64 75 let rt2: i64 = gpu_sync_fence(fd, device, so2, fva2) 76 gv_check("T9-positive-control-a-second-fence-still-round-trips-after-the-refusals" as *u8, rt2 == 0, ctr) 77 gv_check("T10-the-second-fence-is-a-distinct-sync-object" as *u8, so2[0] != so[0], ctr) 78 79 sys_close(fd) 80 return gv_verdict("nx_gpu_sync_gate" as *u8, ctr, "the sovereign monitored fence round-trips on the 5080 through raw dxg; refusals are typed and the channel stays live" as *u8) 81}