summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.h
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 10:40:54 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 10:40:54 -0400
commit017e29adbe8f00e3e500df2ad3b404c2d2896866 (patch)
tree56ac0f2ffbb540ac104e98313f0db19def91a361 /kernel/gsp_phys_booter.h
parentc21f7099a8544b35628a7e104f02c5335a08d79d (diff)
downloadopen-iov-017e29adbe8f00e3e500df2ad3b404c2d2896866.tar.gz
open-iov-017e29adbe8f00e3e500df2ad3b404c2d2896866.zip
gsp-phys: harden the RM transport and add the static-info probe
Applies the adversarial review fixes for the command-queue TX and unload RPC: the unload RPC is gated on GSP-RM init-done, debugfs fops pin the module, REG_POLL timeouts use microseconds, the host status readPtr is published, TX free space is checked, swap flags and barriers are corrected, and the legacy payload fallback is opt-in. Generalizes the transport to multi-element records and a reply-matching status-queue reader, and adds a debugfs probe that round-trips GET_GSP_STATIC_INFO (with a SET_GUEST_SYSTEM_INFO fallback), decodes the server configuration, and a read-only state snapshot file. All gated by gsp_phys_boot; the normal load path is unchanged.
Diffstat (limited to 'kernel/gsp_phys_booter.h')
-rw-r--r--kernel/gsp_phys_booter.h59
1 files changed, 43 insertions, 16 deletions
diff --git a/kernel/gsp_phys_booter.h b/kernel/gsp_phys_booter.h
index a669bf3..7ed1635 100644
--- a/kernel/gsp_phys_booter.h
+++ b/kernel/gsp_phys_booter.h
@@ -71,11 +71,13 @@ void gsp_phys_boot_rmwait(struct gsp_phys_boot *boot, void __iomem *bar0,
/*
* Release sequence, in this order (gsp_phys_gpu_release):
- * 0. gsp_phys_boot_rm_unload(): if stage 3d ran and the
+ * 0. gsp_phys_boot_rm_unload(): if stage 3d ran, the GSP-RM init-done
+ * event (function 0x1001 with rpc_result 0) was observed, and the
* UNLOADING_GUEST_DRIVER RPC has not been submitted yet, submit it once
* (bounded) and wait for the GSP-RM processor suspend so the scratch14
* handoff bit the Booter Unload gate needs can be set; a no-op when
- * stage 3d did not run or the RPC was already sent in this boot;
+ * stage 3d did not run, init-done was never seen (an RPC before
+ * init-done can be dropped) or the RPC was already sent in this boot;
* 1. gsp_phys_boot_quiesce(): if a Booter Load kick was issued, reset the
* GSP falcon (stops RISC-V/GSP-RM) BEFORE the FWSEC teardown runs; no
* device access when bar0 is NULL (unresponsive-board abort);
@@ -88,12 +90,18 @@ void gsp_phys_boot_quiesce(void __iomem *bar0);
void gsp_phys_boot_staging_free(struct pci_dev *pdev);
/*
- * Command-queue TX: build a single-element msgq record with the 570.144
- * element/rpc header layout, compute the XOR-fold checksum, copy it into the
- * next command-queue slot, publish the new writePtr with a DMA barrier and
- * ring the GSP queue-head doorbell. Requires the stage-3d command-queue
- * staging; bounded and refuses (with a log) when the TX header does not match
- * what was staged. Does not touch WPR2 or the falcons.
+ * 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
+ * (reference elemCount = ceil((48 + rpc.length) / 4096), each element copied
+ * to its own slot, checksum folded over the whole record up to the
+ * 8-byte-aligned length), validate the peer command read pointer
+ * (status+rxHdrOff when the status header carries MSGQ_FLAGS_SWAP_RX, else
+ * cmd+rxHdrOff) and the peer-derived free space, copy the record into the
+ * next command-queue slot(s), publish the new writePtr under wmb() and ring
+ * the GSP queue-head doorbell. Requires the stage-3d command-queue staging;
+ * bounded and refuses (with a log) when the TX header does not match what was
+ * staged or the ring cannot hold elemCount free elements. Does not touch WPR2
+ * or the falcons.
*/
int gsp_phys_queue_tx_submit(void __iomem *bar0, u32 function,
const void *payload, u32 payload_len);
@@ -106,18 +114,37 @@ int gsp_phys_queue_tx_submit(void __iomem *bar0, u32 function,
* Sends at most once per boot (tracked across release and the debugfs
* trigger). Returns 0 only when the suspend was observed and all four
* scratch14 handoff bits (24..27) read DONE, -EALREADY if already sent,
- * -EINVAL when stage 3d did not run, -ETIMEDOUT on the suspend bound and
- * -EIO when the handoff bits are not all DONE after the suspend. Never writes
- * WPR2.
+ * -EINVAL when stage 3d did not run or GSP-RM init-done (function 0x1001,
+ * rpc_result 0) was never observed (an RPC before init-done can be dropped),
+ * -ETIMEDOUT on the suspend bound and -EIO when the handoff bits are not all
+ * DONE after the suspend. Never writes WPR2.
*/
int gsp_phys_boot_rm_unload(void __iomem *bar0);
/*
- * Module-owned debugfs trigger (dir "open-iov-vfio", file
- * "gsp-phys-unload-rpc", write-only). Writing "1" runs
- * gsp_phys_boot_rm_unload() on a live claim; every other value or state
- * (parameter off, GPU unclaimed, stage 3d not run, already submitted) is a
- * logged no-op. Registered by nv_vgpu_init() and removed by nv_vgpu_exit().
+ * Module-owned debugfs files (dir "open-iov-vfio"), registered by
+ * nv_vgpu_init() and removed by nv_vgpu_exit(). All file_operations carry
+ * .owner = THIS_MODULE so an open fd pins the module:
+ * - "gsp-phys-unload-rpc" (write-only, mode 0200): writing "1" runs
+ * gsp_phys_boot_rm_unload() on a live claim; every other value or state
+ * (parameter off, GPU unclaimed, stage 3d not run, init-done not
+ * observed, already submitted) is a logged no-op.
+ * - "gsp-phys-rm-probe" (write-only, mode 0200): writing "1" runs one host
+ * RM probe cycle on a live, init-done claim: GET_GSP_STATIC_INFO
+ * (function 65, 4-byte request), and when no reply arrives,
+ * SET_GUEST_SYSTEM_INFO (function 1, 792-byte version payload) once
+ * followed by one GET_GSP_STATIC_INFO retry. Serialised with the unload
+ * trigger by the same mutex and bounded by the per-wait timeouts; never
+ * sends when init-done was not observed and never touches WPR2. The
+ * static-info reply is decoded into dmesg (internal handles, split-VA
+ * flag, BAR1/2 PDE bases, FB geometry, engine caps, SRIOV/board fields).
+ * - "gsp-phys-state" (read-only, mode 0444): seq_file snapshot of the
+ * claimed/booted state (falcon registers, scratch14, both queue TX
+ * headers, a bounded read-only status-ring walk, the stage flags and the
+ * last RM probe result). It returns a one-line status instead of
+ * touching hardware when the device is not claimed or the stage-3d
+ * staging is not primed, never writes and never advances the host
+ * status-queue readPtr (no consumption).
*/
int gsp_phys_boot_debugfs_init(void);
void gsp_phys_boot_debugfs_fini(void);