From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, mst@redhat.com, armbru@redhat.com,
stefanha@redhat.com, pbonzini@redhat.com,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH 5/6] ide: Correct handling of malformed/short PRDTs
Date: Wed, 1 Oct 2014 18:55:50 -0400 [thread overview]
Message-ID: <1412204151-18117-6-git-send-email-jsnow@redhat.com> (raw)
In-Reply-To: <1412204151-18117-1-git-send-email-jsnow@redhat.com>
This impacts both BMDMA and AHCI HBA interfaces for IDE.
Currently, we confuse the difference between a PRD having
"0 bytes" and a PRD having "0 complete sectors."
This leads to, in the BMDMA case, leaked memory for short PRDTs,
and infinite loops in the AHCI case.
the "prepare_buf" callback is reworked to return 0 if it could
not allocate a full sector's worth of buffer space, instead of
returning non-zero if it allocated any number of bytes.
ide_dma_cb adds a call to commit_buf in order to delete
the short PRDT that it will not attempt to use to finish
the DMA operation.
This patch corrects both occurrences and adds an assertion to
prevent future regression. This assertion is tested in the
existing ide-test, and is covered in a forthcoming AHCI test.
Signed-off-by: John Snow <jsnow@redhat.com>
---
dma-helpers.c | 3 +++
hw/ide/ahci.c | 2 +-
hw/ide/core.c | 1 +
hw/ide/pci.c | 5 +++--
4 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/dma-helpers.c b/dma-helpers.c
index 7f86e18..f51d6ee 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -38,6 +38,9 @@ int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len)
void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
AddressSpace *as)
{
+ /* If this is true, you're leaking memory. */
+ assert(qsg->sg == NULL);
+
qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry));
qsg->nsg = 0;
qsg->nalloc = alloc_hint;
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 16cd248..67c1e36 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1147,7 +1147,7 @@ static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
s->io_buffer_size = s->sg.size;
DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
- return s->io_buffer_size != 0;
+ return s->io_buffer_size / 512 != 0;
}
/**
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 7c1929e..82d01e8 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -732,6 +732,7 @@ void ide_dma_cb(void *opaque, int ret)
/* The PRDs were too short. Reset the Active bit, but don't raise an
* interrupt. */
s->status = READY_STAT | SEEK_STAT;
+ dma_buf_commit(s, false);
goto eot;
}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 2397f35..3f643c2 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -74,8 +74,9 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
if (bm->cur_prd_len == 0) {
/* end of table (with a fail safe of one page) */
if (bm->cur_prd_last ||
- (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE)
- return s->io_buffer_size != 0;
+ (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) {
+ return (s->io_buffer_size / 512) != 0;
+ }
pci_dma_read(pci_dev, bm->cur_addr, &prd, 8);
bm->cur_addr += 8;
prd.addr = le32_to_cpu(prd.addr);
--
1.9.3
next prev parent reply other threads:[~2014-10-01 22:56 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-01 22:55 [Qemu-devel] [PATCH 0/6] AHCI Device Fixes John Snow
2014-10-01 22:55 ` [Qemu-devel] [PATCH 1/6] ahci: Correct PIO/D2H FIS responses John Snow
2014-10-27 9:32 ` Markus Armbruster
2014-10-27 15:43 ` John Snow
2014-10-27 15:59 ` Markus Armbruster
2014-10-01 22:55 ` [Qemu-devel] [PATCH 2/6] ahci: Update byte count after DMA completion John Snow
2014-10-01 22:55 ` [Qemu-devel] [PATCH 3/6] ide: repair PIO transfers for cases where nsector > 1 John Snow
2014-10-01 22:55 ` [Qemu-devel] [PATCH 4/6] ahci: unify sglist preparation John Snow
2014-10-01 22:55 ` John Snow [this message]
2014-10-27 10:06 ` [Qemu-devel] [PATCH 5/6] ide: Correct handling of malformed/short PRDTs Paolo Bonzini
2014-10-27 18:30 ` John Snow
2014-10-01 22:55 ` [Qemu-devel] [PATCH 6/6] ahci: Fix SDB FIS Construction John Snow
2014-10-16 9:36 ` [Qemu-devel] [PATCH 0/6] AHCI Device Fixes John Snow
2014-10-25 20:03 ` Michael S. Tsirkin
2014-10-27 10:07 ` Paolo Bonzini
2014-10-28 13:51 ` Stefan Hajnoczi
2014-10-28 23:54 ` John Snow
2014-10-29 0:03 ` Paolo Bonzini
2014-10-29 0:06 ` John Snow
2014-10-29 0:27 ` Paolo Bonzini
2014-10-29 1:28 ` John Snow
2014-10-29 8:58 ` Paolo Bonzini
2014-10-30 10:52 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1412204151-18117-6-git-send-email-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=kwolf@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).