diff options
-rw-r--r-- | hw/display/cirrus_vga.c | 9 | ||||
-rw-r--r-- | hw/display/qxl.c | 3 | ||||
-rw-r--r-- | hw/display/vga-isa-mm.c | 3 | ||||
-rw-r--r-- | hw/display/vga-isa.c | 3 | ||||
-rw-r--r-- | hw/display/vga-pci.c | 5 | ||||
-rw-r--r-- | hw/display/vga.c | 4 | ||||
-rw-r--r-- | hw/display/vga_int.h | 3 | ||||
-rw-r--r-- | hw/display/virtio-gpu.c | 64 | ||||
-rw-r--r-- | hw/display/virtio-vga.c | 2 | ||||
-rw-r--r-- | hw/display/vmware_vga.c | 4 | ||||
-rw-r--r-- | include/hw/compat.h | 16 |
11 files changed, 84 insertions, 32 deletions
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 5e44f00f3f..7583b18c29 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -3048,7 +3048,8 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) s->vram_size_mb); return; } - vga_common_init(s, OBJECT(dev), true); + s->global_vmstate = true; + vga_common_init(s, OBJECT(dev)); cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, isa_address_space(isadev), isa_address_space_io(isadev)); @@ -3062,7 +3063,7 @@ static Property isa_cirrus_vga_properties[] = { DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, cirrus_vga.vga.vram_size_mb, 4), DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, - cirrus_vga.enable_blitter, true), + cirrus_vga.enable_blitter, true), DEFINE_PROP_END_OF_LIST(), }; @@ -3105,7 +3106,7 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp) return; } /* setup VGA */ - vga_common_init(&s->vga, OBJECT(dev), true); + vga_common_init(&s->vga, OBJECT(dev)); cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), pci_address_space_io(dev)); s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga); @@ -3134,6 +3135,8 @@ static Property pci_vga_cirrus_properties[] = { cirrus_vga.vga.vram_size_mb, 4), DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState, cirrus_vga.enable_blitter, true), + DEFINE_PROP_BOOL("global-vmstate", struct PCICirrusVGAState, + cirrus_vga.vga.global_vmstate, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/display/qxl.c b/hw/display/qxl.c index b09a03997a..830c392c53 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2168,7 +2168,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp) qxl_init_ramsize(qxl); vga->vbe_size = qxl->vgamem_size; vga->vram_size_mb = qxl->vga.vram_size / MiB; - vga_common_init(vga, OBJECT(dev), true); + vga_common_init(vga, OBJECT(dev)); vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false); portio_list_init(&qxl->vga_port_list, OBJECT(dev), qxl_vga_portio_list, @@ -2408,6 +2408,7 @@ static Property qxl_properties[] = { #endif DEFINE_PROP_UINT32("xres", PCIQXLDevice, xres, 0), DEFINE_PROP_UINT32("yres", PCIQXLDevice, yres, 0), + DEFINE_PROP_BOOL("global-vmstate", PCIQXLDevice, vga.global_vmstate, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c index bd58141117..232216cad0 100644 --- a/hw/display/vga-isa-mm.c +++ b/hw/display/vga-isa-mm.c @@ -132,7 +132,8 @@ int isa_vga_mm_init(hwaddr vram_base, s = g_malloc0(sizeof(*s)); s->vga.vram_size_mb = VGA_RAM_SIZE / MiB; - vga_common_init(&s->vga, NULL, true); + s->vga.global_vmstate = true; + vga_common_init(&s->vga, NULL); vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space); s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s); diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 469834add5..fa44242e0d 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -58,7 +58,8 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; - vga_common_init(s, OBJECT(dev), true); + s->global_vmstate = true; + vga_common_init(s, OBJECT(dev)); s->legacy_address_space = isa_address_space(isadev); vga_io_memory = vga_init_io(s, OBJECT(dev), &vga_ports, &vbe_ports); isa_register_portio_list(isadev, &d->portio_vga, diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 1ea559762a..e9e62eac70 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -222,7 +222,7 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp) bool qext = false; /* vga + console init */ - vga_common_init(s, OBJECT(dev), true); + vga_common_init(s, OBJECT(dev)); vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), true); @@ -265,7 +265,7 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp) bool qext = false; /* vga + console init */ - vga_common_init(s, OBJECT(dev), false); + vga_common_init(s, OBJECT(dev)); s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s); /* mmio bar */ @@ -308,6 +308,7 @@ static Property vga_pci_properties[] = { DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true), DEFINE_PROP_BIT("qemu-extended-regs", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true), + DEFINE_PROP_BOOL("global-vmstate", PCIVGAState, vga.global_vmstate, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/display/vga.c b/hw/display/vga.c index d7599182a8..802cfd47db 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2164,7 +2164,7 @@ static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax) return val; } -void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) +void vga_common_init(VGACommonState *s, Object *obj) { int i, j, v, b; @@ -2203,7 +2203,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) s->is_vbe_vmstate = 1; memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size, &error_fatal); - vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj)); + vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj)); xen_register_framebuffer(&s->vram); s->vram_ptr = memory_region_get_ram_ptr(&s->vram); s->get_bpp = vga_get_bpp; diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index f8fcf62a56..339661bc01 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -133,6 +133,7 @@ typedef struct VGACommonState { bool full_update_gfx; bool big_endian_fb; bool default_endian_fb; + bool global_vmstate; /* hardware mouse cursor support */ uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; uint32_t hw_cursor_x; @@ -157,7 +158,7 @@ static inline int c6_to_8(int v) return (v << 2) | (b << 1) | b; } -void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate); +void vga_common_init(VGACommonState *s, Object *obj); void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, MemoryRegion *address_space_io, bool init_vga_ports); MemoryRegion *vga_init_io(VGACommonState *s, Object *obj, diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 71a00718e6..ec366f4c35 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -400,9 +400,47 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g, g->hostmem += res->hostmem; } +static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id) +{ + struct virtio_gpu_scanout *scanout = &g->scanout[scanout_id]; + struct virtio_gpu_simple_resource *res; + DisplaySurface *ds = NULL; + + if (scanout->resource_id == 0) { + return; + } + + res = virtio_gpu_find_resource(g, scanout->resource_id); + if (res) { + res->scanout_bitmask &= ~(1 << scanout_id); + } + + if (scanout_id == 0) { + /* primary head */ + ds = qemu_create_message_surface(scanout->width ?: 640, + scanout->height ?: 480, + "Guest disabled display."); + } + dpy_gfx_replace_surface(scanout->con, ds); + scanout->resource_id = 0; + scanout->ds = NULL; + scanout->width = 0; + scanout->height = 0; +} + static void virtio_gpu_resource_destroy(VirtIOGPU *g, struct virtio_gpu_simple_resource *res) { + int i; + + if (res->scanout_bitmask) { + for (i = 0; i < g->conf.max_outputs; i++) { + if (res->scanout_bitmask & (1 << i)) { + virtio_gpu_disable_scanout(g, i); + } + } + } + pixman_image_unref(res->image); virtio_gpu_cleanup_mapping(res); QTAILQ_REMOVE(&g->reslist, res, next); @@ -563,7 +601,7 @@ static void virtio_unref_resource(pixman_image_t *image, void *data) static void virtio_gpu_set_scanout(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd) { - struct virtio_gpu_simple_resource *res; + struct virtio_gpu_simple_resource *res, *ores; struct virtio_gpu_scanout *scanout; pixman_format_code_t format; uint32_t offset; @@ -584,24 +622,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, g->enable = 1; if (ss.resource_id == 0) { - scanout = &g->scanout[ss.scanout_id]; - if (scanout->resource_id) { - res = virtio_gpu_find_resource(g, scanout->resource_id); - if (res) { - res->scanout_bitmask &= ~(1 << ss.scanout_id); - } - } - if (ss.scanout_id == 0) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: illegal scanout id specified %d", - __func__, ss.scanout_id); - cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; - return; - } - dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL); - scanout->ds = NULL; - scanout->width = 0; - scanout->height = 0; + virtio_gpu_disable_scanout(g, ss.scanout_id); return; } @@ -654,6 +675,11 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds); } + ores = virtio_gpu_find_resource(g, scanout->resource_id); + if (ores) { + ores->scanout_bitmask &= ~(1 << ss.scanout_id); + } + res->scanout_bitmask |= (1 << ss.scanout_id); scanout->resource_id = ss.resource_id; scanout->x = ss.r.x; diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index 97db6c3372..8d3d9e14a7 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -106,7 +106,7 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) /* init vga compat bits */ vga->vram_size_mb = 8; - vga_common_init(vga, OBJECT(vpci_dev), false); + vga_common_init(vga, OBJECT(vpci_dev)); vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev), pci_address_space_io(&vpci_dev->pci_dev), true); pci_register_bar(&vpci_dev->pci_dev, 0, diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 08deb08783..0bbb78b9a6 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -1242,7 +1242,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s, &error_fatal); s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); - vga_common_init(&s->vga, OBJECT(dev), true); + vga_common_init(&s->vga, OBJECT(dev)); vga_init(&s->vga, OBJECT(dev), address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); s->new_depth = 32; @@ -1322,6 +1322,8 @@ static void pci_vmsvga_realize(PCIDevice *dev, Error **errp) static Property vga_vmware_properties[] = { DEFINE_PROP_UINT32("vgamem_mb", struct pci_vmsvga_state_s, chip.vga.vram_size_mb, 16), + DEFINE_PROP_BOOL("global-vmstate", struct pci_vmsvga_state_s, + chip.vga.global_vmstate, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/compat.h b/include/hw/compat.h index 44d5964060..c08f4040bb 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -10,6 +10,22 @@ .driver = "hda-audio",\ .property = "use-timer",\ .value = "false",\ + },{\ + .driver = "cirrus-vga",\ + .property = "global-vmstate",\ + .value = "true",\ + },{\ + .driver = "VGA",\ + .property = "global-vmstate",\ + .value = "true",\ + },{\ + .driver = "vmware-svga",\ + .property = "global-vmstate",\ + .value = "true",\ + },{\ + .driver = "qxl-vga",\ + .property = "global-vmstate",\ + .value = "true",\ }, #define HW_COMPAT_2_11 \ |