diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-09-23 12:08:55 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-09-23 12:08:55 +0100 |
commit | 380f649e02f9545159dc3158d7c1b2e70c1005e3 (patch) | |
tree | 0b78130d8ffe96e3020f0435e4b75d33c74da8b8 /hw | |
parent | 17336812c7906b554765d1b48b7f1f51c5c79702 (diff) | |
parent | 52b53c04faab9f7a9879c8dc014930649a3e698d (diff) |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Mon 22 Sep 2014 12:41:59 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/block-pull-request: (59 commits)
block: Always compile virtio-blk dataplane
vring: Better error handling if num is too large
virtio: Import virtio_vring.h
async: aio_context_new(): Handle event_notifier_init failure
block: vhdx - fix reading beyond pointer during image creation
block: delete cow block driver
block/archipelago: Fix typo in qemu_archipelago_truncate()
ahci: Add test_identify case to ahci-test.
ahci: Add test_hba_enable to ahci-test.
ahci: Add test_hba_spec to ahci-test.
ahci: properly shadow the TFD register
ahci: add test_pci_enable to ahci-test.
ahci: Add test_pci_spec to ahci-test.
ahci: MSI capability should be at 0x80, not 0x50.
ahci: Adding basic functionality qtest.
layout: Add generators for refcount table and blocks
fuzz: Add fuzzing functions for entries of refcount table and blocks
docs: List all image elements currently supported by the fuzzer
qapi/block-core: Add "new" qcow2 options
qcow2: Add overlap-check.template option
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/block/virtio-blk.c | 20 | ||||
-rw-r--r-- | hw/ide/ahci.c | 45 | ||||
-rw-r--r-- | hw/ide/atapi.c | 7 | ||||
-rw-r--r-- | hw/ide/core.c | 26 | ||||
-rw-r--r-- | hw/ide/ich.c | 7 | ||||
-rw-r--r-- | hw/net/vhost_net.c | 2 | ||||
-rw-r--r-- | hw/virtio/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/virtio/dataplane/vring.c | 3 |
9 files changed, 65 insertions, 49 deletions
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index bf46f03b7e..d4c3ab758d 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -12,4 +12,4 @@ common-obj-$(CONFIG_NVME_PCI) += nvme.o obj-$(CONFIG_SH4) += tc58128.o obj-$(CONFIG_VIRTIO) += virtio-blk.o -obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/ +obj-$(CONFIG_VIRTIO) += dataplane/ diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 38ad38f49f..45e0c8f6e9 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -18,10 +18,8 @@ #include "hw/block/block.h" #include "sysemu/blockdev.h" #include "hw/virtio/virtio-blk.h" -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE -# include "dataplane/virtio-blk.h" -# include "migration/migration.h" -#endif +#include "dataplane/virtio-blk.h" +#include "migration/migration.h" #include "block/scsi.h" #ifdef __linux__ # include <scsi/sg.h> @@ -435,7 +433,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) .num_writes = 0, }; -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start * dataplane here instead of waiting for .set_status(). */ @@ -443,7 +440,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) virtio_blk_data_plane_start(s->dataplane); return; } -#endif while ((req = virtio_blk_get_request(s))) { virtio_blk_handle_request(req, &mrb); @@ -500,11 +496,9 @@ static void virtio_blk_reset(VirtIODevice *vdev) { VirtIOBlock *s = VIRTIO_BLK(vdev); -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE if (s->dataplane) { virtio_blk_data_plane_stop(s->dataplane); } -#endif /* * This should cancel pending requests, but can't do nicely until there @@ -594,12 +588,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) VirtIOBlock *s = VIRTIO_BLK(vdev); uint32_t features; -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK))) { virtio_blk_data_plane_stop(s->dataplane); } -#endif if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { return; @@ -694,7 +686,6 @@ static const BlockDevOps virtio_block_ops = { .resize_cb = virtio_blk_resize, }; -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE /* Disable dataplane thread during live migration since it does not * update the dirty memory bitmap yet. */ @@ -725,7 +716,6 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data) } } } -#endif /* CONFIG_VIRTIO_BLK_DATA_PLANE */ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) { @@ -762,7 +752,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output); s->complete_request = virtio_blk_complete_request; -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err); if (err != NULL) { error_propagate(errp, err); @@ -771,7 +760,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) } s->migration_state_notifier.notify = virtio_blk_migration_state_changed; add_migration_state_change_notifier(&s->migration_state_notifier); -#endif s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); register_savevm(dev, "virtio-blk", virtio_blk_id++, 2, @@ -789,11 +777,9 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp) VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOBlock *s = VIRTIO_BLK(dev); -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE remove_migration_state_change_notifier(&s->migration_state_notifier); virtio_blk_data_plane_destroy(s->dataplane); s->dataplane = NULL; -#endif qemu_del_vm_change_state_handler(s->change); unregister_savevm(dev, "virtio-blk", s); blockdev_mark_auto_del(s->bs); @@ -818,9 +804,7 @@ static Property virtio_blk_properties[] = { #ifdef __linux__ DEFINE_PROP_BIT("scsi", VirtIOBlock, blk.scsi, 0, true), #endif -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE DEFINE_PROP_BIT("x-data-plane", VirtIOBlock, blk.data_plane, 0, false), -#endif DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index ba69de30e0..8978643fff 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -78,8 +78,7 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset) val = pr->cmd; break; case PORT_TFDATA: - val = ((uint16_t)s->dev[port].port.ifs[0].error << 8) | - s->dev[port].port.ifs[0].status; + val = pr->tfdata; break; case PORT_SIG: val = pr->sig; @@ -251,14 +250,13 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) check_cmd(s, port); break; case PORT_TFDATA: - s->dev[port].port.ifs[0].error = (val >> 8) & 0xff; - s->dev[port].port.ifs[0].status = val & 0xff; + /* Read Only. */ break; case PORT_SIG: - pr->sig = val; + /* Read Only */ break; case PORT_SCR_STAT: - pr->scr_stat = val; + /* Read Only */ break; case PORT_SCR_CTL: if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) && @@ -497,6 +495,8 @@ static void ahci_reset_port(AHCIState *s, int port) pr->scr_stat = 0; pr->scr_err = 0; pr->scr_act = 0; + pr->tfdata = 0x7F; + pr->sig = 0xFFFFFFFF; d->busy_slot = -1; d->init_d2h_sent = false; @@ -528,16 +528,16 @@ static void ahci_reset_port(AHCIState *s, int port) s->dev[port].port_state = STATE_RUN; if (!ide_state->bs) { - s->dev[port].port_regs.sig = 0; + pr->sig = 0; ide_state->status = SEEK_STAT | WRERR_STAT; } else if (ide_state->drive_kind == IDE_CD) { - s->dev[port].port_regs.sig = SATA_SIGNATURE_CDROM; + pr->sig = SATA_SIGNATURE_CDROM; ide_state->lcyl = 0x14; ide_state->hcyl = 0xeb; DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl); ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT; } else { - s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK; + pr->sig = SATA_SIGNATURE_DISK; ide_state->status = SEEK_STAT | WRERR_STAT; } @@ -563,7 +563,8 @@ static void debug_print_fis(uint8_t *fis, int cmd_len) static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) { - AHCIPortRegs *pr = &s->dev[port].port_regs; + AHCIDevice *ad = &s->dev[port]; + AHCIPortRegs *pr = &ad->port_regs; IDEState *ide_state; uint8_t *sdb_fis; @@ -572,8 +573,8 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) return; } - sdb_fis = &s->dev[port].res_fis[RES_FIS_SDBFIS]; - ide_state = &s->dev[port].port.ifs[0]; + sdb_fis = &ad->res_fis[RES_FIS_SDBFIS]; + ide_state = &ad->port.ifs[0]; /* clear memory */ *(uint32_t*)sdb_fis = 0; @@ -582,9 +583,14 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) sdb_fis[0] = ide_state->error; sdb_fis[2] = ide_state->status & 0x77; s->dev[port].finished |= finished; - *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(s->dev[port].finished); + *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(ad->finished); + + /* Update shadow registers (except BSY 0x80 and DRQ 0x08) */ + pr->tfdata = (ad->port.ifs[0].error << 8) | + (ad->port.ifs[0].status & 0x77) | + (pr->tfdata & 0x88); - ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_SDB_FIS); + ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS); } static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len) @@ -642,6 +648,10 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len) pio_fis[18] = 0; pio_fis[19] = 0; + /* Update shadow registers: */ + pr->tfdata = (ad->port.ifs[0].error << 8) | + ad->port.ifs[0].status; + if (pio_fis[2] & ERR_STAT) { ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR); } @@ -693,6 +703,10 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis) d2h_fis[i] = 0; } + /* Update shadow registers: */ + pr->tfdata = (ad->port.ifs[0].error << 8) | + ad->port.ifs[0].status; + if (d2h_fis[2] & ERR_STAT) { ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR); } @@ -791,6 +805,9 @@ static void ncq_cb(void *opaque, int ret) NCQTransferState *ncq_tfs = (NCQTransferState *)opaque; IDEState *ide_state = &ncq_tfs->drive->port.ifs[0]; + if (ret == -ECANCELED) { + return; + } /* Clear bit for this tag in SActive */ ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag); diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 6d52cda4cc..10218dfa3a 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -136,6 +136,7 @@ void ide_atapi_cmd_ok(IDEState *s) s->error = 0; s->status = READY_STAT | SEEK_STAT; s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; + ide_transfer_stop(s); ide_set_irq(s->bus); } @@ -149,6 +150,7 @@ void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc) s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; s->sense_key = sense_key; s->asc = asc; + ide_transfer_stop(s); ide_set_irq(s->bus); } @@ -176,9 +178,7 @@ void ide_atapi_cmd_reply_end(IDEState *s) #endif if (s->packet_transfer_size <= 0) { /* end of transfer */ - s->status = READY_STAT | SEEK_STAT; - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; - ide_transfer_stop(s); + ide_atapi_cmd_ok(s); ide_set_irq(s->bus); #ifdef DEBUG_IDE_ATAPI printf("status=0x%x\n", s->status); @@ -188,7 +188,6 @@ void ide_atapi_cmd_reply_end(IDEState *s) if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) { ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size); if (ret < 0) { - ide_transfer_stop(s); ide_atapi_io_error(s, ret); return; } diff --git a/hw/ide/core.c b/hw/ide/core.c index 6fba056783..190700ac74 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -372,23 +372,21 @@ static void trim_aio_cancel(BlockDriverAIOCB *acb) { TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common); - /* Exit the loop in case bdrv_aio_cancel calls ide_issue_trim_cb again. */ + /* Exit the loop so ide_issue_trim_cb will not continue */ iocb->j = iocb->qiov->niov - 1; iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1; - /* Tell ide_issue_trim_cb not to trigger the completion, too. */ - qemu_bh_delete(iocb->bh); - iocb->bh = NULL; + iocb->ret = -ECANCELED; if (iocb->aiocb) { - bdrv_aio_cancel(iocb->aiocb); + bdrv_aio_cancel_async(iocb->aiocb); + iocb->aiocb = NULL; } - qemu_aio_release(iocb); } static const AIOCBInfo trim_aiocb_info = { .aiocb_size = sizeof(TrimAIOCB), - .cancel = trim_aio_cancel, + .cancel_async = trim_aio_cancel, }; static void ide_trim_bh_cb(void *opaque) @@ -399,7 +397,7 @@ static void ide_trim_bh_cb(void *opaque) qemu_bh_delete(iocb->bh); iocb->bh = NULL; - qemu_aio_release(iocb); + qemu_aio_unref(iocb); } static void ide_issue_trim_cb(void *opaque, int ret) @@ -568,6 +566,9 @@ static void ide_sector_read_cb(void *opaque, int ret) s->pio_aiocb = NULL; s->status &= ~BUSY_STAT; + if (ret == -ECANCELED) { + return; + } block_acct_done(bdrv_get_stats(s->bs), &s->acct); if (ret != 0) { if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO | @@ -678,6 +679,9 @@ void ide_dma_cb(void *opaque, int ret) int64_t sector_num; bool stay_active = false; + if (ret == -ECANCELED) { + return; + } if (ret < 0) { int op = IDE_RETRY_DMA; @@ -803,6 +807,9 @@ static void ide_sector_write_cb(void *opaque, int ret) IDEState *s = opaque; int n; + if (ret == -ECANCELED) { + return; + } block_acct_done(bdrv_get_stats(s->bs), &s->acct); s->pio_aiocb = NULL; @@ -882,6 +889,9 @@ static void ide_flush_cb(void *opaque, int ret) s->pio_aiocb = NULL; + if (ret == -ECANCELED) { + return; + } if (ret < 0) { /* XXX: What sector number to set here? */ if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) { diff --git a/hw/ide/ich.c b/hw/ide/ich.c index a2f1639310..8eb77a1472 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -71,6 +71,7 @@ #include <hw/ide/pci.h> #include <hw/ide/ahci.h> +#define ICH9_MSI_CAP_OFFSET 0x80 #define ICH9_SATA_CAP_OFFSET 0xA8 #define ICH9_IDP_BAR 4 @@ -115,7 +116,6 @@ static int pci_ich9_ahci_init(PCIDevice *dev) /* XXX Software should program this register */ dev->config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */ - msi_init(dev, 0x50, 1, true, false); d->ahci.irq = pci_allocate_irq(dev); pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO, @@ -135,6 +135,11 @@ static int pci_ich9_ahci_init(PCIDevice *dev) (ICH9_IDP_BAR + 0x4) | (ICH9_IDP_INDEX_LOG2 << 4)); d->ahci.idp_offset = ICH9_IDP_INDEX; + /* Although the AHCI 1.3 specification states that the first capability + * should be PMCAP, the Intel ICH9 data sheet specifies that the ICH9 + * AHCI device puts the MSI capability first, pointing to 0x80. */ + msi_init(dev, ICH9_MSI_CAP_OFFSET, 1, true, false); + return 0; } diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 77bb93e4d7..4e3a061622 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -28,7 +28,6 @@ #include <sys/socket.h> #include <linux/kvm.h> #include <fcntl.h> -#include <linux/virtio_ring.h> #include <netpacket/packet.h> #include <net/ethernet.h> #include <net/if.h> @@ -36,6 +35,7 @@ #include <stdio.h> +#include "hw/virtio/virtio_ring.h" #include "hw/virtio/vhost.h" #include "hw/virtio/virtio-bus.h" diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index ec9e855bc1..d21c397756 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o common-obj-y += virtio-bus.o common-obj-y += virtio-mmio.o -common-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/ +common-obj-$(CONFIG_VIRTIO) += dataplane/ obj-y += virtio.o virtio-balloon.o obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c index 67cb2b823e..372706a234 100644 --- a/hw/virtio/dataplane/vring.c +++ b/hw/virtio/dataplane/vring.c @@ -181,7 +181,8 @@ static int get_desc(Vring *vring, VirtQueueElement *elem, /* Stop for now if there are not enough iovecs available. */ if (*num >= VIRTQUEUE_MAX_SIZE) { - return -ENOBUFS; + error_report("Invalid SG num: %u", *num); + return -EFAULT; } /* TODO handle non-contiguous memory across region boundaries */ |