diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-07 14:42:02 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-07 14:42:02 -0400 |
| commit | abb6b30b0d1020f30171f3e361a1591baed3676b (patch) | |
| tree | 327da4ffe5f2338de2e497ff7a3e72d173d5f3d5 /kernel/gsp_sema_service.c | |
| parent | 6fa955affe6ebca807737fcf1e51673e3859aa47 (diff) | |
| download | open-iov-abb6b30b0d1020f30171f3e361a1591baed3676b.tar.gz open-iov-abb6b30b0d1020f30171f3e361a1591baed3676b.zip | |
vgsp: m102 - relocate guest data into the server-managed VA region and rewrite bank pointers
The server refuses UPDATE_PDE_2 (status 0x1f) for guest CUDA VAs: they are
client-managed, while the golden VAS reserves the server-managed region
[0x100000000, 0x11fffffff) (gsp_phys_booter.c:8455). Map each resolved data
page there at an affine-relocated VA (identity HPA, no copies), rewrite every
8-byte pointer value inside the shadowed const-bank pages (banks 0..7) that
falls inside a mapped guest window to the relocated VA, and raise the Tier-1
window pool to 32 windows x 512 PTEs so the relocated pages fit. The kernel
now reaches its real data through the server-installed windows.
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 6dd0c7e..dfc9922 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3251,9 +3251,24 @@ struct svc_gr_page { struct svc_gr_data { u64 va; /* guest VA, page aligned */ u64 pa; /* guest PA, page aligned (0 = unresolved) */ + u64 reloc_va; /* m102: server-managed VA the page maps to */ u8 ap; /* SVC_APERTURE_* of pa */ }; +/* + * m102: guest window -> relocated window base. The server only installs + * page-directory entries in its managed region (the golden VAS reserves + * [0x100000000, 0x11fffffff), 256 x 2 MB windows); guest CUDA VAs are + * client-managed and refused with 0x1f. Data pages are mapped in the + * managed region at an affine-relocated VA and the pointers in the bank + * pages are rewritten to match. + */ +#define SVC_GR_DATA_WINS_MAX 64 +struct svc_gr_data_win { + u64 va_base; /* guest window base (2 MB aligned) */ + u64 reloc_base; /* relocated window base */ +}; + struct svc_gr_cand { bool valid; bool offered; /* consumed by a request or a fallback */ @@ -8277,6 +8292,8 @@ struct svc_fwd_req { struct svc_gr_page gr_pages[SVC_GR_PAGES_MAX]; u32 gr_n_data; struct svc_gr_data gr_data[SVC_GR_DATA_MAX]; + u32 gr_n_data_wins; + struct svc_gr_data_win gr_data_wins[SVC_GR_DATA_WINS_MAX]; }; static struct svc_fwd_req svc_fwd_req; @@ -9087,6 +9104,7 @@ static void svc_fwd_gr_work(void) */ static struct gsp_phys_gr_page pages[SVC_GR_PAGES_MAX]; static struct gsp_phys_gr_data_page data[SVC_GR_DATA_MAX]; + static struct gsp_phys_gr_data_win data_wins[SVC_GR_DATA_WINS_MAX]; struct gsp_phys_gr_submit gs; struct gsp_phys_backend_copy_result cp = { 0 }; u64 rel_hpa = 0; @@ -9174,9 +9192,17 @@ static void svc_fwd_gr_work(void) break; data[gs.n_data].va = dg->va; data[gs.n_data].hpa = dhpa; + data[gs.n_data].reloc_va = dg->reloc_va; gs.n_data++; } gs.data = data; + gs.n_data_wins = svc_fwd_req.gr_n_data_wins; + for (i = 0; i < svc_fwd_req.gr_n_data_wins; i++) { + data_wins[i].va_base = svc_fwd_req.gr_data_wins[i].va_base; + data_wins[i].reloc_base = + svc_fwd_req.gr_data_wins[i].reloc_base; + } + gs.data_wins = data_wins; gs.pages = pages; gs.n_pages = svc_fwd_req.gr_n_pages; gs.inl = (const struct gsp_phys_gr_inline *)svc_fwd_req.gr_inline; @@ -9529,20 +9555,24 @@ 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 + static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) { u64 wins[16]; - u32 n_win = 0; + u32 n_win = 0, n_cand; u32 off = 0, i, w; u8 kind; svc_fwd_req.gr_n_data = 0; + svc_fwd_req.gr_n_data_wins = 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. */ + n_cand = 0; for (i = 0; i < svc_fwd_req.gr_n_pages; i++) { const struct svc_gr_page *pp = &svc_fwd_req.gr_pages[i]; u64 hpa = 0; @@ -9568,24 +9598,43 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) (v & 3)) continue; wv = v & ~0x1fffffULL; - for (w = 0; w < n_win; w++) + for (w = 0; w < n_cand; w++) if (wins[w] == wv) break; - if (w == n_win && n_win < ARRAY_SIZE(wins)) - wins[n_win++] = wv; + if (w == n_cand && n_cand < ARRAY_SIZE(wins)) + wins[n_cand++] = wv; } } - for (w = 0; w < n_win; w++) { + for (w = 0; w < n_cand; w++) { int wi; for (wi = -1; wi <= 16; wi++) { u64 wv = wins[w] + (u64)wi * 0x200000ULL; - u32 got = 0, p; + u64 rbase; + u32 got = 0, p, x; if (wi < 0 && wins[w] < 0x200000ULL) continue; if (wv >= (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) + 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; @@ -9600,6 +9649,7 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) [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++; } @@ -9609,8 +9659,8 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu) return; } } - pr_info("vgsp-sema: svc-gr data fill: %u windows, %u pages resolved\n", - n_win, svc_fwd_req.gr_n_data); + 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); } static int svc_gr_req_fill(struct nv_vgpu_device *vgpu, |
