/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _GSP_SEMA_SERVICE_H_ #define _GSP_SEMA_SERVICE_H_ /* * Emulated-GPU progress service: discovers the guest's GPU-VA -> guest-PA * mapping and applies the copy-engine semaphore releases found in mapped * pages, so that the guest's UVM progress waits complete. * * See gsp_sema_service.c for the full description. */ /* * A guest channel, registered when the driver allocates it. The service uses * the channel's GPFIFO + USERD to notice submissions as they happen (instead * of discovering the pushed work by scanning guest RAM) and to run the pushed * work promptly. * * All addresses are guest-physical except gpfifo_va, which is the GPU VA of * the channel's GPFIFO ring (translated through the discovered VA->PA map). */ struct sema_channel_desc { u32 h_object; u32 engine_type; u32 cid; /* RM channel id (the doorbell token vector) */ u64 gpfifo_va; u32 gpfifo_entries; u64 userd_pa; /* NvA06FControl: GPGet @0x88, GPPut @0x8c */ u32 userd_as; /* NV_ADDR_SYSMEM(1) / NV_ADDR_FBMEM(2) */ u64 instance_pa; u64 notifier_pa; u32 notifier_as; /* NV_ADDR_SYSMEM(1) / NV_ADDR_FBMEM(2) */ }; void gsp_sema_service_channel_add(const struct sema_channel_desc *desc); void gsp_sema_service_channel_del(u32 h_object); /* * A GPU VA space whose top-level page directory the driver has published (the * driver builds its own page tables for the address spaces it owns, then hands * the directory's physical address to the GPU through SET_PAGE_DIRECTORY). * * pdb is the directory base in the aperture selected by b_vidmem (false = * guest RAM, true = emulated vidmem); num_entries is the root entry count and * fixes the number of VA bits the root covers. */ struct sema_vaspace_desc { u32 h_vaspace; u64 pdb; u32 num_entries; bool b_vidmem; }; void gsp_sema_service_vaspace_add(const struct sema_vaspace_desc *desc); void gsp_sema_service_vaspace_del(u32 h_vaspace); int gsp_sema_service_start(void); void gsp_sema_service_stop(void); int gsp_sema_service_probe(u64 gpu_va, u32 count); int gsp_sema_service_walk_probe(u64 gpu_va); int gsp_sema_service_dump_channels(void); int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap); int gsp_sema_service_dump_vidmem(u64 addr, u64 len); int gsp_sema_service_find_vidmem(u64 pattern, u64 max_hits); int gsp_sema_service_counter_add(u32 h_object, u64 pa); void gsp_sema_service_doorbell(u32 token); /* * P5 wave-1 shadow work lifetime hooks. The backend release path must call * gsp_sema_service_work_quiesce() before it frees the ladder buffers: it * pauses new shadow requests and waits (bounded by the submit's 200 ms poll * cap) for the in-flight one to finish, so no poll ever touches freed memory. * gsp_sema_service_work_resume() re-enables requests when a new backend * session starts. */ void gsp_sema_service_work_quiesce(void); void gsp_sema_service_work_resume(void); /* * P6b wave-1 guest-forwarding counters for the gsp-phys-state work_guest * line: guest-eligible requests seen by the pump, guest requests whose * hardware copy failed (wave 1: fell back to the ladder copy; with * gsp_phys_work_defer_release the service applies the held releases instead), * and verified hardware copies. Plain reads of the service counters; safe * from the debugfs show path. */ void gsp_sema_service_fwd_guest_stats(u64 *req, u64 *fallback, u64 *ok); /* * P6b wave-1 candidate accounting for the same work_guest line: how many * forwarding requests found no eligible captured copy, and of those that did, * the operand aperture mix (SYS/SYS, mixed, VID/VID), plus guest-work * resolution failures on the work item. All zero while the feature is off. */ void gsp_sema_service_fwd_cand_stats(u64 *none, u64 *sys_sys, u64 *mixed, u64 *vid_vid, u64 *resolve_fail); /* * P6b wave-1.5/wave-2 deferred-release and copy counters for the * gsp-phys-state work_guard line: copy_skipped (the software copy was * withheld because hardware-primary authorship is armed; always 0 when * gsp_phys_work_hw_primary=0), copy_soft (software fallback copies the * service thread performed before applying releases), copy_fail (fallback * copy attempts that failed), releases deferred until the hardware copy * completed, holds applied on completion (including a hold whose channel * vanished after a successful copy), holds applied because the copy failed / * timed out / forwarding was aborted, releases currently held (gauge), * deferred records dropped by the record bound, holds engaged, holds that hit * the timeout, and holds dropped unresolved after their channel vanished (no * successful copy had completed). All zero while the feature is off. Plain * reads, safe from the debugfs show path. */ void gsp_sema_service_fwd_hold_stats(u64 *copy_skipped, u64 *copy_soft, u64 *copy_fail, u64 *deferred, u64 *applied, u64 *fallback, u64 *pending, u64 *overflow, u64 *engaged, u64 *timeouts, u64 *canceled); /* * Discover and pin GR (compute) channel rings after the CE region of the * channel video-memory allocation. Set false to leave GR rings untranslated * (the pump then only runs the CE channels). */ extern bool gsp_sema_gr_rings; /* * Acknowledge tracking-semaphore releases from CE pushes the pump could not * read: write the expected payload into the channel's pool semaphore so the * driver's wait clears immediately instead of after the content sweep. */ extern bool gsp_sema_fake_rel; extern bool gsp_sema_rel_recover; /* * Master diagnostic switch for the per-push/per-doorbell/per-op tracing * (module parameter sema_dbg). Off by default so a healthy boot leaves the * kernel log quiet; the watch knobs below only take effect while it is on. */ extern bool gsp_sema_dbg; /* * Skip executing a push's collected work (CE memsets/copies) while still * applying its release; see the definition for the trade-off. */ extern bool gsp_sema_skip_ops; /* * How many executed CE ops to log with full operands (diagnostic bound; the * default keeps a healthy run quiet, raise it to audit a data path). */ extern unsigned gsp_sema_ops_log; /* * Data-path watch: for copies of exactly this many bytes, log the first 8 * source/destination bytes before the copy (0 = off). */ extern unsigned gsp_sema_copy_watch; /* Data-path watch: 8-byte value matched in copy src/dst and push bytes. */ extern u64 gsp_sema_copy_pat; /* Data-path watch: dump copies landing in this page (source bytes). */ extern u64 gsp_sema_copy_dst; /* Second destination window for the same watch (0 = off). */ extern u64 gsp_sema_copy_dst2; /* CE pending-entry grace window in ms before the release fallback fires. */ extern unsigned gsp_sema_ce_grace_ms; /* * Grace window (ms) an untranslatable GR GPFIFO entry is left pending before * the pump consumes it as stale. The GR push pages are pinned from guest * truth a moment after the channels appear; the window lets those pins land * so the releases inside the pushes are applied. */ extern unsigned gsp_sema_gr_grace_ms; #endif /* _GSP_SEMA_SERVICE_H_ */