diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-08 07:05:03 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-08 07:05:03 -0500 |
| commit | 4942e2afb6a9470e5c8f3c60515656551bd1e2f2 (patch) | |
| tree | bc253beafeb7920c7fd28945fc1047478f09ae32 | |
| parent | cfa2bf216065c87a185e83a8bf38a6c5dd5788c8 (diff) | |
| download | open-iov-4942e2afb6a9470e5c8f3c60515656551bd1e2f2.tar.gz open-iov-4942e2afb6a9470e5c8f3c60515656551bd1e2f2.zip | |
vgsp-disp: retry the instance block through guest RAM when the shadow copy is empty
The RM's vidmem writes may use the coherent CPU mapping rather than the
BAR1 aperture, in which case the display instance block lands at the
announced address in guest RAM. Log the source used (src=fb|ram) and
fall back to vfio_dma_rw before reporting the hash table empty.
| -rw-r--r-- | kernel/gsp_display_engine.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/kernel/gsp_display_engine.c b/kernel/gsp_display_engine.c index 5109245..426d6a1 100644 --- a/kernel/gsp_display_engine.c +++ b/kernel/gsp_display_engine.c @@ -439,6 +439,7 @@ static int gsp_disp_ctxdma_pa(struct nv_vgpu_device *vgpu, u32 handle, if (have_im) { u64 e; + const char *im_src = "fb"; if (!disp.ibuf) return -ENOMEM; @@ -446,6 +447,52 @@ static int gsp_disp_ctxdma_pa(struct nv_vgpu_device *vgpu, u32 handle, GSP_DISP_INST_OBJ_END)) return -ENOENT; + /* + * The RM may write vidmem through a coherent CPU mapping + * instead of the BAR1 aperture, in which case the block lands + * at the same address in guest RAM rather than in the FB + * shadow. If the shadow copy is empty, retry through + * vfio_dma_rw before giving up. + */ + if (im_space == 2) { + u64 nz = 0; + + for (e = 0; e < GSP_DISP_INST_HASH_END; e += 8) { + u32 a = *(u32 *)(disp.ibuf + e); + u32 b = *(u32 *)(disp.ibuf + e + 4); + + if (a || b) + nz++; + } + if (!nz) { + u8 *tmp = kmalloc(GSP_DISP_INST_OBJ_END, + GFP_KERNEL); + + if (tmp) { + if (vfio_dma_rw(&vgpu->vfio_dev, im_pa, + tmp, + GSP_DISP_INST_OBJ_END, + false) == 0) { + for (e = 0; + e < GSP_DISP_INST_HASH_END; + e += 8) { + u32 a = *(u32 *)(tmp + e); + u32 b = *(u32 *)(tmp + e + 4); + + if (a || b) + nz++; + } + if (nz) { + memcpy(disp.ibuf, tmp, + GSP_DISP_INST_OBJ_END); + im_src = "ram"; + } + } + kfree(tmp); + } + } + } + if (gsp_disp_dbg && disp.im_logs < 8) { u32 nz = 0, shown = 0; @@ -463,8 +510,8 @@ static int gsp_disp_ctxdma_pa(struct nv_vgpu_device *vgpu, u32 handle, } } disp.im_logs++; - pr_info("inst mem pa=0x%llx space=%u handle=0x%x hash_nz=%u\n", - im_pa, im_space, handle, nz); + pr_info("inst mem pa=0x%llx space=%u src=%s handle=0x%x hash_nz=%u\n", + im_pa, im_space, im_src, handle, nz); /* * The announced block may not be where the RM's writes |
