summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c65
1 files changed, 35 insertions, 30 deletions
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;