summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_phys_booter.c126
-rw-r--r--kernel/gsp_sema_service.c5
2 files changed, 111 insertions, 20 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 86205d1..b03ac30 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -2160,6 +2160,20 @@ static struct gsp_phys_boot_stage {
u64 rmcall_gr_qmdwin_va; /* planted VA; 0 = guest destination */
/* m104: module page holding the injected mail_kernel message. */
struct gsp_phys_boot_chunk rmcall_gr_mail;
+ /*
+ * m114: pre-commit bounce window. 112 pages planted into the main
+ * small-PT at slots 0x110..0x17f during stage 3 (the proven win0
+ * pattern: the SM walker resolves the commit-time tree only). The
+ * launch copies the kernel's data pages in, rewrites the pointers to
+ * these VAs (reloc base 0x110000), and copies the results back after
+ * the release; page 100 (VA 0x174000) carries the mail message.
+ */
+ struct gsp_phys_boot_chunk rmcall_gr_bounce;
+ u32 rmcall_gr_bounce_used;
+#define GSP_PHYS_RMCALL_GR_BOUNCE_PAGES 112u
+#define GSP_PHYS_RMCALL_GR_BOUNCE_SLOT0 0x110u
+#define GSP_PHYS_RMCALL_GR_BOUNCE_VA0 0x110000ULL
+#define GSP_PHYS_RMCALL_GR_MAIL_SLOT 100u
/* m99: guest data identity-map table branches (see the PD*_MAX block). */
struct gsp_phys_boot_chunk
rmcall_gr_data_pd1[GSP_PHYS_RMCALL_GR_DATA_PD1_MAX];
@@ -9405,6 +9419,50 @@ static void gsp_phys_rmcall_pdb_build(void)
}
}
/*
+ * m114: allocate the bounce window and plant its PTEs into the main
+ * small-PT at slots 0x110..0x17f - pre-commit direct writes, the
+ * same pattern as the window-0 pool the SM provably reads. The mail
+ * message goes into bounce page GSP_PHYS_RMCALL_GR_MAIL_SLOT.
+ */
+ if (!boot_stage.rmcall_gr_bounce.pages) {
+ struct gsp_phys_boot_chunk *ptb =
+ &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_PT];
+ u32 i;
+
+ if (!gsp_phys_chunk_alloc(boot_stage.pdev,
+ &boot_stage.rmcall_gr_bounce,
+ GSP_PHYS_RMCALL_GR_BOUNCE_PAGES)) {
+ gsp_phys_chunk_zero(&boot_stage.rmcall_gr_bounce);
+ for (i = 0; i < GSP_PHYS_RMCALL_GR_BOUNCE_PAGES; i++)
+ put_unaligned_le64(gsp_phys_rmcall_pte(
+ (u64)gsp_phys_chunk_page_dma(
+ &boot_stage.rmcall_gr_bounce, i)),
+ (u8 *)gsp_phys_chunk_page_va(ptb, 0) +
+ (size_t)(GSP_PHYS_RMCALL_GR_BOUNCE_SLOT0 + i) * 8);
+ dma_wmb();
+ pr_info("vgsp-boot: rm-call: bounce window planted: %u pages at VA 0x%llx..0x%llx (main PT slots 0x%x..0x%x)\n",
+ GSP_PHYS_RMCALL_GR_BOUNCE_PAGES,
+ GSP_PHYS_RMCALL_GR_BOUNCE_VA0,
+ GSP_PHYS_RMCALL_GR_BOUNCE_VA0 +
+ (GSP_PHYS_RMCALL_GR_BOUNCE_PAGES - 1) *
+ GSP_PHYS_PAGE_SIZE,
+ GSP_PHYS_RMCALL_GR_BOUNCE_SLOT0,
+ GSP_PHYS_RMCALL_GR_BOUNCE_SLOT0 +
+ GSP_PHYS_RMCALL_GR_BOUNCE_PAGES - 1);
+ {
+ static const char mail[] =
+ "the little gpu man says you've got mail";
+ memcpy(gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_gr_bounce,
+ GSP_PHYS_RMCALL_GR_MAIL_SLOT),
+ mail, sizeof(mail));
+ }
+ } else {
+ pr_err("vgsp-boot: rm-call: bounce window allocation failed\n");
+ }
+ }
+
+ /*
* P6a guest windows: start from explicit zero (invalid PTE) for both
* slots, then, when the guest GPA is already pinned (it must be pinned
* before stage 3 for this), pre-build both slots with the translated
@@ -16672,15 +16730,13 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
boot_stage.rmcall_gr_data_pt
[GSP_PHYS_RMCALL_GR_DATA_WINS - 1].pages);
{
- u64 mva = 0x1f0000ULL;
+ u64 mva = GSP_PHYS_RMCALL_GR_BOUNCE_VA0 +
+ ((u64)GSP_PHYS_RMCALL_GR_MAIL_SLOT
+ << 12);
int mret = -EINVAL;
- if (boot_stage.rmcall_gr_mail.pages)
- mret = gsp_phys_rmcall_gr_data_map(
- bar0, mva,
- (u64)gsp_phys_chunk_page_dma(
- &boot_stage.rmcall_gr_mail, 0),
- boot_stage.rmcall_gr_submit_epoch);
+ if (boot_stage.rmcall_gr_bounce.pages)
+ mret = 0;
if (!mret) {
w[0] = (u32)mva;
w[1] = (u32)(mva >> 32);
@@ -17097,22 +17153,28 @@ gr_page_unmapped:
le32_to_cpu(iv[172]), le32_to_cpu(iv[173]));
}
}
- if (req->n_data) {
- u32 dmapped = 0, dfailed = 0, di;
+ if (req->n_data && boot_stage.rmcall_gr_bounce.pages) {
+ u32 dcopied = 0, dfailed = 0, di;
for (di = 0; di < req->n_data; di++) {
- if (gsp_phys_rmcall_gr_data_map(bar0,
- req->data[di].reloc_va ?
- req->data[di].reloc_va :
- req->data[di].va,
- req->data[di].hpa,
- boot_stage.rmcall_gr_submit_epoch))
+ u32 bi = (u32)((req->data[di].reloc_va -
+ GSP_PHYS_RMCALL_GR_BOUNCE_VA0) >>
+ 12);
+
+ if (bi >= GSP_PHYS_RMCALL_GR_MAIL_SLOT ||
+ !req->data[di].hpa) {
dfailed++;
- else
- dmapped++;
+ continue;
+ }
+ memcpy(gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_gr_bounce, bi),
+ (u8 *)__va(req->data[di].hpa),
+ GSP_PHYS_PAGE_SIZE);
+ dcopied++;
}
- pr_info("vgsp-gr: guest data identity-map: %u pages in the engine tree, %u failed (pt pages=%u)\n",
- dmapped, dfailed, boot_stage.rmcall_gr_data_pt_n);
+ dma_wmb();
+ pr_info("vgsp-gr: bounce copy-in: %u pages, %u skipped\n",
+ dcopied, dfailed);
if (gsp_phys_rmcall_gr_recommit_value()) {
struct gsp_phys_rmcall_pdb_params rp;
struct {
@@ -17517,6 +17579,32 @@ gr_page_unmapped:
}
gsp_phys_gr_ok++;
+ /*
+ * m114: the kernel ran against the pre-commit bounce window; copy the
+ * results back to the guest's real pages (identity HPAs in the
+ * request). All mapped pages are written back; inputs are unchanged
+ * by the kernels, so copying them back is a no-op.
+ */
+ if (req->n_data && boot_stage.rmcall_gr_bounce.pages) {
+ u32 wbi, wrote = 0;
+
+ for (wbi = 0; wbi < req->n_data; wbi++) {
+ u32 bi = (u32)((req->data[wbi].reloc_va -
+ GSP_PHYS_RMCALL_GR_BOUNCE_VA0) >>
+ 12);
+
+ if (bi >= GSP_PHYS_RMCALL_GR_MAIL_SLOT ||
+ !req->data[wbi].hpa)
+ continue;
+ memcpy((u8 *)__va(req->data[wbi].hpa),
+ gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_gr_bounce, bi),
+ GSP_PHYS_PAGE_SIZE);
+ wrote++;
+ }
+ pr_info("vgsp-gr: bounce copy-out: %u pages written back\n",
+ wrote);
+ }
poll = w1;
if (bar0)
pr_info("vgsp-gr: SKED readback (ok): HWW_ESR=0x%08x INFO2=0x%08x CWD_T0=0x%08x CWD_T1=0x%08x CWD_T2=0x%08x\n",
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index caaaae3..24b3adf 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -9562,6 +9562,9 @@ static bool svc_gr_page_inline_covers(u64 page)
* the demo buffers are small on the native path).
*/
#define SVC_GR_DATA_PAGES_PER_PTR 64u
+/* m114: total pages the pre-commit bounce window can carry (slot 100 is
+ * the mail message). */
+#define SVC_GR_DATA_BOUNCE_MAX 100u
static void svc_gr_data_fill(struct nv_vgpu_device *vgpu)
{
@@ -9633,7 +9636,7 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu)
continue; /* already mapped */
if (svc_resolve_va(vgpu, va, &pa, &ap))
break;
- if (svc_fwd_req.gr_n_data >= SVC_GR_DATA_MAX)
+ if (svc_fwd_req.gr_n_data >= SVC_GR_DATA_BOUNCE_MAX)
return;
rec = &svc_fwd_req.gr_data[svc_fwd_req.gr_n_data];
rec->va = va;