diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 38 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.c | 84 |
2 files changed, 58 insertions, 64 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 9e45937..fdd20db 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -16254,7 +16254,7 @@ static void gsp_phys_gr_rewrite_data_vars(u32 *w, u32 n_words, { u32 rew = 0, k; - if (!req->n_data_wins) + if (!req->n_data) return; /* Scan every 4-byte boundary: the demo's bank-4 base pointer sits at * a 4-aligned (not 8-aligned) offset, which an 8-stride scan misses. */ @@ -16265,12 +16265,11 @@ static void gsp_phys_gr_rewrite_data_vars(u32 *w, u32 n_words, if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3)) continue; - wb = v & ~0x1fffffULL; - for (x = 0; x < req->n_data_wins; x++) { - if (req->data_wins[x].va_base != wb) + wb = v & ~0xfffULL; + for (x = 0; x < req->n_data; x++) { + if (req->data[x].va != wb) continue; - v = req->data_wins[x].reloc_base | - (v & 0x1fffffULL); + v = req->data[x].reloc_va | (v & 0xfffULL); w[k] = (u32)v; w[k + 1] = (u32)(v >> 32); rew++; @@ -16296,20 +16295,30 @@ static int gsp_phys_rmcall_gr_data_map(void __iomem *bar0, u64 va, u64 hpa, u32 epoch) { struct gsp_phys_boot_chunk *pt; - u32 k, ip; + u32 ip; u64 pte; (void)bar0; (void)epoch; - if (va < GSP_PHYS_RMCALL_VA_GR_DATA_BASE) + /* + * m110: the engine's SM walker only honours the commit-time tree, so + * data pages are relocated into the main small-PT window + * (GSP_PHYS_RMCALL_VA_BASE + 0x10000 ..), whose slots above 0x10f are + * fresh PTE lines - the proven window-0 pattern. Slot 0x1f0 (VA + * 0x1f0000) is reserved for the mail injection; 0x180..0x18f stay + * clear of the legacy guest slot. + */ + if (va < GSP_PHYS_RMCALL_VA_BASE + 0x10000ULL || + va >= GSP_PHYS_RMCALL_VA_BASE + 0x200000ULL) return -ERANGE; - k = (u32)((va - GSP_PHYS_RMCALL_VA_GR_DATA_BASE) >> 21); - if (k >= GSP_PHYS_RMCALL_GR_DATA_WINS) + ip = (u32)((va >> 12) & 0x1ffu); + if (ip < 0x110u || (ip >= 0x180u && ip < 0x190u)) return -ERANGE; - pt = &boot_stage.rmcall_gr_data_pt[k]; + pt = &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_PT]; + if (pt->pages) + pt = pt; if (!pt->pages) return -EIO; - ip = (u32)((va >> 12) & 0x1ffu); pte = gsp_phys_rmcall_pte(hpa); if (gsp_phys_rmcall_gr_pte_kind_value()) pte |= (u64)gsp_phys_rmcall_gr_pte_kind_value() << 56; @@ -16661,9 +16670,8 @@ 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 = GSP_PHYS_RMCALL_VA_GR_DATA_BASE + - (((u64)GSP_PHYS_RMCALL_GR_DATA_WINS - 1) - << 21); + u64 mva = GSP_PHYS_RMCALL_VA_BASE + + 0x1f0000ULL; int mret = -EINVAL; if (boot_stage.rmcall_gr_mail.pages) diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 844d2c9..caaaae3 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -9555,7 +9555,13 @@ static bool svc_gr_page_inline_covers(u64 page) * Resolution only happens on the service thread; the work item turns the * guest PAs into HPAs and the backend plants the identity PTEs. */ -#define SVC_GR_DATA_RELOC_BASE 0x100000000ULL +#define SVC_GR_DATA_RELOC_BASE 0x110000ULL +/* + * Per candidate pointer, map at most this many pages from the pointer's + * page onward (the engine-visible main-PT window has ~220 free 4 KB slots; + * the demo buffers are small on the native path). + */ +#define SVC_GR_DATA_PAGES_PER_PTR 64u static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) { @@ -9605,62 +9611,42 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) wins[n_cand++] = wv; } } + /* m110: one contiguous run of pages per candidate pointer, relocated + * into the engine-walkable main-PT window (0x110000 onward, fresh + * PTE lines; the commit-time snapshot only preserves that window). */ for (w = 0; w < n_cand; w++) { - int wi; + u64 base = wins[w] & ~0x1fffffULL; + u32 p; - for (wi = -1; wi <= 16; wi++) { - u64 wv = wins[w] + (u64)wi * 0x200000ULL; - u64 rbase; - u32 got = 0, p, x; + for (p = 0; p < SVC_GR_DATA_PAGES_PER_PTR; p++) { + u64 va = wins[w] + (u64)p * SEMA_PAGE_SIZE; + u64 pa = 0; + u32 ap = 0, x; + struct svc_gr_data *rec; - if (wi < 0 && wins[w] < 0x200000ULL) - continue; - if (wv >= (1ULL << 47)) + if (va >= (1ULL << 47)) break; - for (x = 0; x < svc_fwd_req.gr_n_data_wins; x++) - if (svc_fwd_req.gr_data_wins[x].va_base == wv) + for (x = 0; x < svc_fwd_req.gr_n_data; x++) + if (svc_fwd_req.gr_data[x].va == va) break; - if (x == svc_fwd_req.gr_n_data_wins) { - if (svc_fwd_req.gr_n_data_wins >= - SVC_GR_DATA_WINS_MAX) - return; - svc_fwd_req.gr_data_wins[x].va_base = wv; - rbase = SVC_GR_DATA_RELOC_BASE + - ((u64)svc_fwd_req.gr_n_data_wins << - 21); - svc_fwd_req.gr_data_wins[x].reloc_base = - rbase; - svc_fwd_req.gr_n_data_wins++; - } else { - rbase = - svc_fwd_req.gr_data_wins[x].reloc_base; - } - for (p = 0; p < 512; p++) { - u64 va = wv + (u64)p * SEMA_PAGE_SIZE; - u64 pa = 0; - u32 ap = 0; - struct svc_gr_data *rec; - - if (svc_resolve_va(vgpu, va, &pa, &ap)) - continue; - if (svc_fwd_req.gr_n_data >= SVC_GR_DATA_MAX) - return; - rec = &svc_fwd_req.gr_data - [svc_fwd_req.gr_n_data++]; - rec->va = va; - rec->pa = pa & ~(u64)(SEMA_PAGE_SIZE - 1); - rec->reloc_va = rbase + (va & 0x1fffffULL); - rec->ap = (u8)svc_ap_of(ap); - got++; - } - if (!got && wi > 0) + if (x < svc_fwd_req.gr_n_data) + continue; /* already mapped */ + if (svc_resolve_va(vgpu, va, &pa, &ap)) break; if (svc_fwd_req.gr_n_data >= SVC_GR_DATA_MAX) return; - } - } - pr_info("vgsp-sema: svc-gr data fill: %u candidate ptrs, %u windows, %u pages resolved\n", - n_cand, svc_fwd_req.gr_n_data_wins, svc_fwd_req.gr_n_data); + rec = &svc_fwd_req.gr_data[svc_fwd_req.gr_n_data]; + rec->va = va; + rec->pa = pa & ~(u64)(SEMA_PAGE_SIZE - 1); + rec->reloc_va = SVC_GR_DATA_RELOC_BASE + + ((u64)svc_fwd_req.gr_n_data << 12); + rec->ap = (u8)svc_ap_of(ap); + svc_fwd_req.gr_n_data++; + } + (void)base; + } + pr_info("vgsp-sema: svc-gr data fill: %u candidate ptrs, %u pages resolved (reloc 0x%llx+)\n", + n_cand, svc_fwd_req.gr_n_data, (u64)SVC_GR_DATA_RELOC_BASE); } static int svc_gr_req_fill(struct nv_vgpu_device *vgpu, |
