summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c56
-rw-r--r--kernel/gsp_sema_service.h1
-rw-r--r--kernel/main.c31
3 files changed, 85 insertions, 3 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index b311c0d..7bb7440 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -1838,6 +1838,17 @@ void gsp_sema_service_vaspace_candidate_add(u32 h_vaspace, u64 pdb,
* the lesser evil; it is logged loudly for the record.
*/
#define SVC_VAS_CAND_AGE_MS 15000u
+/*
+ * r705h: the candidate age-out deadline is runtime-tunable. The parked
+ * COPY_SERVER_PDES candidate for the GL/Vulkan client ages out (UNVERIFIED)
+ * at exactly the moment the client's channels first register, so the
+ * content-verified walk can never anchor it; raising the deadline keeps the
+ * candidate parked until a host tool supplies a verified ring pair via
+ * sema_pdb_discover. 0 disables the age-out entirely.
+ */
+static u32 svc_vas_cand_age_ms = SVC_VAS_CAND_AGE_MS;
+module_param_named(sema_vas_cand_ms, svc_vas_cand_age_ms, uint, 0644);
+MODULE_PARM_DESC(sema_vas_cand_ms, "Parked-VAS-candidate age-out (ms, default 15000; 0 = never)");
static void svc_vas_candidates_age_out(struct nv_vgpu_device *vgpu)
{
@@ -1848,8 +1859,9 @@ static void svc_vas_candidates_age_out(struct nv_vgpu_device *vgpu)
if (!svc_vas_cand[i].valid)
continue;
- if (time_before(jiffies, svc_vas_cand[i].stamp +
- msecs_to_jiffies(SVC_VAS_CAND_AGE_MS)))
+ if (!svc_vas_cand_age_ms ||
+ time_before(jiffies, svc_vas_cand[i].stamp +
+ msecs_to_jiffies(svc_vas_cand_age_ms)))
continue;
memset(&d, 0, sizeof(d));
d.h_vaspace = svc_vas_cand[i].h_vaspace;
@@ -1857,7 +1869,7 @@ static void svc_vas_candidates_age_out(struct nv_vgpu_device *vgpu)
d.num_entries = svc_vas_cand[i].entries;
d.b_vidmem = svc_vas_cand[i].vidmem;
pr_warn("sema-svc: VAS 0x%x page directory registered UNVERIFIED after %u ms parked (pdb=0x%llx entries=%u; the content-verified ring walk never anchored this boot)\n",
- d.h_vaspace, SVC_VAS_CAND_AGE_MS, d.pdb,
+ d.h_vaspace, svc_vas_cand_age_ms, d.pdb,
d.num_entries);
gsp_sema_service_vaspace_add(&d);
svc_vas_cand[i].valid = false;
@@ -15621,6 +15633,35 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu,
}
/*
+ * r705h: host-triggered pdb discovery. The automatic latch
+ * (svc_vas_candidates_verify + svc_xvas_pdb_discover) only runs from the RAM
+ * ring scan, which sweeps [0,6GB) before the client's pushes exist and then
+ * gives up for the boot; and per-client VAS state is flushed at session end.
+ * This entry point lets a host tool that CONTENT-LOCATED a verified
+ * {ring VA -> ring PA} pair (the ring page's GPFIFO entries are its
+ * fingerprint) hand the pair to the service while the client is alive, so:
+ * 1. every parked COPY_SERVER_PDES candidate is verified against the pair
+ * (fast: a walk each), and
+ * 2. if none verifies, the vidmem walk-root sweep anchors on the pair.
+ * Registered VASes make the client's pushbuffer VAs walkable and the pump
+ * can then decode the submit's pushes (the fence release among them).
+ */
+static u64 svc_pdb_disc_va;
+static u64 svc_pdb_disc_pa;
+static bool svc_pdb_disc_pending;
+
+int gsp_sema_service_pdb_discover(u64 ring_va, u64 ring_pa)
+{
+ if (!svc.task)
+ return -ENODEV;
+ svc_pdb_disc_va = ring_va & ~0xfffULL;
+ svc_pdb_disc_pa = ring_pa & ~0xfffULL;
+ svc_pdb_disc_pending = true;
+ wake_up_process(svc.task);
+ return 0;
+}
+
+/*
* r496f: discover a kernel-RM client VAS's page directory in the emulated
* VRAM by verification. The CPU RM builds internal-VAS page tables in
* vidmem and never publishes them (SET_PAGE_DIRECTORY is an externally
@@ -23534,6 +23575,15 @@ static void svc_gr_stale_wedge_check(struct nv_vgpu_device *vgpu,
static void svc_pump_channels(struct nv_vgpu_device *vgpu)
{
+ if (svc_pdb_disc_pending) {
+ svc_pdb_disc_pending = false;
+ pr_info("sema-pdb-disc: requested va=0x%llx pa=0x%llx\n",
+ svc_pdb_disc_va, svc_pdb_disc_pa);
+ svc_vas_candidates_verify(vgpu, svc_pdb_disc_va,
+ svc_pdb_disc_pa);
+ svc_xvas_pdb_discover(vgpu, svc_pdb_disc_va,
+ svc_pdb_disc_pa);
+ }
/* Only ever called from the service thread. */
static struct svc_channel local[SVC_MAX_CHANNELS];
/*
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index fbc7e4d..534e38d 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -110,6 +110,7 @@ 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_pdb_discover(u64 ring_va, u64 ring_pa);
int gsp_sema_service_counter_add(u32 h_object, u64 pa);
void gsp_sema_service_doorbell(u32 token);
diff --git a/kernel/main.c b/kernel/main.c
index dd11d12..5ff5047 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2960,6 +2960,37 @@ module_param_cb(sema_map_add, &nv_vgpu_sema_map_add_ops, NULL, 0200);
MODULE_PARM_DESC(sema_map_add, "Inject a GPU VA -> guest PA mapping (hex va,hex pa)");
/*
+ * Debug: retrigger the client-VAS page-directory discovery with a host
+ * content-verified {ring VA -> ring PA} pair (the ring page's GPFIFO
+ * entries are the fingerprint):
+ * echo 0x<va>,0x<pa> > .../parameters/sema_pdb_discover
+ */
+static int nv_vgpu_sema_pdb_discover_set(const char *val,
+ const struct kernel_param *kp)
+{
+ char buf[64];
+ char *comma;
+ u64 va = 0, pa = 0;
+
+ strscpy(buf, val, sizeof(buf));
+ comma = strchr(buf, ',');
+ if (!comma)
+ return -EINVAL;
+ *comma = '\0';
+ if (kstrtoull(buf, 0, &va) || kstrtoull(comma + 1, 0, &pa))
+ return -EINVAL;
+
+ return gsp_sema_service_pdb_discover(va, pa);
+}
+
+static const struct kernel_param_ops nv_vgpu_sema_pdb_discover_ops = {
+ .set = nv_vgpu_sema_pdb_discover_set,
+};
+
+module_param_cb(sema_pdb_discover, &nv_vgpu_sema_pdb_discover_ops, NULL, 0200);
+MODULE_PARM_DESC(sema_pdb_discover, "Retrigger the VAS pdb discovery with a verified ring pair (hex va,hex pa)");
+
+/*
* Debug: register a channel's GPU completion counter (guest PA of the u32
* tracking counter the GPU would write when a push completes):
* echo <h_object>,<pa> > .../parameters/sema_counter