diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/dataplane/virtio-blk.c | 2 | ||||
-rw-r--r-- | hw/ide/ahci.c | 32 | ||||
-rw-r--r-- | hw/ide/ahci.h | 2 |
3 files changed, 23 insertions, 13 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 4c5ba18122..4bc0729bf7 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -84,6 +84,7 @@ static void handle_notify(EventNotifier *e) }; event_notifier_test_and_clear(&s->host_notifier); + bdrv_io_plug(s->blk->conf.bs); for (;;) { /* Disable guest->host notifies to avoid unnecessary vmexits */ vring_disable_notification(s->vdev, &s->vring); @@ -117,6 +118,7 @@ static void handle_notify(EventNotifier *e) break; } } + bdrv_io_unplug(s->blk->conf.bs); } /* Context: QEMU global mutex held */ diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 9bae22ecb1..604152a823 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -175,17 +175,18 @@ static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d, ahci_check_irq(s); } -static void map_page(uint8_t **ptr, uint64_t addr, uint32_t wanted) +static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr, + uint32_t wanted) { hwaddr len = wanted; if (*ptr) { - cpu_physical_memory_unmap(*ptr, len, 1, len); + dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len); } - *ptr = cpu_physical_memory_map(addr, &len, 1); + *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE); if (len < wanted) { - cpu_physical_memory_unmap(*ptr, len, 1, len); + dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len); *ptr = NULL; } } @@ -198,24 +199,24 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) switch (offset) { case PORT_LST_ADDR: pr->lst_addr = val; - map_page(&s->dev[port].lst, + map_page(s->as, &s->dev[port].lst, ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024); s->dev[port].cur_cmd = NULL; break; case PORT_LST_ADDR_HI: pr->lst_addr_hi = val; - map_page(&s->dev[port].lst, + map_page(s->as, &s->dev[port].lst, ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024); s->dev[port].cur_cmd = NULL; break; case PORT_FIS_ADDR: pr->fis_addr = val; - map_page(&s->dev[port].res_fis, + map_page(s->as, &s->dev[port].res_fis, ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); break; case PORT_FIS_ADDR_HI: pr->fis_addr_hi = val; - map_page(&s->dev[port].res_fis, + map_page(s->as, &s->dev[port].res_fis, ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); break; case PORT_IRQ_STAT: @@ -639,6 +640,11 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis) } } +static int prdt_tbl_entry_size(const AHCI_SG *tbl) +{ + return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1; +} + static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset) { AHCICmdHdr *cmd = ad->cur_cmd; @@ -681,7 +687,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset) sum = 0; for (i = 0; i < sglist_alloc_hint; i++) { /* flags_size is zero-based */ - tbl_entry_size = (le32_to_cpu(tbl[i].flags_size) + 1); + tbl_entry_size = prdt_tbl_entry_size(&tbl[i]); if (offset <= (sum + tbl_entry_size)) { off_idx = i; off_pos = offset - sum; @@ -700,12 +706,12 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset) qemu_sglist_init(sglist, qbus->parent, (sglist_alloc_hint - off_idx), ad->hba->as); qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr + off_pos), - le32_to_cpu(tbl[off_idx].flags_size) + 1 - off_pos); + prdt_tbl_entry_size(&tbl[off_idx]) - off_pos); for (i = off_idx + 1; i < sglist_alloc_hint; i++) { /* flags_size is zero-based */ qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr), - le32_to_cpu(tbl[i].flags_size) + 1); + prdt_tbl_entry_size(&tbl[i])); } } @@ -1260,9 +1266,9 @@ static int ahci_state_post_load(void *opaque, int version_id) ad = &s->dev[i]; AHCIPortRegs *pr = &ad->port_regs; - map_page(&ad->lst, + map_page(s->as, &ad->lst, ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024); - map_page(&ad->res_fis, + map_page(s->as, &ad->res_fis, ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); /* * All pending i/o should be flushed out on a migrate. However, diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index 9a4064f892..f418b30ce7 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -201,6 +201,8 @@ #define AHCI_COMMAND_TABLE_ACMD 0x40 +#define AHCI_PRDT_SIZE_MASK 0x3fffff + #define IDE_FEATURE_DMA 1 #define READ_FPDMA_QUEUED 0x60 |