From ae18e08d02500579f084616874d8f2ae57f8281b Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 23 Sep 2026 12:02:31 -0400 Subject: kernel: apply BAR0/BAR1 region writes to the emulated shadows The mdev's region write handler returned success without touching the BAR0 shadow or the trap table, so register writes that arrive through the VFIO region path (QEMU-trapped accesses) never took effect. A fresh guest then polled a register that never changed and spun forever in cuInit (QEMU log: vfio_region_write(mdev:region0+0x88704) failed: Resource temporarily unavailable). Route those writes to the BAR0 shadow/trap handler and mirror BAR1 writes into the emulated vidmem backing. --- kernel/main.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'kernel/main.c') diff --git a/kernel/main.c b/kernel/main.c index 0a1ebc2..45c34ab 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -755,6 +755,39 @@ static ssize_t nv_vgpu_vfio_dev_write(struct vfio_device *vdev, const char __use return ret; } + /* BAR0 region (register space). Most guest accesses hit the mmap'd + * shadow directly, but region writes also arrive here (e.g. when QEMU + * handles a trapped access). They must be applied to the shadow and to + * the trap table - dropping them makes the guest driver poll a + * register that never changes and spin forever. */ + if (pos >= 0 && (u64)pos < vgpu->bars[0].size && count <= 8) { + u8 tmp[8]; + ssize_t ret; + + if (!vgpu->bar_emul_ctx) + return -ENODEV; + if (copy_from_user(tmp, buf, count)) + return -EFAULT; + + ret = nv_vgpu_bar_emul_write(vgpu, 0, (u64)pos, tmp, count); + if (ret) + return ret; + *ppos += count; + return count; + } + + /* BAR1 region (VRAM): same for the emulated vidmem backing. */ + if (pos >= (1ULL << 40) && + (u64)pos < (1ULL << 40) + vgpu->bars[1].size && + vgpu->bars[1].vaddr && count <= 8) { + u64 bar1_off = (u64)pos - (1ULL << 40); + + if (copy_from_user(vgpu->bars[1].vaddr + bar1_off, buf, count)) + return -EFAULT; + *ppos += count; + return count; + } + return 0; } -- cgit v1.2.3