diff --git a/devicemodel/hw/pci/virtio/virtio_gpu.c b/devicemodel/hw/pci/virtio/virtio_gpu.c index aa3dd5ee6..c315dc604 100644 --- a/devicemodel/hw/pci/virtio/virtio_gpu.c +++ b/devicemodel/hw/pci/virtio/virtio_gpu.c @@ -1644,6 +1644,20 @@ virtio_gpu_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) gpu = (struct virtio_gpu *)dev->arg; gpu->vga.enable = false; + pthread_mutex_lock(&gpu->vga_thread_mtx); + if (atomic_load(&gpu->vga_thread_status) != VGA_THREAD_EOL) { + pthread_mutex_unlock(&gpu->vga_thread_mtx); + pthread_join(gpu->vga.tid, NULL); + } else + pthread_mutex_unlock(&gpu->vga_thread_mtx); + + if (gpu->vga.dev) + vga_deinit(&gpu->vga); + if (gpu->vga.gc) { + gc_deinit(gpu->vga.gc); + gpu->vga.gc = NULL; + } + pthread_mutex_destroy(&gpu->vga_thread_mtx); while (LIST_FIRST(&gpu->r2d_list)) { r2d = LIST_FIRST(&gpu->r2d_list); diff --git a/devicemodel/hw/vga.c b/devicemodel/hw/vga.c index 68b943bfc..02764304a 100644 --- a/devicemodel/hw/vga.c +++ b/devicemodel/hw/vga.c @@ -1426,3 +1426,32 @@ vga_vbe_read(struct vmctx *ctx, int vcpu, struct vga *vga, return (value); } + +void vga_deinit(struct vga *vga) +{ + struct vga_vdev *vd; + struct inout_port iop; + int port; + + vd = (struct vga_vdev *)vga->dev; + + for (port = VGA_IOPORT_START; port <= VGA_IOPORT_END; port++) { + iop.port = port; + iop.size = 1; + iop.flags = IOPORT_F_INOUT; + iop.handler = NULL; + iop.arg = NULL; + + unregister_inout(&iop); + //error = unregister_inout(&iop); + //assert(error == 0); + } + + unregister_mem_fallback(&vd->mr); + + free(vd->vga_ram); + vd->vga_ram = NULL; + + free(vd); + vga->dev = NULL; +} diff --git a/devicemodel/include/vga.h b/devicemodel/include/vga.h index 559a7d6b5..437401e97 100644 --- a/devicemodel/include/vga.h +++ b/devicemodel/include/vga.h @@ -199,4 +199,5 @@ void vga_vbe_write(struct vmctx *ctx, int vcpu, struct vga *vga, uint64_t vga_vbe_read(struct vmctx *ctx, int vcpu, struct vga *vga, uint64_t offset, int size); +void vga_deinit(struct vga *vga); #endif /* _VGA_H_ */