summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_rm_emulation.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
-rw-r--r--kernel/gsp_rm_emulation.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 63a4338..4c848b8 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -2456,6 +2456,7 @@ static void gsp_rm_handle_bus_get_info_v2(struct gsp_emu_context *ctx,
#define GSPRM_COPY_PDES_MAX_LEVELS 6
static void gsp_rm_handle_copy_server_pdes(struct gsp_emu_context *ctx,
+ u32 h_object,
const u8 *params, u32 params_size)
{
struct gsp_rm_emu *rm = ctx->rm_emu;
@@ -2506,6 +2507,43 @@ static void gsp_rm_handle_copy_server_pdes(struct gsp_emu_context *ctx,
"vgsp-rm: pt level[%u] phys=0x%llx size=0x%llx aperture=%u pageShift=%u",
i, phys, size, aperture, page_shift);
}
+
+ /*
+ * r496g: this control IS the kernel RM publishing the page-table
+ * chain of its internal VAS (the level[0..] instances with their
+ * phys addresses and page shifts). Register the root with the
+ * progress service so the walker can translate every VA of this
+ * client - the X/GL channel's pushbuffer pages and its progress
+ * semaphore, for which no other translation source exists (the
+ * fn-54 SET_PAGE_DIRECTORY path is external-VAS/UVM only). The
+ * level values are sanity-gated; a wrong chain only costs failed
+ * walks.
+ */
+ if (num_levels >= 1 && rm->pt.levels[0].phys &&
+ rm->pt.levels[0].size >= 16 &&
+ rm->pt.levels[0].size <= 4096 * 8) {
+ struct sema_vaspace_desc d;
+
+ memset(&d, 0, sizeof(d));
+ d.h_vaspace = h_object;
+ d.pdb = rm->pt.levels[0].phys;
+ d.num_entries = (u32)(rm->pt.levels[0].size / 8);
+ /*
+ * The level phys values are guest PAs on this platform
+ * (observed 4+ GiB, above any FB shadow); aperture 3 in the
+ * message does not match the walker's FB/SYS encoding, so
+ * classify by address: values inside the emulated VRAM are
+ * FB, everything else sysmem. The walker also retries the
+ * other aperture, so a misclassification only costs a walk.
+ */
+ d.b_vidmem = rm->pt.levels[0].phys <
+ (u64)ctx->vgpu->bars[1].size;
+ gsp_sema_service_vaspace_add(&d);
+ nv_vgpu_info(ctx->vgpu,
+ "vgsp-rm: VAS 0x%x page directory registered from COPY_SERVER_PDES pdb=0x%llx entries=%u (%s)",
+ h_object, d.pdb, d.num_entries,
+ d.b_vidmem ? "vidmem" : "sysmem");
+ }
}
static bool gsp_rm_alloc_interesting(u32 class_id);
@@ -3219,7 +3257,8 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
break;
case 0x90f10106: /* NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES */
- gsp_rm_handle_copy_server_pdes(ctx, req_data + GSP_RM_CTRL_HDR_SIZE,
+ gsp_rm_handle_copy_server_pdes(ctx, req.hObject,
+ req_data + GSP_RM_CTRL_HDR_SIZE,
req.paramsSize);
out_status = 0;
out_params_size = 0;