diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/acpi/core.c | 8 | ||||
| -rw-r--r-- | hw/block/virtio-blk.c | 10 | ||||
| -rw-r--r-- | hw/core/qdev-properties-system.c | 2 | ||||
| -rw-r--r-- | hw/display/qxl.c | 126 | ||||
| -rw-r--r-- | hw/display/qxl.h | 7 | ||||
| -rw-r--r-- | hw/display/trace-events | 2 | ||||
| -rw-r--r-- | hw/display/virtio-gpu-3d.c | 5 | ||||
| -rw-r--r-- | hw/display/virtio-gpu.c | 10 | ||||
| -rw-r--r-- | hw/pci/pcie_aer.c | 1 | ||||
| -rw-r--r-- | hw/ppc/spapr_drc.c | 4 | ||||
| -rw-r--r-- | hw/scsi/scsi-generic.c | 15 | ||||
| -rw-r--r-- | hw/virtio/virtio-balloon.c | 4 |
12 files changed, 119 insertions, 75 deletions
diff --git a/hw/acpi/core.c b/hw/acpi/core.c index d24b9a98c8..e890a5d675 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -239,11 +239,11 @@ void acpi_table_add(const QemuOpts *opts, Error **errp) char unsigned *blob = NULL; { - OptsVisitor *ov; + Visitor *v; - ov = opts_visitor_new(opts); - visit_type_AcpiTableOptions(opts_get_visitor(ov), NULL, &hdrs, &err); - opts_visitor_cleanup(ov); + v = opts_visitor_new(opts); + visit_type_AcpiTableOptions(v, NULL, &hdrs, &err); + visit_free(v); } if (err) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index fb43bbaa46..ae86e944ea 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -384,7 +384,7 @@ static int multireq_compare(const void *a, const void *b) void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) { int i = 0, start = 0, num_reqs = 0, niov = 0, nb_sectors = 0; - int max_xfer_len = 0; + uint32_t max_transfer; int64_t sector_num = 0; if (mrb->num_reqs == 1) { @@ -393,8 +393,7 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) return; } - max_xfer_len = blk_get_max_transfer_length(mrb->reqs[0]->dev->blk); - max_xfer_len = MIN_NON_ZERO(max_xfer_len, BDRV_REQUEST_MAX_SECTORS); + max_transfer = blk_get_max_transfer(mrb->reqs[0]->dev->blk); qsort(mrb->reqs, mrb->num_reqs, sizeof(*mrb->reqs), &multireq_compare); @@ -410,8 +409,9 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) */ if (sector_num + nb_sectors != req->sector_num || niov > blk_get_max_iov(blk) - req->qiov.niov || - req->qiov.size / BDRV_SECTOR_SIZE > max_xfer_len || - nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) { + req->qiov.size > max_transfer || + nb_sectors > (max_transfer - + req->qiov.size) / BDRV_SECTOR_SIZE) { submit_requests(blk, mrb, start, num_reqs, niov); num_reqs = 0; } diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 891219ae05..df38b8a03b 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -82,7 +82,7 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr, if (blk_attach_dev(blk, dev) < 0) { DriveInfo *dinfo = blk_legacy_dinfo(blk); - if (dinfo->type != IF_NONE) { + if (dinfo && dinfo->type != IF_NONE) { error_setg(errp, "Drive '%s' is already in use because " "it has been automatically connected to another " "device (did you need 'if=none' in the drive options?)", diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 919dc5cd36..46cc86690c 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -504,6 +504,7 @@ static void interface_set_compression_level(QXLInstance *sin, int level) qxl_rom_set_dirty(qxl); } +#if SPICE_NEEDS_SET_MM_TIME static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time) { PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); @@ -517,6 +518,7 @@ static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time) qxl->rom->mm_clock = cpu_to_le32(mm_time); qxl_rom_set_dirty(qxl); } +#endif static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) { @@ -893,7 +895,8 @@ static void interface_update_area_complete(QXLInstance *sin, int qxl_i; qemu_mutex_lock(&qxl->ssd.lock); - if (surface_id != 0 || !qxl->render_update_cookie_num) { + if (surface_id != 0 || !num_updated_rects || + !qxl->render_update_cookie_num) { qemu_mutex_unlock(&qxl->ssd.lock); return; } @@ -1068,7 +1071,9 @@ static const QXLInterface qxl_interface = { .attache_worker = interface_attach_worker, .set_compression_level = interface_set_compression_level, +#if SPICE_NEEDS_SET_MM_TIME .set_mm_time = interface_set_mm_time, +#endif .get_init_info = interface_get_init_info, /* the callbacks below are called from spice server thread context */ @@ -1243,6 +1248,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, int pci_region; pcibus_t pci_start; pcibus_t pci_end; + MemoryRegion *mr; intptr_t virt_start; QXLDevMemSlot memslot; int i; @@ -1289,11 +1295,11 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, switch (pci_region) { case QXL_RAM_RANGE_INDEX: - virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram); + mr = &d->vga.vram; break; case QXL_VRAM_RANGE_INDEX: case 4 /* vram 64bit */: - virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar); + mr = &d->vram_bar; break; default: /* should not happen */ @@ -1301,6 +1307,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, return 1; } + virt_start = (intptr_t)memory_region_get_ram_ptr(mr); memslot.slot_id = slot_id; memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */ memslot.virt_start = virt_start + (guest_start - pci_start); @@ -1310,7 +1317,8 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, qxl_rom_set_dirty(d); qemu_spice_add_memslot(&d->ssd, &memslot, async); - d->guest_slots[slot_id].ptr = (void*)memslot.virt_start; + d->guest_slots[slot_id].mr = mr; + d->guest_slots[slot_id].offset = memslot.virt_start - virt_start; d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start; d->guest_slots[slot_id].delta = delta; d->guest_slots[slot_id].active = 1; @@ -1337,39 +1345,60 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) } /* can be also called from spice server thread context */ -void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id) +static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, + uint32_t *s, uint64_t *o) { uint64_t phys = le64_to_cpu(pqxl); uint32_t slot = (phys >> (64 - 8)) & 0xff; uint64_t offset = phys & 0xffffffffffff; - switch (group_id) { - case MEMSLOT_GROUP_HOST: - return (void *)(intptr_t)offset; - case MEMSLOT_GROUP_GUEST: - if (slot >= NUM_MEMSLOTS) { - qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot, - NUM_MEMSLOTS); - return NULL; - } - if (!qxl->guest_slots[slot].active) { - qxl_set_guest_bug(qxl, "inactive slot %d\n", slot); - return NULL; - } - if (offset < qxl->guest_slots[slot].delta) { - qxl_set_guest_bug(qxl, + if (slot >= NUM_MEMSLOTS) { + qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot, + NUM_MEMSLOTS); + return false; + } + if (!qxl->guest_slots[slot].active) { + qxl_set_guest_bug(qxl, "inactive slot %d\n", slot); + return false; + } + if (offset < qxl->guest_slots[slot].delta) { + qxl_set_guest_bug(qxl, "slot %d offset %"PRIu64" < delta %"PRIu64"\n", slot, offset, qxl->guest_slots[slot].delta); - return NULL; - } - offset -= qxl->guest_slots[slot].delta; - if (offset > qxl->guest_slots[slot].size) { - qxl_set_guest_bug(qxl, + return false; + } + offset -= qxl->guest_slots[slot].delta; + if (offset > qxl->guest_slots[slot].size) { + qxl_set_guest_bug(qxl, "slot %d offset %"PRIu64" > size %"PRIu64"\n", slot, offset, qxl->guest_slots[slot].size); + return false; + } + + *s = slot; + *o = offset; + return true; +} + +/* can be also called from spice server thread context */ +void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id) +{ + uint64_t offset; + uint32_t slot; + void *ptr; + + switch (group_id) { + case MEMSLOT_GROUP_HOST: + offset = le64_to_cpu(pqxl) & 0xffffffffffff; + return (void *)(intptr_t)offset; + case MEMSLOT_GROUP_GUEST: + if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) { return NULL; } - return qxl->guest_slots[slot].ptr + offset; + ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr); + ptr += qxl->guest_slots[slot].offset; + ptr += offset; + return ptr; } return NULL; } @@ -1784,9 +1813,23 @@ static void qxl_hw_update(void *opaque) qxl_render_update(qxl); } +static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, + uint32_t height, int32_t stride) +{ + uint64_t offset; + uint32_t slot, size; + bool rc; + + rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset); + assert(rc == true); + size = height * abs(stride); + trace_qxl_surfaces_dirty(qxl->id, (int)offset, size); + qxl_set_dirty(qxl->guest_slots[slot].mr, + qxl->guest_slots[slot].offset + offset, size); +} + static void qxl_dirty_surfaces(PCIQXLDevice *qxl) { - uintptr_t vram_start; int i; if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) { @@ -1794,16 +1837,13 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) } /* dirty the primary surface */ - qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, - qxl->shadow_rom.surface0_area_size); - - vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); + qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem, + qxl->guest_primary.surface.height, + qxl->guest_primary.surface.stride); /* dirty the off-screen surfaces */ for (i = 0; i < qxl->ssd.num_surfaces; i++) { QXLSurfaceCmd *cmd; - intptr_t surface_offset; - int surface_size; if (qxl->guest_surfaces.cmds[i] == 0) { continue; @@ -1813,15 +1853,9 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) MEMSLOT_GROUP_GUEST); assert(cmd); assert(cmd->type == QXL_SURFACE_CMD_CREATE); - surface_offset = (intptr_t)qxl_phys2virt(qxl, - cmd->u.surface_create.data, - MEMSLOT_GROUP_GUEST); - assert(surface_offset); - surface_offset -= vram_start; - surface_size = cmd->u.surface_create.height * - abs(cmd->u.surface_create.stride); - trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size); - qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size); + qxl_dirty_one_surface(qxl, cmd->u.surface_create.data, + cmd->u.surface_create.height, + cmd->u.surface_create.stride); } } @@ -1914,7 +1948,7 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl) /* vram (surfaces, 64bit, bar 4+5) */ if (qxl->vram_size_mb != -1) { - qxl->vram_size = qxl->vram_size_mb * 1024 * 1024; + qxl->vram_size = (uint64_t)qxl->vram_size_mb * 1024 * 1024; } if (qxl->vram_size < qxl->vram32_size) { qxl->vram_size = qxl->vram32_size; @@ -2020,9 +2054,9 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) dprint(qxl, 1, "ram/%s: %d MB [region 0]\n", qxl->id == 0 ? "pri" : "sec", qxl->vga.vram_size / (1024*1024)); - dprint(qxl, 1, "vram/32: %d MB [region 1]\n", + dprint(qxl, 1, "vram/32: %" PRIx64 "d MB [region 1]\n", qxl->vram32_size / (1024*1024)); - dprint(qxl, 1, "vram/64: %d MB %s\n", + dprint(qxl, 1, "vram/64: %" PRIx64 "d MB %s\n", qxl->vram_size / (1024*1024), qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]"); @@ -2276,7 +2310,7 @@ static VMStateDescription qxl_vmstate = { static Property qxl_properties[] = { DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), - DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size, + DEFINE_PROP_UINT64("vram_size", PCIQXLDevice, vram32_size, 64 * 1024 * 1024), DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, QXL_DEFAULT_REVISION), diff --git a/hw/display/qxl.h b/hw/display/qxl.h index 2ddf065e1f..fdb619d4a7 100644 --- a/hw/display/qxl.h +++ b/hw/display/qxl.h @@ -53,7 +53,8 @@ typedef struct PCIQXLDevice { struct guest_slots { QXLMemSlot slot; - void *ptr; + MemoryRegion *mr; + uint64_t offset; uint64_t size; uint64_t delta; uint32_t active; @@ -104,9 +105,9 @@ typedef struct PCIQXLDevice { #endif /* vram pci bar */ - uint32_t vram_size; + uint64_t vram_size; MemoryRegion vram_bar; - uint32_t vram32_size; + uint64_t vram32_size; MemoryRegion vram32_bar; /* io bar */ diff --git a/hw/display/trace-events b/hw/display/trace-events index 30bebffd8b..9dd82cecde 100644 --- a/hw/display/trace-events +++ b/hw/display/trace-events @@ -105,7 +105,7 @@ qxl_spice_reset_image_cache(int qid) "%d" qxl_spice_reset_memslots(int qid) "%d" qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]" qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d" -qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d" +qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d" qxl_send_events(int qid, uint32_t events) "%d %d" qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d" qxl_set_guest_bug(int qid) "%d" diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c index 29918a090b..d6c8c6e2dc 100644 --- a/hw/display/virtio-gpu-3d.c +++ b/hw/display/virtio-gpu-3d.c @@ -171,13 +171,14 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, virgl_renderer_force_ctx_0(); dpy_gl_scanout(g->scanout[ss.scanout_id].con, info.tex_id, info.flags & 1 /* FIXME: Y_0_TOP */, + info.width, info.height, ss.r.x, ss.r.y, ss.r.width, ss.r.height); } else { if (ss.scanout_id != 0) { dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL); } dpy_gl_scanout(g->scanout[ss.scanout_id].con, 0, false, - 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); } g->scanout[ss.scanout_id].resource_id = ss.resource_id; } @@ -580,7 +581,7 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g) if (i != 0) { dpy_gfx_replace_surface(g->scanout[i].con, NULL); } - dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0); + dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0, 0, 0); } } diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 136c095b7d..f8b0274752 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -934,8 +934,14 @@ static void virtio_gpu_gl_block(void *opaque, bool block) { VirtIOGPU *g = opaque; - g->renderer_blocked = block; - if (!block) { + if (block) { + g->renderer_blocked++; + } else { + g->renderer_blocked--; + } + assert(g->renderer_blocked >= 0); + + if (g->renderer_blocked == 0) { virtio_gpu_process_cmdq(g); } } diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index e2d4e68ba3..048ce6a424 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" #include "qapi/qmp/types.h" +#include "qapi/qmp/qjson.h" #include "monitor/monitor.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pcie.h" diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index d276db3a72..26a067951c 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -300,7 +300,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */ g_assert(fdt_depth > 0); visit_check_struct(v, &err); - visit_end_struct(v); + visit_end_struct(v, NULL); if (err) { error_propagate(errp, err); return; @@ -323,7 +323,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, return; } } - visit_end_list(v); + visit_end_list(v, NULL); break; } default: diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 6a2d89afba..7a588a7ad4 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -225,13 +225,14 @@ static void scsi_read_complete(void * opaque, int ret) if (s->type == TYPE_DISK && r->req.cmd.buf[0] == INQUIRY && r->req.cmd.buf[2] == 0xb0) { - uint32_t max_xfer_len = blk_get_max_transfer_length(s->conf.blk); - if (max_xfer_len) { - stl_be_p(&r->buf[8], max_xfer_len); - /* Also take care of the opt xfer len. */ - if (ldl_be_p(&r->buf[12]) > max_xfer_len) { - stl_be_p(&r->buf[12], max_xfer_len); - } + uint32_t max_transfer = + blk_get_max_transfer(s->conf.blk) / s->blocksize; + + assert(max_transfer); + stl_be_p(&r->buf[8], max_transfer); + /* Also take care of the opt xfer len. */ + if (ldl_be_p(&r->buf[12]) > max_transfer) { + stl_be_p(&r->buf[12], max_transfer); } } scsi_req_data(&r->req, len); diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 557d3f9e0c..1a22e6d993 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -139,13 +139,13 @@ static void balloon_stats_get_all(Object *obj, Visitor *v, const char *name, } visit_check_struct(v, &err); out_nested: - visit_end_struct(v); + visit_end_struct(v, NULL); if (!err) { visit_check_struct(v, &err); } out_end: - visit_end_struct(v); + visit_end_struct(v, NULL); out: error_propagate(errp, err); } |