ide: add limit to .prepare_buf()
commita718978ed58abc1ad92567a9c17525136be02a71
authorJohn Snow <jsnow@redhat.com>
Sat, 4 Jul 2015 06:06:04 +0000 (4 02:06 -0400)
committerJohn Snow <jsnow@redhat.com>
Sat, 4 Jul 2015 06:06:04 +0000 (4 02:06 -0400)
treebaed83445cbc9819e3b67ab6d0ba7da413dfef06
parent07a1ee7958cc3433706ab0d3a07c42fdd9d98fe6
ide: add limit to .prepare_buf()

prepare_buf should not always grab as many descriptors
as it can, sometimes it should self-limit.

For example, an NCQ transfer of 1 sector with a PRDT that
describes 4GiB of data should not copy 4GiB of data, it
should just transfer that first 512 bytes.

PIO is not affected, because the dma_buf_rw dma helpers
already have a byte limit built-in to them, but DMA/NCQ
will exhaust the entire list regardless of requested size.

AHCI 1.3 specifies in section 6.1.6 Command List Underflow that
NCQ is not required to detect underflow conditions. Non-NCQ
pathways signal underflow by writing to the PRDBC field, which
will already occur by writing the actual transferred byte count
to the PRDBC, signaling the underflow.

Our NCQ pathways aren't required to detect underflow, but since our DMA
backend uses the size of the PRDT to determine the size of the transer,
if our PRDT is bigger than the transaction (the underflow condition) it
doesn't cost us anything to detect it and truncate the PRDT.

This is a recoverable error and is not signaled to the guest, in either
NCQ or normal DMA cases.

For BMDMA, the existing pathways should see no guest-visible difference,
but any bytes described in the overage will no longer be transferred
before indicating to the guest that there was an underflow.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435767578-32743-2-git-send-email-jsnow@redhat.com
hw/ide/ahci.c
hw/ide/core.c
hw/ide/internal.h
hw/ide/macio.c
hw/ide/pci.c