From 035d033c5a047e395a7b06bceea1dc5b594c3b90 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sat, 7 Nov 2026 18:44:21 -0500 Subject: vgsp-disp: host-side EVO display engine (channels, push buffer, notifier, raster) The guest nvidia-modeset drives the display through per-channel NV-DMA push buffers kicked via the BAR0 UDISP control windows. Emulate that engine contract host-side, unmodified guest: - channel registration: display-channel RM objects (core 0xc57d, window 0xc57e, cursor 0xc57b, 0xc57a) are noted from the alloc stream, and the internal control NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) records each push buffer (guest PA, size, class, instance, validity); - PUT polling + GET publication in the channel control pages (core 0x680000, window 0x690000+n*0x1000, cursor 0x6D8000+n*0x1000); - NV-DMA method parser (METHOD/ONE_INC/NONINC/JUMP/SET_SUBDEVICE_MASK) with the wrap-JUMP follow; - completion: SET_CONTEXT_DMA_NOTIFIER / SET_NOTIFIER_CONTROL tracking, exact notifier-surface resolution through the display instance hash table (no heuristic writes), NV_DISP_NOTIFIER FINISHED on UPDATE (0x200), and the channel completion event post; - free-running 1080p60 raster line for NVC57E_GET_LINE. All effects are behind independent knobs (disp_engine, disp_finish, disp_vblank, disp_events, disp_notifier_pa) with verbose diagnostics (disp_dbg, disp_dump), so the previous behaviour stays one load away. --- kernel/gsp_sema_service.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 6f0103b..fb75f33 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -53,6 +53,7 @@ #include "bar_emulation.h" #include "gsp_sema_service.h" #include "gsp_rm_emulation.h" +#include "gsp_display_engine.h" #include "gsp_phys_booter.h" #include "gsp_phys_gpu.h" #include "gsp_cuda_bridge.h" @@ -44685,6 +44686,16 @@ static int svc_thread(void *arg) if (svc.gpfifo_entries_done != done_before) pumped = true; + /* + * r1621: display-engine progress. The guest's + * nvidia-modeset kicks its EVO channels through the + * BAR0 UDISP control windows; consume the push buffers, + * publish GET and complete each UPDATE's core notifier. + * The boot display-init and every Xorg mode set wait on + * that completion. + */ + gsp_disp_engine_pump(vgpu); + /* * Host CUDA bridge: marshal one queued launch into a * daemon job and resolve completions. Inert until a @@ -44876,8 +44887,11 @@ int gsp_sema_service_start(void) * while gsp_phys_work_forward is enabled; the software path needs no * workqueue at all. */ + if (gsp_disp_engine_init()) + pr_warn("sema-svc: display engine init failed\n"); svc.task = kthread_run(svc_thread, NULL, "gsp-sema-svc"); if (IS_ERR(svc.task)) { + gsp_disp_engine_fini(); int ret = PTR_ERR(svc.task); svc.task = NULL; @@ -44921,6 +44935,7 @@ void gsp_sema_service_stop(void) svc_fwd_wq = NULL; } /* Thread is gone: release the bridge's pending jobs and debugfs files. */ + gsp_disp_engine_fini(); gsp_cuda_bridge_fini(); svc_setup_demand_debugfs_fini(); /* A fresh session must not inherit shadowed bytes from the last one. */ @@ -44957,6 +44972,9 @@ void gsp_sema_service_vgpu_cleanup(struct nv_vgpu_device *vgpu) if (!vgpu) return; + /* r1621: drop the guest's display channels with the rest of its state. */ + gsp_disp_engine_vgpu_cleanup(vgpu); + /* * The forward work item runs on its own kthread and may be using the * request's vgpu; quiesce waits for it (bounded by the submit's -- cgit v1.2.3