1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# The Execution Frontier
> **What this page is.** The current leading edge of guest-facing execution:
> the chain that must fire for a stock guest CUDA kernel to run on the
> physical GPU, what has been proven about it, where it stops, how we know,
> and the open lines of investigation and theories. It is evidence-led: every
> statement carries a live observation, a decompilation finding, or a clearly
> labelled theory. Condensed from
> [`../docs/04-implementation/03-execution-frontier.md`](../docs/04-implementation/03-execution-frontier.md);
> the docs tree wins on disagreement.
Status: 2026-10-12 (source page dated 2026-10-06), tree `master @ 2f066727`.
Tags: `[live]` observed; `[wip]` partial; `[wall]` current blocker; theories
are labelled as such.
## 1. The chain that should fire
A guest CUDA launch becomes a **method stream** in a push buffer, referenced
by a **GPFIFO ring entry**, announced by a **doorbell**. The host emulation
decodes it and forwards an equivalent method stream to a real channel owned by
the module's resource-manager session. The hardware **front-end** fetches and
executes the methods, the launch descriptor (**QMD**) is materialised and read
by the **GR engine**, the grid is dispatched to the SMs, and completion is
published as **semaphores** the guest waits on.
```text
guest: builds launch + method stream
GPFIFO entry + doorbell
-> host: doorbell trap, decode, rebuild forward stream,
prewrite QMD, ring/USERD, doorbell
-> front-end: fetch GPFIFO entry (ring cursor advances)
-> front-end: execute methods (object bind, cache ops, report sem)
-> front-end: install inline QMD into the descriptor buffer
-> GR engine: read QMD through the channel's page tables
-> context switch loads the channel context (FECS/ucode)
-> GR: dispatch grid to the SMs
-> engine authors release semaphore + channel semaphore
-> host polls release, relays to guest; CUDA wakes
```
| # | Stage | State |
|---|---|---|
| 1 | Guest builds launch + method stream | `[live]` observed (stock driver, unmodified) |
| 2 | GPFIFO entry + doorbell | `[live]` observed |
| 3 | Host decode + forward stream + QMD prewrite + ring/USERD | `[live]` observed |
| 4 | Front-end fetches the ring entry | `[live]` observed (ring cursor advances) |
| 5 | Front-end executes methods | `[live]` observed (object bind, cache ops, report semaphore) |
| 6 | **Inline-QMD install** (descriptor materialised) | `[wall]` not observed |
| 7 | **Engine reads the QMD** | `[wall]` not observed |
| 8 | Context switch loads the channel context | `[live]` context validity at dispatch is ruled in |
| 9 | GR dispatches the grid to the SMs | never observed on this stack |
| 10 | Engine authors release + channel semaphore | absent for forwarded launches |
| 11 | Host relays completion; guest wakes | the guest waits and times out |
**One-line summary:** the guest, the emulation, the forwarding path and the
front-end are live; the **launch-descriptor install path** (stages 6–7) is the
leading edge, and with it stages 9–11.
## 2. Where the leading edge is
A stock guest program now reaches its kernel launch and submits it through the
forwarding path. On the wire the ring entry is consumed and the front-end
methods run — but the launch descriptor is never materialised, the engine
never reads a QMD, no engine-authored completion appears, and the guest blocks
in its synchronisation wait.
This is **not** a context-validity wall (ruled out at dispatch) and **not** a
window-mapping wall for the descriptor destination (that install is accepted).
The wall is the **form of the launch method stream**: what the front-end
requires in order to install the inline descriptor, and what the engine
requires in order to read and dispatch it.
## 3. How we know (observables and their limits)
| Observable | What it proves | What it does not prove |
|---|---|---|
| Ring entry consumed; ring cursor advances | the front-end is alive and fetching | nothing about the engine |
| Method execution on the ladder channel | the front-end can execute the method vocabulary | **not** engine execution — these signals can be front-end-authored |
| Descriptor buffer prewritten with a detectable sentinel | whether the descriptor was materialised after submission | a read does not modify memory; the sentinel detects installs, not reads |
| Install sentinel unchanged after submit | the inline-install method did not run | it does not say why |
| Engine-authored release word absent; poll times out | the engine did not complete the launch | it does not say whether the engine started |
| No GR fault recorded | the engine did not raise this error | silence is not health: a skipped launch is silent by construction |
| Channel instance context flag set | the channel is context-valid at dispatch | nothing about the descriptor path |
**Consequence:** progress on this frontier must be measured by an
**engine-authored** signal (the release word advancing) — not by front-end
signals, which we have already learned to distinguish.
## 4. What is exonerated (do not relitigate)
* Context validity at dispatch — the channel's context is valid when the
launch is submitted (instance flag set).
* The descriptor destination window mapping — installed in the engine's table
view at submit.
* Front-end fetch and control-block alignment — the entry is consumed with the
host control block at offset 0.
* The shared context-buffer one-shot rule — traced to a shared per-GPU buffer
already initialised in the same cycle; not the dispatch delta.
* Parenting/TSG for the fetch — both variants fetch identically.
* The copy-engine path — CE-class work, releases and fault relay are live
(default off); the GR path is a separate problem.
## 5. The clear issues (ranked)
**Issue A — the forwarded stream carries a verbatim guest prelude that cannot
complete.** The forwarded stream includes a verbatim copy of the guest's
prelude whose inline-data writes target addresses not present in the engine's
view of the channel's page tables, and the referenced data is not relocated.
The shorter, proven stream shape fires its tail (channel semaphore) but still
does not schedule the descriptor.
**Issue B — the descriptor-virtualization control method is absent.** The
method that arms the inline-descriptor install path is not present in the
forwarded stream. Fixing it should materialise the descriptor — falsifiable in
one cycle by watching the sentinel and the engine-read signal.
**Issue C — diagnostic hygiene.** The sentinel placed at word 0 overlaps real
descriptor fields; it must be moved to an unused word so diagnostics do not
perturb what they measure.
## 6. Lines of investigation (live)
1. **Restore the proven launch shape** as the baseline and **re-add the
virtualization control method** — one variable at a time, with the install
sentinel and the engine-read signal as the readout.
2. **Relocate or drop the verbatim prelude** so inline-data writes target
addresses present in the engine's view, or replace it with the host-side
staging the proven shape already uses.
3. **Move the sentinel** and re-run to confirm the readout is clean.
4. **Diff against a known-good reference** — our own ladder dispatching a
descriptor built from the same source material, or a captured working
launch of the stock stack on the same GPU — converting the remaining work
from inference to differential.
5. **Offline probing** of any rule the front-end or engine is believed to
require, using the firmware debugger before spending a supervised cycle
([`Riscv-GSP-RM-Debugger.md`](Riscv-GSP-RM-Debugger.md)).
## 7. Theories (labelled; not yet proven)
* **T1 — the virtualization control is the gate.** The front-end will not
materialise an inline descriptor until the control method enables the
install path.
* **T2 — materialise-then-read.** The engine only schedules a descriptor that
exists in its own view; an install targeting unmapped destinations aborts
silently rather than faulting.
* **T3 — the verbatim prelude poisons the launch.** Its refused writes leave
the launch path unable to schedule the descriptor.
* **T4 — relocation is the missing transform.** The guest's descriptor is
valid for the guest's view of memory; the forwarding path must relocate
referenced data into the channel's view before install.
Each theory has a one-cycle falsifier: the install sentinel, the engine-read
signal, and the engine-authored release, in that order.
## 8. Claim discipline
* **Engine-authored release is the only proof of execution.** Front-end
signals are necessary but not sufficient.
* **Silence is not health.** No fault recorded does not mean no fault
occurred.
* **Emulator verdicts are instruction/memory-level.** They bound behaviour,
never timing or device environment.
* **A wall is closed only by an acceptance signal**, named before the
experiment.
## 9. Related pages
* [`Project-Status.md`](Project-Status.md) — the project-level ladder.
* [`CUDA-Userspace-Driver.md`](CUDA-Userspace-Driver.md) — the guest-side
client path.
* [`Physical-GPU-Backend.md`](Physical-GPU-Backend.md) — the backend the work
is forwarded to.
* [`Execution-Plane.md`](Execution-Plane.md) — the execution layer's design.
* [`Introduction-to-GMMU.md`](Introduction-to-GMMU.md) — page tables, QMDs and
the engines.
* [`../docs/04-implementation/03-execution-frontier.md`](../docs/04-implementation/03-execution-frontier.md) —
the canonical, continuously-updated version with the full evidence tables.
|