diff options
| -rw-r--r-- | audio/paaudio.c | 11 | ||||
| -rwxr-xr-x | configure | 4 | ||||
| -rw-r--r-- | gdbstub.c | 12 | ||||
| -rw-r--r-- | hw/audio/cs4231.c | 12 | ||||
| -rw-r--r-- | hw/audio/intel-hda.c | 32 | ||||
| -rw-r--r-- | hw/audio/milkymist-ac97.c | 26 | ||||
| -rw-r--r-- | hw/display/virtio-gpu-3d.c | 2 | ||||
| -rw-r--r-- | hw/display/virtio-gpu.c | 202 | ||||
| -rw-r--r-- | hw/display/virtio-vga.c | 12 | ||||
| -rw-r--r-- | hw/display/vmware_vga.c | 78 | ||||
| -rw-r--r-- | hw/scsi/scsi-disk.c | 2 | ||||
| -rw-r--r-- | include/hw/virtio/virtio-gpu.h | 4 | ||||
| -rw-r--r-- | target-alpha/translate.c | 3 | ||||
| -rw-r--r-- | target-cris/translate.c | 3 | ||||
| -rw-r--r-- | target-i386/translate.c | 3 | ||||
| -rw-r--r-- | target-lm32/translate.c | 3 | ||||
| -rw-r--r-- | target-m68k/translate.c | 3 | ||||
| -rw-r--r-- | target-microblaze/translate.c | 3 | ||||
| -rw-r--r-- | target-mips/translate.c | 3 | ||||
| -rw-r--r-- | target-openrisc/translate.c | 3 | ||||
| -rw-r--r-- | target-ppc/translate.c | 3 | ||||
| -rw-r--r-- | target-s390x/translate.c | 3 | ||||
| -rw-r--r-- | target-sh4/translate.c | 3 | ||||
| -rw-r--r-- | target-sparc/translate.c | 3 | ||||
| -rw-r--r-- | target-tricore/translate.c | 3 | ||||
| -rw-r--r-- | target-unicore32/translate.c | 3 | ||||
| -rw-r--r-- | target-xtensa/translate.c | 3 |
27 files changed, 335 insertions, 107 deletions
diff --git a/audio/paaudio.c b/audio/paaudio.c index 57678e72e1..65beb6f010 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -781,23 +781,22 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) pa_threaded_mainloop_lock (g->mainloop); - /* FIXME: use the upcoming "set_source_output_{volume,mute}" */ - op = pa_context_set_source_volume_by_index (g->context, - pa_stream_get_device_index (pa->stream), + op = pa_context_set_source_output_volume (g->context, + pa_stream_get_index (pa->stream), &v, NULL, NULL); if (!op) { qpa_logerr (pa_context_errno (g->context), - "set_source_volume() failed\n"); + "set_source_output_volume() failed\n"); } else { pa_operation_unref(op); } - op = pa_context_set_source_mute_by_index (g->context, + op = pa_context_set_source_output_mute (g->context, pa_stream_get_index (pa->stream), sw->vol.mute, NULL, NULL); if (!op) { qpa_logerr (pa_context_errno (g->context), - "set_source_mute() failed\n"); + "set_source_output_mute() failed\n"); } else { pa_operation_unref (op); } diff --git a/configure b/configure index b5aab7257b..6d01d968b8 100755 --- a/configure +++ b/configure @@ -2813,8 +2813,8 @@ for drv in $audio_drv_list; do ;; pa) - audio_drv_probe $drv pulse/mainloop.h "-lpulse" \ - "pa_mainloop *m = 0; pa_mainloop_free (m); return 0;" + audio_drv_probe $drv pulse/pulseaudio.h "-lpulse" \ + "pa_context_set_source_output_volume(NULL, 0, NULL, NULL, NULL); return 0;" libs_softmmu="-lpulse $libs_softmmu" audio_pt_int="yes" ;; diff --git a/gdbstub.c b/gdbstub.c index b9e3710bfe..8155eedf9c 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -333,7 +333,7 @@ static int get_char(GDBState *s) if (ret < 0) { if (errno == ECONNRESET) s->fd = -1; - if (errno != EINTR && errno != EAGAIN) + if (errno != EINTR) return -1; } else if (ret == 0) { close(s->fd); @@ -394,7 +394,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) while (len > 0) { ret = send(s->fd, buf, len, 0); if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) + if (errno != EINTR) return; } else { buf += ret; @@ -1543,9 +1543,13 @@ gdb_handlesig(CPUState *cpu, int sig) for (i = 0; i < n; i++) { gdb_read_byte(s, buf[i]); } - } else if (n == 0 || errno != EAGAIN) { + } else { /* XXX: Connection closed. Should probably wait for another connection before continuing. */ + if (n == 0) { + close(s->fd); + } + s->fd = -1; return sig; } } @@ -1600,8 +1604,6 @@ static void gdb_accept(void) gdb_has_xml = false; gdbserver_state = s; - - fcntl(fd, F_SETFL, O_NONBLOCK); } static int gdbserver_open(int port) diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c index caf97c1692..30690f96ae 100644 --- a/hw/audio/cs4231.c +++ b/hw/audio/cs4231.c @@ -145,16 +145,15 @@ static const VMStateDescription vmstate_cs4231 = { } }; -static int cs4231_init1(SysBusDevice *dev) +static void cs4231_init(Object *obj) { - CSState *s = CS4231(dev); + CSState *s = CS4231(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); - memory_region_init_io(&s->iomem, OBJECT(s), &cs_mem_ops, s, "cs4321", + memory_region_init_io(&s->iomem, obj, &cs_mem_ops, s, "cs4321", CS_SIZE); sysbus_init_mmio(dev, &s->iomem); sysbus_init_irq(dev, &s->irq); - - return 0; } static Property cs4231_properties[] = { @@ -164,9 +163,7 @@ static Property cs4231_properties[] = { static void cs4231_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = cs4231_init1; dc->reset = cs_reset; dc->vmsd = &vmstate_cs4231; dc->props = cs4231_properties; @@ -176,6 +173,7 @@ static const TypeInfo cs4231_info = { .name = TYPE_CS4231, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(CSState), + .instance_init = cs4231_init, .class_init = cs4231_class_init, }; diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index d372d4ab98..93d7669fb5 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -26,6 +26,7 @@ #include "intel-hda.h" #include "intel-hda-defs.h" #include "sysemu/dma.h" +#include "qapi/error.h" /* --------------------------------------------------------------------- */ /* hda bus */ @@ -50,25 +51,28 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size, bus->xfer = xfer; } -static int hda_codec_dev_init(DeviceState *qdev) +static void hda_codec_dev_realize(DeviceState *qdev, Error **errp) { - HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus); - HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev); + HDACodecBus *bus = HDA_BUS(qdev->parent_bus); + HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev); HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev); if (dev->cad == -1) { dev->cad = bus->next_cad; } if (dev->cad >= 15) { - return -1; + error_setg(errp, "HDA audio codec address is full"); + return; } bus->next_cad = dev->cad + 1; - return cdc->init(dev); + if (cdc->init(dev) != 0) { + error_setg(errp, "HDA audio init failed"); + } } static int hda_codec_dev_exit(DeviceState *qdev) { - HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev); + HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev); HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev); if (cdc->exit) { @@ -84,7 +88,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; - cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); + cdev = HDA_CODEC_DEVICE(qdev); if (cdev->cad == cad) { return cdev; } @@ -94,14 +98,14 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t response) { - HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus); + HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); bus->response(dev, solicited, response); } bool hda_codec_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, uint8_t *buf, uint32_t len) { - HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus); + HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); return bus->xfer(dev, stnr, output, buf, len); } @@ -337,7 +341,7 @@ static void intel_hda_corb_run(IntelHDAState *d) static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response) { - HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus); + HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); IntelHDAState *d = container_of(bus, IntelHDAState, codecs); hwaddr addr; uint32_t wp, ex; @@ -386,7 +390,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, uint8_t *buf, uint32_t len) { - HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus); + HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); IntelHDAState *d = container_of(bus, IntelHDAState, codecs); hwaddr addr; uint32_t s, copy, left; @@ -493,7 +497,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn DeviceState *qdev = kid->child; HDACodecDeviceClass *cdc; - cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); + cdev = HDA_CODEC_DEVICE(qdev); cdc = HDA_CODEC_DEVICE_GET_CLASS(cdev); if (cdc->stream) { cdc->stream(cdev, stream, running, output); @@ -1120,7 +1124,7 @@ static void intel_hda_reset(DeviceState *dev) /* reset codecs */ QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) { DeviceState *qdev = kid->child; - cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); + cdev = HDA_CODEC_DEVICE(qdev); device_reset(DEVICE(cdev)); d->state_sts |= (1 << cdev->cad); } @@ -1298,7 +1302,7 @@ static const TypeInfo intel_hda_info_ich9 = { static void hda_codec_device_class_init(ObjectClass *klass, void *data) { DeviceClass *k = DEVICE_CLASS(klass); - k->init = hda_codec_dev_init; + k->realize = hda_codec_dev_realize; k->exit = hda_codec_dev_exit; set_bit(DEVICE_CATEGORY_SOUND, k->categories); k->bus_type = TYPE_HDA_BUS; diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c index 6a3b53674e..5075c2b148 100644 --- a/hw/audio/milkymist-ac97.c +++ b/hw/audio/milkymist-ac97.c @@ -284,16 +284,26 @@ static int ac97_post_load(void *opaque, int version_id) return 0; } -static int milkymist_ac97_init(SysBusDevice *dev) +static void milkymist_ac97_init(Object *obj) { - MilkymistAC97State *s = MILKYMIST_AC97(dev); + MilkymistAC97State *s = MILKYMIST_AC97(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); - struct audsettings as; sysbus_init_irq(dev, &s->crrequest_irq); sysbus_init_irq(dev, &s->crreply_irq); sysbus_init_irq(dev, &s->dmar_irq); sysbus_init_irq(dev, &s->dmaw_irq); + memory_region_init_io(&s->regs_region, obj, &ac97_mmio_ops, s, + "milkymist-ac97", R_MAX * 4); + sysbus_init_mmio(dev, &s->regs_region); +} + +static void milkymist_ac97_realize(DeviceState *dev, Error **errp) +{ + MilkymistAC97State *s = MILKYMIST_AC97(dev); + struct audsettings as; + AUD_register_card("Milkymist AC'97", &s->card); as.freq = 48000; @@ -305,12 +315,6 @@ static int milkymist_ac97_init(SysBusDevice *dev) "mm_ac97.in", s, ac97_in_cb, &as); s->voice_out = AUD_open_out(&s->card, s->voice_out, "mm_ac97.out", s, ac97_out_cb, &as); - - memory_region_init_io(&s->regs_region, OBJECT(s), &ac97_mmio_ops, s, - "milkymist-ac97", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; } static const VMStateDescription vmstate_milkymist_ac97 = { @@ -327,9 +331,8 @@ static const VMStateDescription vmstate_milkymist_ac97 = { static void milkymist_ac97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_ac97_init; + dc->realize = milkymist_ac97_realize; dc->reset = milkymist_ac97_reset; dc->vmsd = &vmstate_milkymist_ac97; } @@ -338,6 +341,7 @@ static const TypeInfo milkymist_ac97_info = { .name = TYPE_MILKYMIST_AC97, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MilkymistAC97State), + .instance_init = milkymist_ac97_init, .class_init = milkymist_ac97_class_init, }; diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c index 433bf93024..29918a090b 100644 --- a/hw/display/virtio-gpu-3d.c +++ b/hw/display/virtio-gpu-3d.c @@ -284,7 +284,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, VIRTIO_GPU_FILL_CMD(att_rb); trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id); - ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, &res_iovs); + ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, NULL, &res_iovs); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index f3b0f1419e..136c095b7d 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -22,6 +22,8 @@ #include "qemu/log.h" #include "qapi/error.h" +#define VIRTIO_GPU_VM_VERSION 1 + static struct virtio_gpu_simple_resource* virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id); @@ -94,7 +96,7 @@ static void update_cursor_data_virgl(VirtIOGPU *g, static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor) { struct virtio_gpu_scanout *s; - bool move = cursor->hdr.type != VIRTIO_GPU_CMD_MOVE_CURSOR; + bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR; if (cursor->pos.scanout_id >= g->conf.max_outputs) { return; @@ -107,7 +109,7 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor) move ? "move" : "update", cursor->resource_id); - if (move) { + if (!move) { if (!s->current_cursor) { s->current_cursor = cursor_alloc(64, 64); } @@ -120,6 +122,11 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor) g, s, cursor->resource_id); } dpy_cursor_define(s->con, s->current_cursor); + + s->cursor = *cursor; + } else { + s->cursor.pos.x = cursor->pos.x; + s->cursor.pos.y = cursor->pos.y; } dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y, cursor->resource_id ? 1 : 0); @@ -495,6 +502,11 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, pixman_region_fini(&flush_region); } +static void virtio_unref_resource(pixman_image_t *image, void *data) +{ + pixman_image_unref(data); +} + static void virtio_gpu_set_scanout(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd) { @@ -571,8 +583,15 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, != ((uint8_t *)pixman_image_get_data(res->image) + offset) || scanout->width != ss.r.width || scanout->height != ss.r.height) { + pixman_image_t *rect; + void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset; + rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr, + pixman_image_get_stride(res->image)); + pixman_image_ref(res->image); + pixman_image_set_destroy_function(rect, virtio_unref_resource, + res->image); /* realloc the surface ptr */ - scanout->ds = qemu_create_displaysurface_pixman(res->image); + scanout->ds = qemu_create_displaysurface_pixman(rect); if (!scanout->ds) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -590,7 +609,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, - struct iovec **iov) + uint64_t **addr, struct iovec **iov) { struct virtio_gpu_mem_entry *ents; size_t esize, s; @@ -616,10 +635,16 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, } *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries); + if (addr) { + *addr = g_malloc0(sizeof(uint64_t) * ab->nr_entries); + } for (i = 0; i < ab->nr_entries; i++) { hwaddr len = ents[i].length; (*iov)[i].iov_len = ents[i].length; (*iov)[i].iov_base = cpu_physical_memory_map(ents[i].addr, &len, 1); + if (addr) { + (*addr)[i] = ents[i].addr; + } if (!(*iov)[i].iov_base || len != ents[i].length) { qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" " resource %d element %d\n", @@ -627,6 +652,10 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, virtio_gpu_cleanup_mapping_iov(*iov, i); g_free(ents); *iov = NULL; + if (addr) { + g_free(*addr); + *addr = NULL; + } return -1; } } @@ -650,6 +679,8 @@ static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res) virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt); res->iov = NULL; res->iov_cnt = 0; + g_free(res->addrs); + res->addrs = NULL; } static void @@ -671,7 +702,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g, return; } - ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->iov); + ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -917,11 +948,163 @@ const GraphicHwOps virtio_gpu_ops = { .gl_block = virtio_gpu_gl_block, }; +static const VMStateDescription vmstate_virtio_gpu_scanout = { + .name = "virtio-gpu-one-scanout", + .version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout), + VMSTATE_UINT32(width, struct virtio_gpu_scanout), + VMSTATE_UINT32(height, struct virtio_gpu_scanout), + VMSTATE_INT32(x, struct virtio_gpu_scanout), + VMSTATE_INT32(y, struct virtio_gpu_scanout), + VMSTATE_UINT32(cursor.resource_id, struct virtio_gpu_scanout), + VMSTATE_UINT32(cursor.hot_x, struct virtio_gpu_scanout), + VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout), + VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout), + VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout), + VMSTATE_END_OF_LIST() + }, +}; + +static const VMStateDescription vmstate_virtio_gpu_scanouts = { + .name = "virtio-gpu-scanouts", + .version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(enable, struct VirtIOGPU), + VMSTATE_UINT32_EQUAL(conf.max_outputs, struct VirtIOGPU), + VMSTATE_STRUCT_VARRAY_UINT32(scanout, struct VirtIOGPU, + conf.max_outputs, 1, + vmstate_virtio_gpu_scanout, + struct virtio_gpu_scanout), + VMSTATE_END_OF_LIST() + }, +}; + static const VMStateDescription vmstate_virtio_gpu_unmigratable = { - .name = "virtio-gpu", + .name = "virtio-gpu-with-virgl", .unmigratable = 1, }; +static void virtio_gpu_save(QEMUFile *f, void *opaque) +{ + VirtIOGPU *g = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(g); + struct virtio_gpu_simple_resource *res; + int i; + + virtio_save(vdev, f); + + /* in 2d mode we should never find unprocessed commands here */ + assert(QTAILQ_EMPTY(&g->cmdq)); + + QTAILQ_FOREACH(res, &g->reslist, next) { + qemu_put_be32(f, res->resource_id); + qemu_put_be32(f, res->width); + qemu_put_be32(f, res->height); + qemu_put_be32(f, res->format); + qemu_put_be32(f, res->iov_cnt); + for (i = 0; i < res->iov_cnt; i++) { + qemu_put_be64(f, res->addrs[i]); + qemu_put_be32(f, res->iov[i].iov_len); + } + qemu_put_buffer(f, (void *)pixman_image_get_data(res->image), + pixman_image_get_stride(res->image) * res->height); + } + qemu_put_be32(f, 0); /* end of list */ + + vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL); +} + +static int virtio_gpu_load(QEMUFile *f, void *opaque, int version_id) +{ + VirtIOGPU *g = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(g); + struct virtio_gpu_simple_resource *res; + struct virtio_gpu_scanout *scanout; + uint32_t resource_id, pformat; + int i, ret; + + if (version_id != VIRTIO_GPU_VM_VERSION) { + return -EINVAL; + } + + ret = virtio_load(vdev, f, version_id); + if (ret) { + return ret; + } + + resource_id = qemu_get_be32(f); + while (resource_id != 0) { + res = g_new0(struct virtio_gpu_simple_resource, 1); + res->resource_id = resource_id; + res->width = qemu_get_be32(f); + res->height = qemu_get_be32(f); + res->format = qemu_get_be32(f); + res->iov_cnt = qemu_get_be32(f); + + /* allocate */ + pformat = get_pixman_format(res->format); + if (!pformat) { + return -EINVAL; + } + res->image = pixman_image_create_bits(pformat, + res->width, res->height, + NULL, 0); + if (!res->image) { + return -EINVAL; + } + + res->addrs = g_new(uint64_t, res->iov_cnt); + res->iov = g_new(struct iovec, res->iov_cnt); + + /* read data */ + for (i = 0; i < res->iov_cnt; i++) { + res->addrs[i] = qemu_get_be64(f); + res->iov[i].iov_len = qemu_get_be32(f); + } + qemu_get_buffer(f, (void *)pixman_image_get_data(res->image), + pixman_image_get_stride(res->image) * res->height); + + /* restore mapping */ + for (i = 0; i < res->iov_cnt; i++) { + hwaddr len = res->iov[i].iov_len; + res->iov[i].iov_base = + cpu_physical_memory_map(res->addrs[i], &len, 1); + if (!res->iov[i].iov_base || len != res->iov[i].iov_len) { + return -EINVAL; + } + } + + QTAILQ_INSERT_HEAD(&g->reslist, res, next); + + resource_id = qemu_get_be32(f); + } + + /* load & apply scanout state */ + vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1); + for (i = 0; i < g->conf.max_outputs; i++) { + scanout = &g->scanout[i]; + if (!scanout->resource_id) { + continue; + } + res = virtio_gpu_find_resource(g, scanout->resource_id); + if (!res) { + return -EINVAL; + } + scanout->ds = qemu_create_displaysurface_pixman(res->image); + if (!scanout->ds) { + return -EINVAL; + } + + dpy_gfx_replace_surface(scanout->con, scanout->ds); + dpy_gfx_update(scanout->con, 0, 0, scanout->width, scanout->height); + update_cursor(g, &scanout->cursor); + res->scanout_bitmask |= (1 << i); + } + + return 0; +} + static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(qdev); @@ -979,7 +1162,12 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) } } - vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g); + if (virtio_gpu_virgl_enabled(g->conf)) { + vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g); + } else { + register_savevm(qdev, "virtio-gpu", -1, VIRTIO_GPU_VM_VERSION, + virtio_gpu_save, virtio_gpu_load, g); + } } static void virtio_gpu_instance_init(Object *obj) diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index f49f8deee7..315b7fc58c 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -84,6 +84,17 @@ static const GraphicHwOps virtio_vga_ops = { .gl_block = virtio_vga_gl_block, }; +static const VMStateDescription vmstate_virtio_vga = { + .name = "virtio-vga", + .version_id = 2, + .minimum_version_id = 2, + .fields = (VMStateField[]) { + /* no pci stuff here, saving the virtio device will handle that */ + VMSTATE_STRUCT(vga, VirtIOVGA, 0, vmstate_vga_common, VGACommonState), + VMSTATE_END_OF_LIST() + } +}; + /* VGA device wrapper around PCI device around virtio GPU */ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { @@ -168,6 +179,7 @@ static void virtio_vga_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); dc->props = virtio_vga_properties; dc->reset = virtio_vga_reset; + dc->vmsd = &vmstate_virtio_vga; dc->hotpluggable = false; k->realize = virtio_vga_realize; diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 0c63fa8513..e51a05ea7e 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -66,17 +66,11 @@ struct vmsvga_state_s { uint8_t *fifo_ptr; unsigned int fifo_size; - union { - uint32_t *fifo; - struct QEMU_PACKED { - uint32_t min; - uint32_t max; - uint32_t next_cmd; - uint32_t stop; - /* Add registers here when adding capabilities. */ - uint32_t fifo[0]; - } *cmd; - }; + uint32_t *fifo; + uint32_t fifo_min; + uint32_t fifo_max; + uint32_t fifo_next; + uint32_t fifo_stop; #define REDRAW_FIFO_LEN 512 struct vmsvga_rect_s { @@ -198,7 +192,7 @@ enum { */ SVGA_FIFO_MIN = 0, SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ - SVGA_FIFO_NEXT_CMD, + SVGA_FIFO_NEXT, SVGA_FIFO_STOP, /* @@ -546,8 +540,6 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s, } #endif -#define CMD(f) le32_to_cpu(s->cmd->f) - static inline int vmsvga_fifo_length(struct vmsvga_state_s *s) { int num; @@ -555,21 +547,45 @@ static inline int vmsvga_fifo_length(struct vmsvga_state_s *s) if (!s->config || !s->enable) { return 0; } - num = CMD(next_cmd) - CMD(stop); + + s->fifo_min = le32_to_cpu(s->fifo[SVGA_FIFO_MIN]); + s->fifo_max = le32_to_cpu(s->fifo[SVGA_FIFO_MAX]); + s->fifo_next = le32_to_cpu(s->fifo[SVGA_FIFO_NEXT]); + s->fifo_stop = le32_to_cpu(s->fifo[SVGA_FIFO_STOP]); + + /* Check range and alignment. */ + if ((s->fifo_min | s->fifo_max | s->fifo_next | s->fifo_stop) & 3) { + return 0; + } + if (s->fifo_min < sizeof(uint32_t) * 4) { + return 0; + } + if (s->fifo_max > SVGA_FIFO_SIZE || + s->fifo_min >= SVGA_FIFO_SIZE || + s->fifo_stop >= SVGA_FIFO_SIZE || + s->fifo_next >= SVGA_FIFO_SIZE) { + return 0; + } + if (s->fifo_max < s->fifo_min + 10 * 1024) { + return 0; + } + + num = s->fifo_next - s->fifo_stop; if (num < 0) { - num += CMD(max) - CMD(min); + num += s->fifo_max - s->fifo_min; } return num >> 2; } static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s) { - uint32_t cmd = s->fifo[CMD(stop) >> 2]; + uint32_t cmd = s->fifo[s->fifo_stop >> 2]; - s->cmd->stop = cpu_to_le32(CMD(stop) + 4); - if (CMD(stop) >= CMD(max)) { - s->cmd->stop = s->cmd->min; + s->fifo_stop += 4; + if (s->fifo_stop >= s->fifo_max) { + s->fifo_stop = s->fifo_min; } + s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop); return cmd; } @@ -581,15 +597,15 @@ static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s) static void vmsvga_fifo_run(struct vmsvga_state_s *s) { uint32_t cmd, colour; - int args, len; + int args, len, maxloop = 1024; int x, y, dx, dy, width, height; struct vmsvga_cursor_definition_s cursor; uint32_t cmd_start; len = vmsvga_fifo_length(s); - while (len > 0) { + while (len > 0 && --maxloop > 0) { /* May need to go back to the start of the command if incomplete */ - cmd_start = s->cmd->stop; + cmd_start = s->fifo_stop; switch (cmd = vmsvga_fifo_read(s)) { case SVGA_CMD_UPDATE: @@ -748,7 +764,8 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s) break; rewind: - s->cmd->stop = cmd_start; + s->fifo_stop = cmd_start; + s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop); break; } } @@ -1005,19 +1022,6 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) case SVGA_REG_CONFIG_DONE: if (value) { s->fifo = (uint32_t *) s->fifo_ptr; - /* Check range and alignment. */ - if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) { - break; - } - if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) { - break; - } - if (CMD(max) > SVGA_FIFO_SIZE) { - break; - } - if (CMD(max) < CMD(min) + 10 * 1024) { - break; - } vga_dirty_log_stop(&s->vga); } s->config = !!value; diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index ace65e0720..ab7cf9cbf8 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -347,7 +347,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret) scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, r->qiov.size, BLOCK_ACCT_READ); - r->req.aiocb = sdc->dma_readv(r->sector, &r->qiov, + r->req.aiocb = sdc->dma_readv(r->sector << BDRV_SECTOR_BITS, &r->qiov, scsi_read_complete, r, r); } diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 1602a13ba2..89f4879f55 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -32,6 +32,7 @@ struct virtio_gpu_simple_resource { uint32_t width; uint32_t height; uint32_t format; + uint64_t *addrs; struct iovec *iov; unsigned int iov_cnt; uint32_t scanout_bitmask; @@ -46,6 +47,7 @@ struct virtio_gpu_scanout { int x, y; int invalidate; uint32_t resource_id; + struct virtio_gpu_update_cursor cursor; QEMUCursor *current_cursor; }; @@ -150,7 +152,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, - struct iovec **iov); + uint64_t **addr, struct iovec **iov); void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count); void virtio_gpu_process_cmdq(VirtIOGPU *g); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 76dab154ee..f9b2426636 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -2994,7 +2994,8 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 1); qemu_log("\n"); diff --git a/target-cris/translate.c b/target-cris/translate.c index 2153ea7af6..cc515690e1 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3311,7 +3311,8 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS #if !DISAS_CRIS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { log_target_disas(cs, pc_start, dc->pc - pc_start, env->pregs[PR_VR]); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-i386/translate.c b/target-i386/translate.c index bf33e6b353..f010022fcd 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8354,7 +8354,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { int disas_flags; qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); diff --git a/target-lm32/translate.c b/target-lm32/translate.c index d09d81447b..526b4374e6 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1147,7 +1147,8 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-m68k/translate.c b/target-m68k/translate.c index f90187ff96..83db42a7d3 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -3067,7 +3067,8 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 513f390807..c54304aca5 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1818,7 +1818,8 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS #if !SIM_COMPAT - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); #if DISAS_GNU log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-mips/translate.c b/target-mips/translate.c index 3bd96aae97..f420680d1f 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -19913,7 +19913,8 @@ done_generating: #ifdef DEBUG_DISAS LOG_DISAS("\n"); - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index d4f1f260e4..c08876b14a 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -1751,7 +1751,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", diff --git a/target-ppc/translate.c b/target-ppc/translate.c index fe10bf8774..123e42fe6b 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -11642,7 +11642,8 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) tb->icount = num_insns; #if defined(DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { int flags; flags = env->bfd_mach; flags |= ctx.le_mode << 16; diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 2bbd1020c9..ce5db5dd46 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -5429,7 +5429,8 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) tb->icount = num_insns; #if defined(S390X_DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 1); qemu_log("\n"); diff --git a/target-sh4/translate.c b/target-sh4/translate.c index ff5222b04e..7518eb5508 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1924,7 +1924,8 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */ log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 21760b9fea..afd306fbab 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5330,7 +5330,8 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) tb->icount = num_insns; #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("--------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0); diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 83fa4fcd54..eb3deac889 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -8787,7 +8787,8 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) } #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index b04d22c9fb..c4d45fa0f4 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -2021,7 +2021,8 @@ done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 67efb32ef3..2a8e5c5d94 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -3153,7 +3153,8 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb) gen_tb_end(tb, insn_count); #ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) + && qemu_log_in_addr_range(pc_start)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 0); |