diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/pflash_cfi01.c | 18 | ||||
-rw-r--r-- | hw/char/cadence_uart.c | 3 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 12 | ||||
-rw-r--r-- | hw/ide/atapi.c | 26 | ||||
-rw-r--r-- | hw/ide/core.c | 39 | ||||
-rw-r--r-- | hw/ide/internal.h | 35 | ||||
-rw-r--r-- | hw/ide/macio.c | 2 | ||||
-rw-r--r-- | hw/ide/pci.c | 4 | ||||
-rw-r--r-- | hw/ide/piix.c | 1 | ||||
-rw-r--r-- | hw/input/virtio-input-hid.c | 6 | ||||
-rw-r--r-- | hw/input/virtio-input-host.c | 70 | ||||
-rw-r--r-- | hw/input/virtio-input.c | 46 | ||||
-rw-r--r-- | hw/misc/ivshmem.c | 30 | ||||
-rw-r--r-- | hw/misc/macio/cuda.c | 4 | ||||
-rw-r--r-- | hw/tpm/tpm_passthrough.c | 2 | ||||
-rw-r--r-- | hw/usb/hcd-ehci.c | 11 | ||||
-rw-r--r-- | hw/virtio/virtio-balloon.c | 5 |
17 files changed, 258 insertions, 56 deletions
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index c475c2aea7..106a775232 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -46,6 +46,7 @@ #include "exec/address-spaces.h" #include "qemu/host-utils.h" #include "hw/sysbus.h" +#include "sysemu/sysemu.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -97,6 +98,7 @@ struct pflash_t { MemoryRegion mem; char *name; void *storage; + VMChangeStateEntry *vmstate; }; static int pflash_post_load(void *opaque, int version_id); @@ -944,13 +946,25 @@ MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl) return &fl->mem; } +static void postload_update_cb(void *opaque, int running, RunState state) +{ + pflash_t *pfl = opaque; + + /* This is called after bdrv_invalidate_cache_all. */ + qemu_del_vm_change_state_handler(pfl->vmstate); + pfl->vmstate = NULL; + + DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name); + pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs); +} + static int pflash_post_load(void *opaque, int version_id) { pflash_t *pfl = opaque; if (!pfl->ro) { - DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name); - pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs); + pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb, + pfl); } return 0; } diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 486591bf07..797787823e 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -375,6 +375,9 @@ static void uart_write(void *opaque, hwaddr offset, DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value); offset >>= 2; + if (offset >= CADENCE_UART_R_MAX) { + return; + } switch (offset) { case R_IER: /* ier (wts imr) */ s->r[R_IMR] |= value; diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 35180efe0c..64770034ff 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2167,6 +2167,11 @@ build_dsdt(GArray *table_data, GArray *linker, 0, pci->w64.begin, pci->w64.end - 1, 0, pci->w64.end - pci->w64.begin)); } + + if (misc->tpm_version != TPM_VERSION_UNSPEC) { + aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE, + TPM_TIS_ADDR_SIZE, AML_READ_WRITE)); + } aml_append(scope, aml_name_decl("_CRS", crs)); /* reserve GPE0 block resources */ @@ -2343,7 +2348,12 @@ build_dsdt(GArray *table_data, GArray *linker, crs = aml_resource_template(); aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE, AML_READ_WRITE)); - aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ)); + /* + FIXME: TPM_TIS_IRQ=5 conflicts with PNP0C0F irqs, + Rewrite to take IRQ from TPM device model and + fix default IRQ value there to use some unused IRQ + */ + /* aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ)); */ aml_append(dev, aml_name_decl("_CRS", crs)); aml_append(scope, dev); } diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 1fe58ab7fd..2bb606c1c5 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -375,15 +375,18 @@ static void ide_atapi_cmd_check_status(IDEState *s) } /* ATAPI DMA support */ -/* XXX: handle read errors */ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) { IDEState *s = opaque; int data_offset, n; if (ret < 0) { - ide_atapi_io_error(s, ret); - goto eot; + if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) { + if (s->bus->error_status) { + return; + } + goto eot; + } } if (s->io_buffer_size > 0) { @@ -481,21 +484,16 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, } } - -/* Called by *_restart_bh when the transfer function points - * to ide_atapi_cmd - */ void ide_atapi_dma_restart(IDEState *s) { /* - * I'm not sure we have enough stored to restart the command - * safely, so give the guest an error it should recover from. - * I'm assuming most guests will try to recover from something - * listed as a medium error on a CD; it seems to work on Linux. - * This would be more of a problem if we did any other type of - * DMA operation. + * At this point we can just re-evaluate the packet command and start over. + * The presence of ->dma_cb callback in the pre_save ensures that the packet + * command has been completely sent and we can safely restart command. */ - ide_atapi_cmd_error(s, MEDIUM_ERROR, ASC_NO_SEEK_COMPLETE); + s->unit = s->bus->retry_unit; + s->bus->dma->ops->restart_dma(s->bus->dma); + ide_atapi_cmd(s); } static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index, diff --git a/hw/ide/core.c b/hw/ide/core.c index 90524d5e16..41e6a2dc45 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -57,7 +57,6 @@ static const int smart_attributes[][12] = { { 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32}, }; -static int ide_handle_rw_error(IDEState *s, int error, int op); static void ide_dummy_transfer_stop(IDEState *s); static void padstr(char *str, const char *src, int len) @@ -773,7 +772,7 @@ void ide_dma_error(IDEState *s) ide_set_irq(s->bus); } -static int ide_handle_rw_error(IDEState *s, int error, int op) +int ide_handle_rw_error(IDEState *s, int error, int op) { bool is_read = (op & IDE_RETRY_READ) != 0; BlockErrorAction action = blk_get_error_action(s->blk, is_read, error); @@ -783,8 +782,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) s->bus->error_status = op; } else if (action == BLOCK_ERROR_ACTION_REPORT) { block_acct_failed(blk_get_stats(s->blk), &s->acct); - if (op & IDE_RETRY_DMA) { + if (IS_IDE_RETRY_DMA(op)) { ide_dma_error(s); + } else if (IS_IDE_RETRY_ATAPI(op)) { + ide_atapi_io_error(s, -error); } else { ide_rw_error(s); } @@ -804,14 +805,7 @@ static void ide_dma_cb(void *opaque, int ret) return; } if (ret < 0) { - int op = IDE_RETRY_DMA; - - if (s->dma_cmd == IDE_DMA_READ) - op |= IDE_RETRY_READ; - else if (s->dma_cmd == IDE_DMA_TRIM) - op |= IDE_RETRY_TRIM; - - if (ide_handle_rw_error(s, -ret, op)) { + if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) { return; } } @@ -879,6 +873,8 @@ static void ide_dma_cb(void *opaque, int ret) ide_issue_trim, ide_dma_cb, s, DMA_DIRECTION_TO_DEVICE); break; + default: + abort(); } return; @@ -1641,6 +1637,9 @@ static bool cmd_packet(IDEState *s, uint8_t cmd) s->status = READY_STAT | SEEK_STAT; s->atapi_dma = s->feature & 1; + if (s->atapi_dma) { + s->dma_cmd = IDE_DMA_ATAPI; + } s->nsector = 1; ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, ide_atapi_cmd); @@ -2525,15 +2524,13 @@ static void ide_restart_bh(void *opaque) if (s->bus->dma->ops->restart) { s->bus->dma->ops->restart(s->bus->dma); } - } - - if (error_status & IDE_RETRY_DMA) { + } else if (IS_IDE_RETRY_DMA(error_status)) { if (error_status & IDE_RETRY_TRIM) { ide_restart_dma(s, IDE_DMA_TRIM); } else { ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); } - } else if (error_status & IDE_RETRY_PIO) { + } else if (IS_IDE_RETRY_PIO(error_status)) { if (is_read) { ide_sector_read(s); } else { @@ -2541,15 +2538,11 @@ static void ide_restart_bh(void *opaque) } } else if (error_status & IDE_RETRY_FLUSH) { ide_flush_cache(s); + } else if (IS_IDE_RETRY_ATAPI(error_status)) { + assert(s->end_transfer_func == ide_atapi_cmd); + ide_atapi_dma_restart(s); } else { - /* - * We've not got any bits to tell us about ATAPI - but - * we do have the end_transfer_func that tells us what - * we're trying to do. - */ - if (s->end_transfer_func == ide_atapi_cmd) { - ide_atapi_dma_restart(s); - } + abort(); } } diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 86bde26551..d2c458f579 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -338,6 +338,7 @@ enum ide_dma_cmd { IDE_DMA_READ, IDE_DMA_WRITE, IDE_DMA_TRIM, + IDE_DMA_ATAPI, }; #define ide_cmd_is_read(s) \ @@ -506,13 +507,45 @@ struct IDEDevice { }; /* These are used for the error_status field of IDEBus */ +#define IDE_RETRY_MASK 0xf8 #define IDE_RETRY_DMA 0x08 #define IDE_RETRY_PIO 0x10 +#define IDE_RETRY_ATAPI 0x20 /* reused IDE_RETRY_READ bit */ #define IDE_RETRY_READ 0x20 #define IDE_RETRY_FLUSH 0x40 #define IDE_RETRY_TRIM 0x80 #define IDE_RETRY_HBA 0x100 +#define IS_IDE_RETRY_DMA(_status) \ + ((_status) & IDE_RETRY_DMA) + +#define IS_IDE_RETRY_PIO(_status) \ + ((_status) & IDE_RETRY_PIO) + +/* + * The method of the IDE_RETRY_ATAPI determination is to use a previously + * impossible bit combination as a new status value. + */ +#define IS_IDE_RETRY_ATAPI(_status) \ + (((_status) & IDE_RETRY_MASK) == IDE_RETRY_ATAPI) + +static inline uint8_t ide_dma_cmd_to_retry(uint8_t dma_cmd) +{ + switch (dma_cmd) { + case IDE_DMA_READ: + return IDE_RETRY_DMA | IDE_RETRY_READ; + case IDE_DMA_WRITE: + return IDE_RETRY_DMA; + case IDE_DMA_TRIM: + return IDE_RETRY_DMA | IDE_RETRY_TRIM; + case IDE_DMA_ATAPI: + return IDE_RETRY_ATAPI; + default: + break; + } + return 0; +} + static inline IDEState *idebus_active_if(IDEBus *bus) { return bus->ifs + bus->unit; @@ -597,4 +630,6 @@ void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev, int bus_id, int max_units); IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive); +int ide_handle_rw_error(IDEState *s, int error, int op); + #endif /* HW_IDE_INTERNAL_H */ diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 1725e5b23f..76256eb8a8 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -346,6 +346,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) case IDE_DMA_TRIM: pmac_dma_trim(s->blk, offset, io->len, pmac_ide_transfer_cb, io); break; + default: + abort(); } return; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 92ffee7264..8d56a00b1b 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -308,6 +308,10 @@ static void ide_bmdma_pre_save(void *opaque) BMDMAState *bm = opaque; uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + if (!(bm->status & BM_STATUS_DMAING) && bm->dma_cb) { + bm->bus->error_status = + ide_dma_cmd_to_retry(bmdma_active_if(bm)->dma_cmd); + } bm->migration_retry_unit = bm->bus->retry_unit; bm->migration_retry_sector_num = bm->bus->retry_sector_num; bm->migration_retry_nsector = bm->bus->retry_nsector; diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 0a4cbcbcbb..6d76ce980b 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -189,6 +189,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) idedev = pci_ide->bus[di->bus].slave; } idedev->conf.blk = NULL; + monitor_remove_blk(blk); blk_unref(blk); } } diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 5d12157114..3ee0c1814a 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -121,6 +121,8 @@ static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL, [Q_KEY_CODE_SYSRQ] = KEY_SYSRQ, + [Q_KEY_CODE_PRINT] = KEY_SYSRQ, + [Q_KEY_CODE_PAUSE] = KEY_PAUSE, [Q_KEY_CODE_ALT_R] = KEY_RIGHTALT, [Q_KEY_CODE_HOME] = KEY_HOME, @@ -482,12 +484,12 @@ static struct virtio_input_config virtio_tablet_config[] = { .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_X, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), },{ .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_Y, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), }, { /* end of list */ }, }; diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index 9e0f46d88f..cb79e80024 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -70,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih, virtio_input_add_config(VIRTIO_INPUT(vih), &bits); } +static void virtio_input_abs_config(VirtIOInputHost *vih, int axis) +{ + virtio_input_config config; + struct input_absinfo absinfo; + int rc; + + rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo); + if (rc < 0) { + return; + } + + memset(&config, 0, sizeof(config)); + config.select = VIRTIO_INPUT_CFG_ABS_INFO; + config.subsel = axis; + config.size = sizeof(virtio_input_absinfo); + + config.u.abs.min = cpu_to_le32(absinfo.minimum); + config.u.abs.max = cpu_to_le32(absinfo.maximum); + config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz); + config.u.abs.flat = cpu_to_le32(absinfo.flat); + config.u.abs.res = cpu_to_le32(absinfo.resolution); + + virtio_input_add_config(VIRTIO_INPUT(vih), &config); +} + static void virtio_input_host_realize(DeviceState *dev, Error **errp) { VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); VirtIOInput *vinput = VIRTIO_INPUT(dev); - virtio_input_config id; + virtio_input_config id, *abs; struct input_id ids; - int rc, ver; + int rc, ver, i, axis; + uint8_t byte; if (!vih->evdev) { error_setg(errp, "evdev property is required"); @@ -125,6 +151,23 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp) virtio_input_bits_config(vih, EV_ABS, ABS_CNT); virtio_input_bits_config(vih, EV_MSC, MSC_CNT); virtio_input_bits_config(vih, EV_SW, SW_CNT); + virtio_input_bits_config(vih, EV_LED, LED_CNT); + + abs = virtio_input_find_config(VIRTIO_INPUT(vih), + VIRTIO_INPUT_CFG_EV_BITS, EV_ABS); + if (abs) { + for (i = 0; i < abs->size; i++) { + byte = abs->u.bitmap[i]; + axis = 8 * i; + while (byte) { + if (byte & 1) { + virtio_input_abs_config(vih, axis); + } + axis++; + byte >>= 1; + } + } + } qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); return; @@ -145,6 +188,28 @@ static void virtio_input_host_unrealize(DeviceState *dev, Error **errp) } } +static void virtio_input_host_handle_status(VirtIOInput *vinput, + virtio_input_event *event) +{ + VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput); + struct input_event evdev; + int rc; + + if (gettimeofday(&evdev.time, NULL)) { + perror("virtio_input_host_handle_status: gettimeofday"); + return; + } + + evdev.type = le16_to_cpu(event->type); + evdev.code = le16_to_cpu(event->code); + evdev.value = le32_to_cpu(event->value); + + rc = write(vih->fd, &evdev, sizeof(evdev)); + if (rc == -1) { + perror("virtio_input_host_handle_status: write"); + } +} + static const VMStateDescription vmstate_virtio_input_host = { .name = "virtio-input-host", .unmigratable = 1, @@ -164,6 +229,7 @@ static void virtio_input_host_class_init(ObjectClass *klass, void *data) dc->props = virtio_input_host_properties; vic->realize = virtio_input_host_realize; vic->unrealize = virtio_input_host_unrealize; + vic->handle_status = virtio_input_host_handle_status; } static void virtio_input_host_init(Object *obj) diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 672c207eb5..f59749a943 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -14,6 +14,8 @@ #include "standard-headers/linux/input.h" +#define VIRTIO_INPUT_VM_VERSION 1 + /* ----------------------------------------------------------------- */ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) @@ -97,9 +99,9 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq) virtio_notify(vdev, vinput->sts); } -static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, - uint8_t select, - uint8_t subsel) +virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, + uint8_t select, + uint8_t subsel) { VirtIOInputConfig *cfg; @@ -214,6 +216,38 @@ static void virtio_input_reset(VirtIODevice *vdev) } } +static void virtio_input_save(QEMUFile *f, void *opaque) +{ + VirtIOInput *vinput = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + + virtio_save(vdev, f); +} + +static int virtio_input_load(QEMUFile *f, void *opaque, int version_id) +{ + VirtIOInput *vinput = opaque; + VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput); + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + int ret; + + if (version_id != VIRTIO_INPUT_VM_VERSION) { + return -EINVAL; + } + + ret = virtio_load(vdev, f, version_id); + if (ret) { + return ret; + } + + /* post_load() */ + vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK; + if (vic->change_active) { + vic->change_active(vinput); + } + return 0; +} + static void virtio_input_device_realize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); @@ -245,14 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) vinput->cfg_size); vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); + + register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION, + virtio_input_save, virtio_input_load, vinput); } static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOInput *vinput = VIRTIO_INPUT(dev); Error *local_err = NULL; + unregister_savevm(dev, "virtio-input", vinput); + if (vic->unrealize) { vic->unrealize(dev, &local_err); if (local_err) { diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 2eb866899a..e40f23bfc2 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -872,6 +872,8 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem, &error_abort); } else { + assert(s->server_chr); + IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", s->server_chr->filename); @@ -1051,10 +1053,24 @@ static void ivshmem_plain_init(Object *obj) &error_abort); } +static void ivshmem_plain_realize(PCIDevice *dev, Error **errp) +{ + IVShmemState *s = IVSHMEM_COMMON(dev); + + if (!s->hostmem) { + error_setg(errp, "You must specify a 'memdev'"); + return; + } + + ivshmem_common_realize(dev, errp); +} + static void ivshmem_plain_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + k->realize = ivshmem_plain_realize; dc->props = ivshmem_plain_properties; dc->vmsd = &ivshmem_plain_vmsd; } @@ -1099,10 +1115,24 @@ static void ivshmem_doorbell_init(Object *obj) s->legacy_size = SIZE_MAX; /* whatever the server sends */ } +static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp) +{ + IVShmemState *s = IVSHMEM_COMMON(dev); + + if (!s->server_chr) { + error_setg(errp, "You must specify a 'chardev'"); + return; + } + + ivshmem_common_realize(dev, errp); +} + static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + k->realize = ivshmem_doorbell_realize; dc->props = ivshmem_doorbell_properties; dc->vmsd = &ivshmem_doorbell_vmsd; } diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index c7472aaa9d..f15f301100 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -685,8 +685,8 @@ static bool cuda_cmd_set_time(CUDAState *s, return false; } - ti = (((uint32_t)in_data[1]) << 24) + (((uint32_t)in_data[2]) << 16) - + (((uint32_t)in_data[3]) << 8) + in_data[4]; + ti = (((uint32_t)in_data[0]) << 24) + (((uint32_t)in_data[1]) << 16) + + (((uint32_t)in_data[2]) << 8) + in_data[3]; s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / NANOSECONDS_PER_SECOND); return true; diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c index e98efb709e..e88c0d20bc 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -86,7 +86,7 @@ static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len) int ret, remain; remain = len; - while (len > 0) { + while (remain > 0) { ret = write(fd, buf, remain); if (ret < 0) { if (errno != EINTR && errno != EAGAIN) { diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 159f58d5a0..43a8f7abcc 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1397,7 +1397,7 @@ static int ehci_process_itd(EHCIState *ehci, { USBDevice *dev; USBEndpoint *ep; - uint32_t i, len, pid, dir, devaddr, endp, xfers = 0; + uint32_t i, len, pid, dir, devaddr, endp; uint32_t pg, off, ptr1, ptr2, max, mult; ehci->periodic_sched_active = PERIODIC_ACTIVE; @@ -1489,10 +1489,9 @@ static int ehci_process_itd(EHCIState *ehci, ehci_raise_irq(ehci, USBSTS_INT); } itd->transact[i] &= ~ITD_XACT_ACTIVE; - xfers++; } } - return xfers ? 0 : -1; + return 0; } @@ -2011,6 +2010,7 @@ static int ehci_state_writeback(EHCIQueue *q) static void ehci_advance_state(EHCIState *ehci, int async) { EHCIQueue *q = NULL; + int itd_count = 0; int again; do { @@ -2035,10 +2035,12 @@ static void ehci_advance_state(EHCIState *ehci, int async) case EST_FETCHITD: again = ehci_state_fetchitd(ehci, async); + itd_count++; break; case EST_FETCHSITD: again = ehci_state_fetchsitd(ehci, async); + itd_count++; break; case EST_ADVANCEQUEUE: @@ -2087,7 +2089,8 @@ static void ehci_advance_state(EHCIState *ehci, int async) break; } - if (again < 0) { + if (again < 0 || itd_count > 16) { + /* TODO: notify guest (raise HSE irq?) */ fprintf(stderr, "processing error - resetting ehci HC\n"); ehci_reset(ehci); again = 0; diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index c74101e479..9dbe681790 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -19,7 +19,6 @@ #include "qemu-common.h" #include "hw/virtio/virtio.h" #include "hw/i386/pc.h" -#include "cpu.h" #include "sysemu/balloon.h" #include "hw/virtio/virtio-balloon.h" #include "sysemu/kvm.h" @@ -35,12 +34,14 @@ #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" +#define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT) + static void balloon_page(void *addr, int deflate) { #if defined(__linux__) if (!qemu_balloon_is_inhibited() && (!kvm_enabled() || kvm_has_sync_mmu())) { - qemu_madvise(addr, TARGET_PAGE_SIZE, + qemu_madvise(addr, BALLOON_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); } #endif |