summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:42:02 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:42:02 -0400
commitabb6b30b0d1020f30171f3e361a1591baed3676b (patch)
tree327da4ffe5f2338de2e497ff7a3e72d173d5f3d5 /kernel/gsp_sema_service.c
parent6fa955affe6ebca807737fcf1e51673e3859aa47 (diff)
downloadopen-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.c66
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,