summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:28:39 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:28:39 -0400
commit0d8f7427b0e21c87e3a5d2b20fbd27c403ea5954 (patch)
tree8e4c57ff99338280b8fe747e7aa981a3b2b96bec
parent1cba231142fcaa88467b196ede280b5618b1bb82 (diff)
downloadopen-iov-0d8f7427b0e21c87e3a5d2b20fbd27c403ea5954.tar.gz
open-iov-0d8f7427b0e21c87e3a5d2b20fbd27c403ea5954.zip
vgsp: m100 - scan every const-bank page for data VAs; data PTEs kind 0 by default
The +0x880 trap instruction disassembles (nvdisasm on the m98b prologue bytes) to LDG.E.U8.CONSTANT.SYS R5, [R2.64+UR4] with UR4 = c[0x4][0x0] - the first global load's base comes from const bank 4, not the c[0x0] param page the m99 scan covered. svc_gr_data_fill now scans every bank page the launch carries (QMD words 32..47, even LO words: banks 0..7), deduping up to 16 windows. Data PTEs use the gr_pte_kind param (default 0 = the kind proven SM-visible via the const reads) instead of a hardcoded 6.
-rw-r--r--kernel/gsp_phys_booter.c4
-rw-r--r--kernel/gsp_sema_service.c65
2 files changed, 38 insertions, 31 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 6db26a4..880299c 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -16263,7 +16263,9 @@ static int gsp_phys_rmcall_gr_data_map(u64 va, u64 hpa)
pt = gsp_phys_rmcall_gr_data_pt_get(i2, i1, i0);
if (!pt)
return -ENOSPC;
- pte = gsp_phys_rmcall_pte(hpa) | (6ULL << 56);
+ pte = gsp_phys_rmcall_pte(hpa);
+ if (gsp_phys_rmcall_gr_pte_kind_value())
+ pte |= (u64)gsp_phys_rmcall_gr_pte_kind_value() << 56;
put_unaligned_le64(pte, (u8 *)gsp_phys_chunk_page_va(pt, 0) +
(size_t)ip * 8);
dma_wmb();
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 0e93058..6dd0c7e 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -9531,44 +9531,49 @@ static bool svc_gr_page_inline_covers(u64 page)
*/
static void svc_gr_data_fill(struct nv_vgpu_device *vgpu)
{
- const struct svc_gr_page *pp = NULL;
- u64 wins[8];
+ u64 wins[16];
u32 n_win = 0;
- u64 param_hpa = 0;
u32 off = 0, i, w;
- const u8 *page;
u8 kind;
svc_fwd_req.gr_n_data = 0;
+ /*
+ * m100: scan every const-bank page the launch carries (QMD words
+ * 32..47 are the bank LO/HI pairs; the demo's LDG.E base comes from
+ * c[0x4][0x0], not from the c[0x0] param page). Each page's first
+ * 2 KB is scanned for plausible device VAs.
+ */
for (i = 0; i < svc_fwd_req.gr_n_pages; i++) {
- if (svc_fwd_req.gr_pages[i].qmd_word == 32 &&
- svc_fwd_req.gr_pages[i].pa) {
- pp = &svc_fwd_req.gr_pages[i];
- break;
- }
- }
- if (!pp)
- return;
- kind = (pp->ap == SVC_APERTURE_FB) ? SVC_APERTURE_FB :
- SVC_APERTURE_SYS;
- if (svc_fwd_operand_hpa(vgpu, kind, pp->pa, 0, SEMA_PAGE_SIZE,
- &param_hpa, &off) || off)
- return;
- page = (const u8 *)__va(param_hpa);
- if (!page)
- return;
- for (i = 0; i < 256; i++) {
- u64 v = get_unaligned_le64(page + i * 8);
- u64 wv;
+ const struct svc_gr_page *pp = &svc_fwd_req.gr_pages[i];
+ u64 hpa = 0;
+ const u8 *page;
+ u32 k;
- if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3))
+ if (pp->qmd_word < 32 || pp->qmd_word > 47 ||
+ (pp->qmd_word & 1) || !pp->pa)
continue;
- wv = v & ~0x1fffffULL;
- for (w = 0; w < n_win; w++)
- if (wins[w] == wv)
- break;
- if (w == n_win && n_win < ARRAY_SIZE(wins))
- wins[n_win++] = wv;
+ kind = (pp->ap == SVC_APERTURE_FB) ? SVC_APERTURE_FB :
+ SVC_APERTURE_SYS;
+ if (svc_fwd_operand_hpa(vgpu, kind, pp->pa, 0,
+ SEMA_PAGE_SIZE, &hpa, &off) || off)
+ continue;
+ page = (const u8 *)__va(hpa);
+ if (!page)
+ continue;
+ for (k = 0; k < 256; k++) {
+ u64 v = get_unaligned_le64(page + k * 8);
+ u64 wv;
+
+ if (v < 0x10000000ULL || v >= (1ULL << 47) ||
+ (v & 3))
+ continue;
+ wv = v & ~0x1fffffULL;
+ for (w = 0; w < n_win; w++)
+ if (wins[w] == wv)
+ break;
+ if (w == n_win && n_win < ARRAY_SIZE(wins))
+ wins[n_win++] = wv;
+ }
}
for (w = 0; w < n_win; w++) {
int wi;