summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.h
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 07:43:05 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 07:43:05 -0400
commitfe95eadb2bc1cb9af49814528edecbc5e497d6cd (patch)
treee6664933422202b4c9eae77446aa6431f457af66 /kernel/gsp_phys_booter.h
parent941ceedd33dcdbb34741af6c04865a7024e3e849 (diff)
downloadopen-iov-fe95eadb2bc1cb9af49814528edecbc5e497d6cd.tar.gz
open-iov-fe95eadb2bc1cb9af49814528edecbc5e497d6cd.zip
gsp-phys: P6c C0+C1 - engine-authored guest CE semaphore (default off)
New default-off gsp_phys_relay: for a forwarded guest CE copy whose push ends in a one-word release, the release page is resolved at forward time, mapped on a fresh scratch line, and the real engine writes the payload directly into the guest-visible semaphore page; the deferred-release hold then verifies that page and skips only that record's software apply. Any failure (unresolvable target, refused kind, pool exhaustion, poll timeout, data mismatch, channel teardown) falls back to applying every release in software, so a release is never lost or duplicated. - new exported gsp_phys_backend_guest_ce_copy_ex() + relay counters; gsp_phys_backend_guest_ce_copy() behavior unchanged (wrapper) - new work_relay: counters line in gsp-phys-state - relay limited to CE channels and one-word absolute releases; counter and reduction releases stay on the existing paths Live: param-off regression matched the wave-2 baseline exactly (req=101 ok=101 verify_ok=101, copy_skipped=119, smoke matched=64/64, relay zeros). With the parameter on: requested=68 ok=67 skipped_sw=67, verify_fail=0, resolve_fail=0, timeouts=0, smoke 64/64, and the engine-authored guest semaphore was observed directly (sem=0x00000003 / 0x0000007e at the guest page). One copy in 68 released its semaphore but failed the host-side data compare; it fell back to the software apply (fallback accounting applied+fallback==engaged) with the smoke green - residual to triage, which is why the parameter stays default-off. A forced-unresolvable run (requested=103, fallback=105, no relay submissions) kept the smoke green. Every cycle: 5 power-domain locks held, driver rebound, WPR2 down, no rail cycles, pstore empty, same boot.
Diffstat (limited to 'kernel/gsp_phys_booter.h')
-rw-r--r--kernel/gsp_phys_booter.h36
1 files changed, 36 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.h b/kernel/gsp_phys_booter.h
index ada3280..408d380 100644
--- a/kernel/gsp_phys_booter.h
+++ b/kernel/gsp_phys_booter.h
@@ -235,12 +235,48 @@ void gsp_phys_backend_work_counters(u64 *submitted, u64 *released,
* gsp_phys_backend_guest_counters() reads the booter-side guest counters
* (verified copies, direct-map verifies, verify failures, pool exhaustion,
* refusals including poll timeouts) for logging and the state file.
+ *
+ * P6c completion relay (gsp_phys_relay=1; default off):
+ * gsp_phys_backend_guest_ce_copy_ex() is the same copy with an optional
+ * guest-visible release relay: a nonzero sem_hpa (page aligned) makes the
+ * submission map that page as a third PTE on the same fresh 128 B line and
+ * point the CE release methods at sem_va + sem_off with sem_payload; the
+ * caller's page is pinned for the duration (pfn_valid -> get_page/put_page)
+ * and the poll watches __va(sem_hpa) + sem_off for the exact payload instead
+ * of the module ladder semaphore. *out (if given) always carries the last
+ * semaphore word observed, the elapsed milliseconds and the return code. A
+ * zero sem_hpa keeps the module-semaphore behavior byte-identical.
+ * gsp_phys_backend_guest_ce_copy() is a wrapper for the zero-relay form.
*/
int gsp_phys_backend_guest_ce_copy(u64 src_hpa, u32 src_off, u64 dst_hpa,
u32 dst_off, u32 bytes, u32 poll_ms);
void gsp_phys_backend_guest_counters(u64 *ok, u64 *verify_ok, u64 *verify_fail,
u64 *pool_exhausted, u64 *refused);
+/* Result of one guest CE copy (see the P6c note above). */
+struct gsp_phys_backend_copy_result {
+ u32 sem_value; /* last word observed at the polled semaphore */
+ u32 elapsed_ms; /* return-to-caller elapsed milliseconds */
+ int rc; /* duplicated function return code */
+};
+
+int gsp_phys_backend_guest_ce_copy_ex(u64 src_hpa, u32 src_off, u64 dst_hpa,
+ u32 dst_off, u32 bytes, u32 poll_ms,
+ u64 sem_hpa, u32 sem_off,
+ u32 sem_payload,
+ struct gsp_phys_backend_copy_result *out);
+
+/*
+ * gsp_phys_backend_relay_counters() reads the P6c relay-path counters
+ * (requested relay copies, verified relays, data verify failures, guest
+ * semaphore poll timeouts, gate/structural refusals and scratch-pool
+ * exhaustion) for logging and the gsp-phys-state work_relay line. All zero
+ * unless gsp_phys_relay=1 copies ran.
+ */
+void gsp_phys_backend_relay_counters(u64 *requested, u64 *ok, u64 *verify_fail,
+ u64 *timeouts, u64 *refused,
+ u64 *pool_exhausted);
+
/*
* Command-queue TX: build a msgq record with the 570.144 element/rpc header
* layout, splitting it into 1..16 4 KB elements when it does not fit one