hw/dma: Let dma_buf_read() / dma_buf_write() propagate MemTxResult

Since commit 292e13142d, dma_buf_rw() returns a MemTxResult type.
Do not discard it, return it to the caller. Pass the previously
returned value (the QEMUSGList residual size, which was rarely used)
as an optional argument.

With this new API, SCSIRequest::residual might now be accessed via
a pointer. Since the size_t type does not have the same size on
32 and 64-bit host architectures, convert it to a uint64_t, which
is big enough to hold the residual size, and the type is constant
on both 32/64-bit hosts.

Update the few dma_buf_read() / dma_buf_write() callers to the new
API.

Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Acked-by: Peter Xu <peterx@redhat.com>
Message-Id: <20220117125130.131828-1-f4bug@amsat.org>
This commit is contained in:
Philippe Mathieu-Daudé 2021-12-16 09:36:38 +01:00 committed by Philippe Mathieu-Daudé
parent bfa30f3903
commit f02b664aad
7 changed files with 59 additions and 40 deletions

View File

@ -1384,9 +1384,9 @@ static void ahci_pio_transfer(const IDEDMA *dma)
const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
if (is_write) { if (is_write) {
dma_buf_write(s->data_ptr, size, &s->sg, attrs); dma_buf_write(s->data_ptr, size, NULL, &s->sg, attrs);
} else { } else {
dma_buf_read(s->data_ptr, size, &s->sg, attrs); dma_buf_read(s->data_ptr, size, NULL, &s->sg, attrs);
} }
} }
@ -1479,9 +1479,9 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
} }
if (is_write) { if (is_write) {
dma_buf_read(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED);
} else { } else {
dma_buf_write(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED); dma_buf_write(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED);
} }
/* free sglist, update byte count */ /* free sglist, update byte count */

View File

