summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c44
-rw-r--r--kernel/gsp_sema_service.h6
-rw-r--r--kernel/main.c9
3 files changed, 58 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 97c41d7..343684b 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -729,6 +729,8 @@ struct sema_svc {
u64 op_tr_log; /* operand targeted-resolve budget */
u32 op_tr_pending; /* an operand's targeted scan is in progress */
u64 copy_watch_log; /* sema_copy_watch log budget */
+ u64 copy_dst_hold; /* m169: device-dst copies held for
+ * want of a pin (stale-table guard) */
u64 copy_pat_log; /* sema_copy_pat log budget */
u64 copy_dst_log; /* sema_copy_dst log budget */
u32 op_tr_src; /* provenance of last svc_op_translate */
@@ -4554,6 +4556,30 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
dst_virt = true;
}
}
+ /*
+ * m169 (AGENT-F R1): a device-lane destination translated only by a
+ * page-directory walk (prov 3/4) or the RAM scan (5) can be a stale
+ * PTE from the previous session - the table CONTENT is not wiped by
+ * the session flush - and a wrong-but-valid vidmem write is silent.
+ * r172 streams2_diag: the stream-1 a H2D ran rc=0 through a
+ * walk-resolved destination while the launch (pin-resolved) read the
+ * true page still holding the previous client's h_a; the engine
+ * computed from stale inputs and the client verified 32768 bad.
+ * Since the resolver tries pins FIRST, prov >= 3 means no pin existed
+ * at resolve time: hold the copy (-ENOENT feeds the m163 bounded
+ * hold), which re-decodes after the client's pins land (seconds) and
+ * is loud on expiry - never silent corruption. Device destinations
+ * only; sysmem copies keep the historical sources.
+ */
+ if (dst_virt && dst_aperture == CE_APERTURE_VID &&
+ dst_prov >= 3 && dst_orig >= SVC_VAS_FLOOR &&
+ gsp_sema_copy_dst_pin_guard) {
+ svc.copy_dst_hold++;
+ if (svc.copy_dst_hold <= 16)
+ pr_info("sema-svc: device-dst copy held: dst=0x%llx prov=%u (no pin yet; stale-table guard)\n",
+ dst_orig, dst_prov);
+ return -ENOENT;
+ }
if (!src_phys) {
u64 pa;
u32 aper;
@@ -4581,7 +4607,8 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
* 16 bytes on each side before the copy. The vadd data path is exactly
* these copies; this separates a wrong resolution from a wrong copy.
*/
- if (total >= (1u << 20) && bigcopy_log < 24) {
+ if ((total >= (1u << 20) ||
+ (dst_virt && dst_orig >= SVC_VAS_FLOOR)) && bigcopy_log < 24) {
u8 sb[16] = {0}, db[16] = {0};
bigcopy_log++;
@@ -7581,6 +7608,14 @@ static void svc_session_flush(void)
svc.entry_log = 0;
svc_pushalt_log = 0;
/*
+ * m169: the op-trace budget is session state too. Left un-reset, the
+ * first client of a boot spends it and the failing client's copy ops
+ * are invisible in exactly the runs that need them (r172: streams2's
+ * H2D evidence was blacked out because the shared budget was spent at
+ * 29704, before the client ran).
+ */
+ svc.op_trace_log = 0;
+ /*
* Per-entry/stream decode diagnostics are per-session: the first
* client otherwise spends them and the second client's CE->GR
* transition is invisible (r24-r30: c2's follow-up pushes never
@@ -9595,6 +9630,13 @@ unsigned gsp_sema_gr_nocap_hold_ms = 6000;
bool gsp_sema_pool_hold_fresh = 1;
/*
+ * m169 (AGENT-F R1): hold device-destination copies whose only
+ * translation is a page-directory walk or RAM scan (no pin). Default on;
+ * 0 restores the historical immediate-write behavior.
+ */
+bool gsp_sema_copy_dst_pin_guard = 1;
+
+/*
* CE release fallback: when a push carrying a tracking-semaphore release
* cannot be read (and the content rescue failed), advance the channel's
* tracking semaphore to the expected payload directly. The push's data
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index ede8fa0..e0f1587 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -275,4 +275,10 @@ extern unsigned gsp_sema_gr_nocap_hold_ms;
*/
extern bool gsp_sema_pool_hold_fresh;
+/*
+ * m169 (AGENT-F R1): hold device-destination copies translated only by a
+ * walk/RAM scan until a pin confirms (default on).
+ */
+extern bool gsp_sema_copy_dst_pin_guard;
+
#endif /* _GSP_SEMA_SERVICE_H_ */
diff --git a/kernel/main.c b/kernel/main.c
index c4e4792..d2dc57a 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2789,6 +2789,15 @@ module_param_named(sema_pool_hold_fresh, gsp_sema_pool_hold_fresh, bool, 0644);
MODULE_PARM_DESC(sema_pool_hold_fresh, "apply pool releases at fresh-pin time instead of registration+5s (default 1)");
/*
+ * m169 (AGENT-F R1): hold device-destination copies translated only by a
+ * page-directory walk until a pin confirms (default on). A wrong-but-valid
+ * stale table entry silently writes the wrong vidmem page; the hold lets
+ * the m163 retry path re-resolve with pins.
+ */
+module_param_named(sema_copy_dst_pin_guard, gsp_sema_copy_dst_pin_guard, bool, 0644);
+MODULE_PARM_DESC(sema_copy_dst_pin_guard, "hold device-dst copies without a pin-resolved translation (default 1)");
+
+/*
* Debug: inject a verified {GPU VA -> guest PA} translation into the
* semaphore service (used when the client's mapping cannot be discovered
* from guest structures):