code wiki / _hdl_build / _gpu_dxg_submit_gate.nx
_gpu_dxg_submit_gate.nx
buildroot/runtime/_hdl_build/_gpu_dxg_submit_gate.nx
about
_gpu_dxg_submit_gate.nx -- SOVEREIGN-GPU ladder R5 (a REAL command submission ACCEPTED by the 5080).
R4f pinned allocations resident. This rung drives LX_DXSUBMITCOMMAND itself: a well-formed submission
carrying a mapped, resident pushbuffer GPU-VA and a resolved context, accepted by dxgkrnl on the real
discrete RTX 5080 -- wrapper-free, no libcuda / libvulkan / libd3d12 / libdxcore / libc.
THE ABI WAS MEASURED, NOT GUESSED. Two recon sweeps established it against the live device:
* ioctl SIZE: sweeping the size field with broadcast_context_count=0 (which cannot start GPU work, so
it cannot TDR), exactly ONE size answers -EINVAL (recognised, contents rejected) while every other
size answers -ENOTTY (unknown ioctl). That size is 384 => SUBMIT_CODE 0xC180470F.
* FIELD OFFSETS: with command_length=0 (a no-op submit: well-formed, the GPU executes 0 bytes), only
the layout whose count and context fields are both correct lets the context RESOLVE and returns 0;
every wrong layout leaves the count zero or the context unresolved and returns -EINVAL. Exactly one
of five candidate layouts answered 0: broadcast_context_count@0x18, broadcast_context[0]@0x1c.
GREEN iff (author=organ, every value from a REAL device return):
A) the full chain resolves: enum -> discrete adapter -> device -> context -> paging queue ->
EXISTINGHEAP allocation -> GPU VA -> resident;
B) SUBMIT ret == 0 (dxgkrnl ACCEPTED the submission);
C) the accept is REPEATABLE -- the mechanism, not a one-shot;
D) TAMPER matrix, each from a DIFFERENT real rule, every one differing from the real ret==0:
T1 count at the WRONG offset (0x14) -> context never resolves;
T2 bogus context handle -> real validation rejects;
T3 correct struct but the WRONG ioctl size (392) -> -ENOTTY from the size-encoded command number;
T4 the same well-formed submit on a NON-dxg fd (/dev/null) -> -ENOTTY.
T3 and T4 together are what stop "any ioctl returns 0" from passing as an accept.
E) a POSITIVE CONTROL after the tampers: the channel still accepts, so this is not a guard that
refuses everything once poked.
SCOPE -- READ THIS BEFORE QUOTING THE GREEN. command_length is 0, so THE GPU EXECUTES ZERO BYTES. This
rung proves the SUBMISSION CHANNEL accepts a well-formed command with a resolved context and a resident
pushbuffer. It proves NO throughput, NO kernel execution, and NO speedup, because a zero-length buffer
contains no instructions. Running actual work needs NVIDIA Blackwell ISA (SASS) encoded into that
pushbuffer -- that is the next rung and it is NOT claimed here. A green here that was read as "we run
compute on the 5080" would be exactly the false-green this gate is shaped to prevent.
⚠RUN IT ON THE HOST THAT HOLDS THE GPU. The build root has no /dev/dxg; the gate reports UNOBSERVABLE
and exits CLEAN there, so a RED from this gate always means the GPU path actually broke.
license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_gate_verdict.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 43 | const ENUM2_CODE: i64 = 0xC0104714 |
| 44 | const QAI_CODE: i64 = 0xC0184709 |
| 45 | const OAFL_CODE: i64 = 0xC00C4701 |
| 46 | const CDEV_CODE: i64 = 0xC0404702 |
| 47 | const CCV_CODE: i64 = 0xC0284704 |
| 48 | const CPQ_CODE: i64 = 0xC0204707 |
| 49 | const CALLOC_CODE: i64 = 0xC0484706 |
| 50 | const MAPVA_CODE: i64 = 0xC068470C |
| 51 | const MKRES_CODE: i64 = 0xC030470B |
| 53 | const SUBMIT_CODE: i64 = 0xC180470F |
| 55 | const SUBMIT_BADSIZE_CODE: i64 = 0xC188470F |
| 57 | const SUB_COUNT_OFF: i64 = 0x18 |
| 58 | const SUB_CTX_OFF: i64 = 0x1c |
| 59 | const SUB_BAD_COUNT_OFF: i64 = 0x14 |
| 60 | const EXISTINGHEAP_FLAGS: i64 = 0x10020 |
| 61 | const HEAP_BYTES: i64 = 65536 |
| 62 | const GPU_VA_BASE: i64 = 0x10000000000 |
functions
| 64 | func rd32(buf: *u8, off: i64) -> i64 { return (buf[off] as i64)|((buf[off+1] as i64)<<8)|((buf[off+2] as i64)<<16)|((buf[off+3] as i64)<<24) } |
| 65 | func rd64(buf: *u8, off: i64) -> i64 { let q: *i64 = (buf as i64 + off) as *i64; return q[0] } |
| 66 | func setu32(buf: *u8, off: i64, val: i64) -> i64 { let w: *u8 = (buf as i64 + off) as *u8; w[0]=(val&0xff) as u8; w[1]=((val>>8)&0xff) as u8; w[2]=((val>>16)&0xff) as u8; w[3]=((val>>24)&0xff) as u8; return 0 } |
| 67 | func setu64(buf: *u8, off: i64, val: i64) -> i64 { let q: *i64 = (buf as i64 + off) as *i64; q[0]=val; return 0 } |
| 68 | func zerobuf(n: i64) -> *u8 { let b: *u8 = sys_mmap(n); var i: i64 = 0; while i < n { b[i] = 0 as u8; i = i + 1 } return b } |
| 70 | func query_type(fd: i64, handle: i64, qtype: i64, psize: i64, outv: *i64) -> i64 |
| 78 | func open_from_luid(fd: i64, luid_lo: i64, luid_hi: i64, outh: *i64) -> i64 |
| 83 | func create_device(fd: i64, adapter: i64, outd: *i64) -> i64 |
| 88 | func create_ctx(fd: i64, device: i64, outc: *i64) -> i64 |
| 93 | func create_pq(fd: i64, device: i64, outpq: *i64, outfva: *i64) -> i64 |
| 98 | func alloc_eh(fd: i64, device: i64, sysmem: *u8, outh: *i64) -> i64 |
| 108 | func map_va(fd: i64, pq: i64, alloc: i64, outva: *i64) -> i64 |
| 114 | func makeresident(fd: i64, pq: i64, alloc_handle: i64) -> i64 |
| 123 | func submit_at(fd: i64, code: i64, cmdbuf: i64, len: i64, count_off: i64, ctx_off: i64, context: i64) -> i64 |
| 130 | func main() -> i64 |