@ -1150,9 +1150,9 @@ static uint16_t nvme_tx(NvmeCtrl *n, NvmeSg *sg, uint8_t *ptr, uint32_t len,
dma_addr_t residual; dma_addr_t residual;
if (dir == NVME_TX_DIRECTION_TO_DEVICE) { if (dir == NVME_TX_DIRECTION_TO_DEVICE) {
residual = dma_buf_write(ptr, len, &sg->qsg, attrs); dma_buf_write(ptr, len, &residual, &sg->qsg, attrs);
} else { } else {
residual = dma_buf_read(ptr, len, &sg->qsg, attrs); dma_buf_read(ptr, len, &residual, &sg->qsg, attrs);
} }
if (unlikely(residual)) { if (unlikely(residual)) {

View File

@ -750,6 +750,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
size_t dcmd_size = sizeof(info); size_t dcmd_size = sizeof(info);
BusChild *kid; BusChild *kid;
int num_pd_disks = 0; int num_pd_disks = 0;
dma_addr_t residual;
memset(&info, 0x0, dcmd_size); memset(&info, 0x0, dcmd_size);
if (cmd->iov_size < dcmd_size) { if (cmd->iov_size < dcmd_size) {
@ -860,7 +861,9 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
MFI_INFO_PDMIX_SATA | MFI_INFO_PDMIX_SATA |
MFI_INFO_PDMIX_LD); MFI_INFO_PDMIX_LD);
cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -868,6 +871,7 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd)
{ {
struct mfi_defaults info; struct mfi_defaults info;
size_t dcmd_size = sizeof(struct mfi_defaults); size_t dcmd_size = sizeof(struct mfi_defaults);
dma_addr_t residual;
memset(&info, 0x0, dcmd_size); memset(&info, 0x0, dcmd_size);
if (cmd->iov_size < dcmd_size) { if (cmd->iov_size < dcmd_size) {
@ -890,7 +894,9 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd)
info.disable_preboot_cli = 1; info.disable_preboot_cli = 1;
info.cluster_disable = 1; info.cluster_disable = 1;
cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -898,6 +904,7 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd)
{ {
struct mfi_bios_data info; struct mfi_bios_data info;
size_t dcmd_size = sizeof(info); size_t dcmd_size = sizeof(info);
dma_addr_t residual;
memset(&info, 0x0, dcmd_size); memset(&info, 0x0, dcmd_size);
if (cmd->iov_size < dcmd_size) { if (cmd->iov_size < dcmd_size) {
@ -911,7 +918,9 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd)
info.expose_all_drives = 1; info.expose_all_drives = 1;
} }
cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -919,10 +928,13 @@ static int megasas_dcmd_get_fw_time(MegasasState *s, MegasasCmd *cmd)
{ {
uint64_t fw_time; uint64_t fw_time;
size_t dcmd_size = sizeof(fw_time); size_t dcmd_size = sizeof(fw_time);
dma_addr_t residual;
fw_time = cpu_to_le64(megasas_fw_time()); fw_time = cpu_to_le64(megasas_fw_time());
cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&fw_time, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -942,6 +954,7 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd)
{ {
struct mfi_evt_log_state info; struct mfi_evt_log_state info;
size_t dcmd_size = sizeof(info); size_t dcmd_size = sizeof(info);
dma_addr_t residual;
memset(&info, 0, dcmd_size); memset(&info, 0, dcmd_size);
@ -949,7 +962,9 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd)
info.shutdown_seq_num = cpu_to_le32(s->shutdown_event); info.shutdown_seq_num = cpu_to_le32(s->shutdown_event);
info.boot_seq_num = cpu_to_le32(s->boot_event); info.boot_seq_num = cpu_to_le32(s->boot_event);
cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -979,6 +994,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd)
size_t dcmd_size = sizeof(info); size_t dcmd_size = sizeof(info);
BusChild *kid; BusChild *kid;
uint32_t offset, dcmd_limit, num_pd_disks = 0, max_pd_disks; uint32_t offset, dcmd_limit, num_pd_disks = 0, max_pd_disks;
dma_addr_t residual;
memset(&info, 0, dcmd_size); memset(&info, 0, dcmd_size);
offset = 8; offset = 8;
@ -1018,7 +1034,9 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd)
info.size = cpu_to_le32(offset); info.size = cpu_to_le32(offset);
info.count = cpu_to_le32(num_pd_disks); info.count = cpu_to_le32(num_pd_disks);
cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, offset, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -1113,8 +1131,9 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
info->connected_port_bitmap = 0x1; info->connected_port_bitmap = 0x1;
info->device_speed = 1; info->device_speed = 1;
info->link_speed = 1; info->link_speed = 1;
residual = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, dma_buf_read(cmd->iov_buf, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED); MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
g_free(cmd->iov_buf); g_free(cmd->iov_buf);
cmd->iov_size = dcmd_size - residual; cmd->iov_size = dcmd_size - residual;
cmd->iov_buf = NULL; cmd->iov_buf = NULL;
@ -1187,8 +1206,8 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)
info.ld_count = cpu_to_le32(num_ld_disks); info.ld_count = cpu_to_le32(num_ld_disks);
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
residual = dma_buf_read(&info, dcmd_size, &cmd->qsg, dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED); MEMTXATTRS_UNSPECIFIED);
cmd->iov_size = dcmd_size - residual; cmd->iov_size = dcmd_size - residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -1238,8 +1257,8 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd)
info.size = dcmd_size; info.size = dcmd_size;
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
residual = dma_buf_read(&info, dcmd_size, &cmd->qsg, dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED); MEMTXATTRS_UNSPECIFIED);
cmd->iov_size = dcmd_size - residual; cmd->iov_size = dcmd_size - residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -1290,8 +1309,8 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
info->ld_config.span[0].num_blocks = info->size; info->ld_config.span[0].num_blocks = info->size;
info->ld_config.span[0].array_ref = cpu_to_le16(sdev_id); info->ld_config.span[0].array_ref = cpu_to_le16(sdev_id);
residual = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, dma_buf_read(cmd->iov_buf, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED); MEMTXATTRS_UNSPECIFIED);
g_free(cmd->iov_buf); g_free(cmd->iov_buf);
cmd->iov_size = dcmd_size - residual; cmd->iov_size = dcmd_size - residual;
cmd->iov_buf = NULL; cmd->iov_buf = NULL;
@ -1336,6 +1355,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
struct mfi_config_data *info; struct mfi_config_data *info;
int num_pd_disks = 0, array_offset, ld_offset; int num_pd_disks = 0, array_offset, ld_offset;
BusChild *kid; BusChild *kid;
dma_addr_t residual;
if (cmd->iov_size > 4096) { if (cmd->iov_size > 4096) {
return MFI_STAT_INVALID_PARAMETER; return MFI_STAT_INVALID_PARAMETER;
@ -1410,7 +1430,9 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
ld_offset += sizeof(struct mfi_ld_config); ld_offset += sizeof(struct mfi_ld_config);
} }
cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(data, info->size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -1418,6 +1440,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd)
{ {
struct mfi_ctrl_props info; struct mfi_ctrl_props info;
size_t dcmd_size = sizeof(info); size_t dcmd_size = sizeof(info);
dma_addr_t residual;
memset(&info, 0x0, dcmd_size); memset(&info, 0x0, dcmd_size);
if (cmd->iov_size < dcmd_size) { if (cmd->iov_size < dcmd_size) {
@ -1440,7 +1463,9 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd)
info.ecc_bucket_leak_rate = cpu_to_le16(1440); info.ecc_bucket_leak_rate = cpu_to_le16(1440);
info.expose_encl_devices = 1; info.expose_encl_devices = 1;
cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(&info, dcmd_size, &residual, &cmd->qsg,
MEMTXATTRS_UNSPECIFIED);
cmd->iov_size -= residual;
return MFI_STAT_OK; return MFI_STAT_OK;
} }
@ -1485,7 +1510,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd)
dcmd_size); dcmd_size);
return MFI_STAT_INVALID_PARAMETER; return MFI_STAT_INVALID_PARAMETER;
} }
dma_buf_write(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); dma_buf_write(&info, dcmd_size, NULL, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size); trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size);
return MFI_STAT_OK; return MFI_STAT_OK;
} }

View File

@ -1421,9 +1421,11 @@ void scsi_req_data(SCSIRequest *req, int len)
buf = scsi_req_get_buf(req); buf = scsi_req_get_buf(req);
if (req->cmd.mode == SCSI_XFER_FROM_DEV) { if (req->cmd.mode == SCSI_XFER_FROM_DEV) {
req->residual = dma_buf_read(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED); dma_buf_read(buf, len, &req->residual, req->sg,
MEMTXATTRS_UNSPECIFIED);
} else { } else {
req->residual = dma_buf_write(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED); dma_buf_write(buf, len, &req->residual, req->sg,
MEMTXATTRS_UNSPECIFIED);
} }
scsi_req_continue(req); scsi_req_continue(req);
} }

View File

@ -30,7 +30,7 @@ struct SCSIRequest {
int16_t status; int16_t status;
int16_t host_status; int16_t host_status;
void *hba_private; void *hba_private;
size_t residual; uint64_t residual;
SCSICommand cmd; SCSICommand cmd;
NotifierList cancel_notifiers; NotifierList cancel_notifiers;

View File

@ -301,9 +301,9 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk,
BlockAIOCB *dma_blk_write(BlockBackend *blk, BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset, uint32_t align, QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque); BlockCompletionFunc *cb, void *opaque);
dma_addr_t dma_buf_read(void *ptr, dma_addr_t len, MemTxResult dma_buf_read(void *ptr, dma_addr_t len, dma_addr_t *residual,
QEMUSGList *sg, MemTxAttrs attrs); QEMUSGList *sg, MemTxAttrs attrs);
dma_addr_t dma_buf_write(void *ptr, dma_addr_t len, MemTxResult dma_buf_write(void *ptr, dma_addr_t len, dma_addr_t *residual,
QEMUSGList *sg, MemTxAttrs attrs); QEMUSGList *sg, MemTxAttrs attrs);
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,

View File

@ -321,24 +321,16 @@ static MemTxResult dma_buf_rw(void *buf, dma_addr_t len, dma_addr_t *residual,
return res; return res;
} }
dma_addr_t dma_buf_read(void *ptr, dma_addr_t len, MemTxResult dma_buf_read(void *ptr, dma_addr_t len, dma_addr_t *residual,
QEMUSGList *sg, MemTxAttrs attrs) QEMUSGList *sg, MemTxAttrs attrs)
{ {
dma_addr_t residual; return dma_buf_rw(ptr, len, residual, sg, DMA_DIRECTION_FROM_DEVICE, attrs);
dma_buf_rw(ptr, len, &residual, sg, DMA_DIRECTION_FROM_DEVICE, attrs);
return residual;
} }
dma_addr_t dma_buf_write(void *ptr, dma_addr_t len, MemTxResult dma_buf_write(void *ptr, dma_addr_t len, dma_addr_t *residual,
QEMUSGList *sg, MemTxAttrs attrs) QEMUSGList *sg, MemTxAttrs attrs)
{ {
dma_addr_t residual; return dma_buf_rw(ptr, len, residual, sg, DMA_DIRECTION_TO_DEVICE, attrs);
dma_buf_rw(ptr, len, &residual, sg, DMA_DIRECTION_TO_DEVICE, attrs);
return residual;
} }
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,