fix CVE-2021-3611

Signed-off-by: yezengruan <yezengruan@huawei.com>
This commit is contained in:
yezengruan 2022-06-09 17:10:50 +08:00
parent 5fcb2de04b
commit cbe2a01c81
26 changed files with 4609 additions and 1 deletions

View File

@ -0,0 +1,164 @@
From 0f43c97e5a88131fc5d30dc2150d3265c99725d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 16 Dec 2021 11:27:23 +0100
Subject: [PATCH 09/25] dma: Have dma_buf_read() / dma_buf_write() take a void
pointer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DMA operations are run on any kind of buffer, not arrays of
uint8_t. Convert dma_buf_read/dma_buf_write functions to take
a void pointer argument and save us pointless casts to uint8_t *.
Remove this pointless casts in the megasas device model.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-9-philmd@redhat.com>
---
hw/scsi/megasas.c | 22 +++++++++++-----------
include/sysemu/dma.h | 4 ++--
softmmu/dma-helpers.c | 4 ++--
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 6d21bf9fdd..fac46c54ab 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -847,7 +847,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
MFI_INFO_PDMIX_SATA |
MFI_INFO_PDMIX_LD);
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -877,7 +877,7 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd)
info.disable_preboot_cli = 1;
info.cluster_disable = 1;
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -898,7 +898,7 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd)
info.expose_all_drives = 1;
}
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -909,7 +909,7 @@ static int megasas_dcmd_get_fw_time(MegasasState *s, MegasasCmd *cmd)
fw_time = cpu_to_le64(megasas_fw_time());
- cmd->iov_size -= dma_buf_read((uint8_t *)&fw_time, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -936,7 +936,7 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd)
info.shutdown_seq_num = cpu_to_le32(s->shutdown_event);
info.boot_seq_num = cpu_to_le32(s->boot_event);
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -1005,7 +1005,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd)
info.size = cpu_to_le32(offset);
info.count = cpu_to_le32(num_pd_disks);
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, offset, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -1171,7 +1171,7 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)
info.ld_count = cpu_to_le32(num_ld_disks);
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
- resid = dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg);
cmd->iov_size = dcmd_size - resid;
return MFI_STAT_OK;
}
@@ -1220,7 +1220,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd)
info.size = dcmd_size;
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
- resid = dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg);
cmd->iov_size = dcmd_size - resid;
return MFI_STAT_OK;
}
@@ -1389,7 +1389,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
ld_offset += sizeof(struct mfi_ld_config);
}
- cmd->iov_size -= dma_buf_read((uint8_t *)data, info->size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -1419,7 +1419,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd)
info.ecc_bucket_leak_rate = cpu_to_le16(1440);
info.expose_encl_devices = 1;
- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
return MFI_STAT_OK;
}
@@ -1464,7 +1464,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd)
dcmd_size);
return MFI_STAT_INVALID_PARAMETER;
}
- dma_buf_write((uint8_t *)&info, dcmd_size, &cmd->qsg);
+ dma_buf_write(&info, dcmd_size, &cmd->qsg);
trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size);
return MFI_STAT_OK;
}
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 97ff6f29f8..0d5b836013 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -302,8 +302,8 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk,
BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque);
-uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
-uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg);
+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg);
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
QEMUSGList *sg, enum BlockAcctType type);
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 09e29997ee..7f37548394 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -317,12 +317,12 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
return resid;
}
-uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg)
+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg)
{
return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE);
}
-uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg)
{
return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE);
}
--
2.27.0

View File

@ -0,0 +1,38 @@
From cb11b87fe29fa0f4ee664bacff242ed34bf3f33e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 16 Dec 2021 11:24:56 +0100
Subject: [PATCH 08/25] dma: Have dma_buf_rw() take a void pointer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DMA operations are run on any kind of buffer, not arrays of
uint8_t. Convert dma_buf_rw() to take a void pointer argument
to save us pointless casts to uint8_t *.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-8-philmd@redhat.com>
---
softmmu/dma-helpers.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 3c06a2fedd..09e29997ee 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -294,9 +294,10 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk,
}
-static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg,
+static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
DMADirection dir)
{
+ uint8_t *ptr = buf;
uint64_t resid;
int sg_cur_index;
--
2.27.0

View File

@ -0,0 +1,218 @@
From ccdbeeb4171a532acc75ee2b78253aa24b3faa73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Wed, 15 Dec 2021 23:29:52 +0100
Subject: [PATCH 13/25] dma: Let dma_buf_read() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_buf_read().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-13-philmd@redhat.com>
---
hw/ide/ahci.c | 4 ++--
hw/nvme/ctrl.c | 2 +-
hw/scsi/megasas.c | 24 ++++++++++++------------
hw/scsi/scsi-bus.c | 2 +-
include/sysemu/dma.h | 2 +-
softmmu/dma-helpers.c | 5 ++---
6 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 8e27fb8b35..1e482738de 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1386,7 +1386,7 @@ static void ahci_pio_transfer(const IDEDMA *dma)
if (is_write) {
dma_buf_write(s->data_ptr, size, &s->sg, attrs);
} else {
- dma_buf_read(s->data_ptr, size, &s->sg);
+ dma_buf_read(s->data_ptr, size, &s->sg, attrs);
}
}
@@ -1481,7 +1481,7 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
}
if (is_write) {
- dma_buf_read(p, l, &s->sg);
+ dma_buf_read(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED);
} else {
dma_buf_write(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED);
}
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index e1a531d5d6..462f79a1f6 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1152,7 +1152,7 @@ static uint16_t nvme_tx(NvmeCtrl *n, NvmeSg *sg, uint8_t *ptr, uint32_t len,
if (dir == NVME_TX_DIRECTION_TO_DEVICE) {
residual = dma_buf_write(ptr, len, &sg->qsg, attrs);
} else {
- residual = dma_buf_read(ptr, len, &sg->qsg);
+ residual = dma_buf_read(ptr, len, &sg->qsg, attrs);
}
if (unlikely(residual)) {
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 72376d92f6..f1c4d5782b 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -847,7 +847,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
MFI_INFO_PDMIX_SATA |
MFI_INFO_PDMIX_LD);
- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -877,7 +877,7 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd)
info.disable_preboot_cli = 1;
info.cluster_disable = 1;
- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -898,7 +898,7 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd)
info.expose_all_drives = 1;
}
- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -909,7 +909,7 @@ static int megasas_dcmd_get_fw_time(MegasasState *s, MegasasCmd *cmd)
fw_time = cpu_to_le64(megasas_fw_time());
- cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -936,7 +936,7 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd)
info.shutdown_seq_num = cpu_to_le32(s->shutdown_event);
info.boot_seq_num = cpu_to_le32(s->boot_event);
- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -1005,7 +1005,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd)
info.size = cpu_to_le32(offset);
info.count = cpu_to_le32(num_pd_disks);
- cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -1099,7 +1099,7 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
info->connected_port_bitmap = 0x1;
info->device_speed = 1;
info->link_speed = 1;
- resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
g_free(cmd->iov_buf);
cmd->iov_size = dcmd_size - resid;
cmd->iov_buf = NULL;
@@ -1171,7 +1171,7 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)
info.ld_count = cpu_to_le32(num_ld_disks);
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
- resid = dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
cmd->iov_size = dcmd_size - resid;
return MFI_STAT_OK;
}
@@ -1220,7 +1220,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd)
info.size = dcmd_size;
trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);
- resid = dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
cmd->iov_size = dcmd_size - resid;
return MFI_STAT_OK;
}
@@ -1270,7 +1270,7 @@ 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].array_ref = cpu_to_le16(sdev_id);
- resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg);
+ resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
g_free(cmd->iov_buf);
cmd->iov_size = dcmd_size - resid;
cmd->iov_buf = NULL;
@@ -1389,7 +1389,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
ld_offset += sizeof(struct mfi_ld_config);
}
- cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
@@ -1419,7 +1419,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd)
info.ecc_bucket_leak_rate = cpu_to_le16(1440);
info.expose_encl_devices = 1;
- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg);
+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
return MFI_STAT_OK;
}
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 6fe30327b1..2b613ad2b3 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1428,7 +1428,7 @@ void scsi_req_data(SCSIRequest *req, int len)
buf = scsi_req_get_buf(req);
if (req->cmd.mode == SCSI_XFER_FROM_DEV) {
- req->resid = dma_buf_read(buf, len, req->sg);
+ req->resid = dma_buf_read(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED);
} else {
req->resid = dma_buf_write(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED);
}
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index e3dd74a9c4..fd8f16003d 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -302,7 +302,7 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk,
BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque);
-uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg);
+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs);
uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs);
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 2f1a241b81..a391773c29 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -316,10 +316,9 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
return resid;
}
-uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg)
+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, attrs);
}
uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs)
--
2.27.0

View File

@ -0,0 +1,87 @@
From 829b5bede922364061540abc51e80bb2e8b39085 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Wed, 15 Dec 2021 23:38:52 +0100
Subject: [PATCH 14/25] dma: Let dma_buf_rw() propagate MemTxResult
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
dma_memory_rw() returns a MemTxResult type. Do not discard
it, return it to the caller.
Since dma_buf_rw() was previously returning the QEMUSGList
size not consumed, add an extra argument where this size
can be stored.
Update the 2 callers.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-14-philmd@redhat.com>
---
softmmu/dma-helpers.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index a391773c29..b0be156479 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -294,12 +294,14 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk,
}
-static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
- DMADirection dir, MemTxAttrs attrs)
+static MemTxResult dma_buf_rw(void *buf, int32_t len, uint64_t *residp,
+ QEMUSGList *sg, DMADirection dir,
+ MemTxAttrs attrs)
{
uint8_t *ptr = buf;
uint64_t resid;
int sg_cur_index;
+ MemTxResult res = MEMTX_OK;
resid = sg->size;
sg_cur_index = 0;
@@ -307,23 +309,34 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
while (len > 0) {
ScatterGatherEntry entry = sg->sg[sg_cur_index++];
int32_t xfer = MIN(len, entry.len);
- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs);
+ res |= dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs);
ptr += xfer;
len -= xfer;
resid -= xfer;
}
- return resid;
+ if (residp) {
+ *residp = resid;
+ }
+ return res;
}
uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, attrs);
+ uint64_t resid;
+
+ dma_buf_rw(ptr, len, &resid, sg, DMA_DIRECTION_FROM_DEVICE, attrs);
+
+ return resid;
}
uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, attrs);
+ uint64_t resid;
+
+ dma_buf_rw(ptr, len, &resid, sg, DMA_DIRECTION_TO_DEVICE, attrs);
+
+ return resid;
}
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
--
2.27.0

View File

@ -0,0 +1,62 @@
From 1afc40c527dd25dd02d4b4d78530542d25d2d739 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Wed, 15 Dec 2021 22:59:46 +0100
Subject: [PATCH 11/25] dma: Let dma_buf_rw() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling dma_buf_rw().
Keep the default MEMTXATTRS_UNSPECIFIED in the 2 callers.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-11-philmd@redhat.com>
---
softmmu/dma-helpers.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 7f37548394..fa81d2b386 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -295,7 +295,7 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk,
static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
- DMADirection dir)
+ DMADirection dir, MemTxAttrs attrs)
{
uint8_t *ptr = buf;
uint64_t resid;
@@ -307,8 +307,7 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
while (len > 0) {
ScatterGatherEntry entry = sg->sg[sg_cur_index++];
int32_t xfer = MIN(len, entry.len);
- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir,
- MEMTXATTRS_UNSPECIFIED);
+ dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs);
ptr += xfer;
len -= xfer;
resid -= xfer;
@@ -319,12 +318,14 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg,
uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE);
+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
}
uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE);
+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
}
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
--
2.27.0

View File

@ -0,0 +1,126 @@
From f08ff9489ec9d42246b038d90df11457928d6886 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Wed, 15 Dec 2021 23:02:21 +0100
Subject: [PATCH 12/25] dma: Let dma_buf_write() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_buf_write().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-12-philmd@redhat.com>
---
hw/ide/ahci.c | 6 ++++--
hw/nvme/ctrl.c | 3 ++-
hw/scsi/megasas.c | 2 +-
hw/scsi/scsi-bus.c | 2 +-
include/sysemu/dma.h | 2 +-
softmmu/dma-helpers.c | 5 ++---
6 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 7580bd2a96..8e27fb8b35 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1381,8 +1381,10 @@ static void ahci_pio_transfer(const IDEDMA *dma)
has_sglist ? "" : "o");
if (has_sglist && size) {
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+
if (is_write) {
- dma_buf_write(s->data_ptr, size, &s->sg);
+ dma_buf_write(s->data_ptr, size, &s->sg, attrs);
} else {
dma_buf_read(s->data_ptr, size, &s->sg);
}
@@ -1481,7 +1483,7 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
if (is_write) {
dma_buf_read(p, l, &s->sg);
} else {
- dma_buf_write(p, l, &s->sg);
+ dma_buf_write(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED);
}
/* free sglist, update byte count */
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 5f573c417b..e1a531d5d6 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1146,10 +1146,11 @@ static uint16_t nvme_tx(NvmeCtrl *n, NvmeSg *sg, uint8_t *ptr, uint32_t len,
assert(sg->flags & NVME_SG_ALLOC);
if (sg->flags & NVME_SG_DMA) {
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
uint64_t residual;
if (dir == NVME_TX_DIRECTION_TO_DEVICE) {
- residual = dma_buf_write(ptr, len, &sg->qsg);
+ residual = dma_buf_write(ptr, len, &sg->qsg, attrs);
} else {
residual = dma_buf_read(ptr, len, &sg->qsg);
}
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index fac46c54ab..72376d92f6 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1464,7 +1464,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd)
dcmd_size);
return MFI_STAT_INVALID_PARAMETER;
}
- dma_buf_write(&info, dcmd_size, &cmd->qsg);
+ dma_buf_write(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED);
trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size);
return MFI_STAT_OK;
}
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 9d37f490ce..6fe30327b1 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1430,7 +1430,7 @@ void scsi_req_data(SCSIRequest *req, int len)
if (req->cmd.mode == SCSI_XFER_FROM_DEV) {
req->resid = dma_buf_read(buf, len, req->sg);
} else {
- req->resid = dma_buf_write(buf, len, req->sg);
+ req->resid = dma_buf_write(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED);
}
scsi_req_continue(req);
}
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 0d5b836013..e3dd74a9c4 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -303,7 +303,7 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque);
uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg);
-uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg);
+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs);
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
QEMUSGList *sg, enum BlockAcctType type);
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index fa81d2b386..2f1a241b81 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -322,10 +322,9 @@ uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg)
MEMTXATTRS_UNSPECIFIED);
}
-uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg)
+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs)
{
- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, attrs);
}
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
--
2.27.0

View File

@ -0,0 +1,223 @@
From 61b0b2e243c382da97cc97c6a96ee8e14197fd33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 3 Sep 2020 11:00:47 +0200
Subject: [PATCH 07/25] dma: Let dma_memory_map() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_memory_map().
Patch created mechanically using spatch with this script:
@@
expression E1, E2, E3, E4;
@@
- dma_memory_map(E1, E2, E3, E4)
+ dma_memory_map(E1, E2, E3, E4, MEMTXATTRS_UNSPECIFIED)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20211223115554.3155328-7-philmd@redhat.com>
---
hw/display/virtio-gpu.c | 10 ++++++----
hw/hyperv/vmbus.c | 8 +++++---
hw/ide/ahci.c | 8 +++++---
hw/usb/libhw.c | 3 ++-
hw/virtio/virtio.c | 6 ++++--
include/hw/pci/pci.h | 3 ++-
include/sysemu/dma.h | 5 +++--
softmmu/dma-helpers.c | 3 ++-
8 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index d78b9700c7..c6dc818988 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -814,8 +814,9 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
do {
len = l;
- map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as,
- a, &len, DMA_DIRECTION_TO_DEVICE);
+ map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len,
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
if (!map) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
" element %d\n", __func__, e);
@@ -1252,8 +1253,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
for (i = 0; i < res->iov_cnt; i++) {
hwaddr len = res->iov[i].iov_len;
res->iov[i].iov_base =
- dma_memory_map(VIRTIO_DEVICE(g)->dma_as,
- res->addrs[i], &len, DMA_DIRECTION_TO_DEVICE);
+ dma_memory_map(VIRTIO_DEVICE(g)->dma_as, res->addrs[i], &len,
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
if (!res->iov[i].iov_base || len != res->iov[i].iov_len) {
/* Clean up the half-a-mapping we just created... */
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
index dbce3b35fb..8aad29f1bb 100644
--- a/hw/hyperv/vmbus.c
+++ b/hw/hyperv/vmbus.c
@@ -373,7 +373,8 @@ static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, uint32_t len)
maddr = (iter->gpadl->gfns[idx] << TARGET_PAGE_BITS) | off_in_page;
- iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir);
+ iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir,
+ MEMTXATTRS_UNSPECIFIED);
if (mlen != pgleft) {
dma_memory_unmap(iter->as, iter->map, mlen, iter->dir, 0);
iter->map = NULL;
@@ -490,7 +491,8 @@ int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
goto err;
}
- iov[ret_cnt].iov_base = dma_memory_map(sgl->as, a, &l, dir);
+ iov[ret_cnt].iov_base = dma_memory_map(sgl->as, a, &l, dir,
+ MEMTXATTRS_UNSPECIFIED);
if (!l) {
ret = -EFAULT;
goto err;
@@ -566,7 +568,7 @@ static vmbus_ring_buffer *ringbuf_map_hdr(VMBusRingBufCommon *ringbuf)
dma_addr_t mlen = sizeof(*rb);
rb = dma_memory_map(ringbuf->as, ringbuf->rb_addr, &mlen,
- DMA_DIRECTION_FROM_DEVICE);
+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
if (mlen != sizeof(*rb)) {
dma_memory_unmap(ringbuf->as, rb, mlen,
DMA_DIRECTION_FROM_DEVICE, 0);
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 256b58026a..7580bd2a96 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -249,7 +249,8 @@ static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr,
dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
}
- *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE);
+ *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
if (len < wanted && *ptr) {
dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
*ptr = NULL;
@@ -939,7 +940,8 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
/* map PRDT */
if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
- DMA_DIRECTION_TO_DEVICE))){
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED))){
trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no);
return -1;
}
@@ -1301,7 +1303,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
tbl_addr = le64_to_cpu(cmd->tbl_addr);
cmd_len = 0x80;
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
- DMA_DIRECTION_TO_DEVICE);
+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
if (!cmd_fis) {
trace_handle_cmd_badfis(s, port);
return -1;
diff --git a/hw/usb/libhw.c b/hw/usb/libhw.c
index 9c33a1640f..f350eae443 100644
--- a/hw/usb/libhw.c
+++ b/hw/usb/libhw.c
@@ -36,7 +36,8 @@ int usb_packet_map(USBPacket *p, QEMUSGList *sgl)
while (len) {
dma_addr_t xlen = len;
- mem = dma_memory_map(sgl->as, base, &xlen, dir);
+ mem = dma_memory_map(sgl->as, base, &xlen, dir,
+ MEMTXATTRS_UNSPECIFIED);
if (!mem) {
goto err;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 120672672e..f8ab48e6bd 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1306,7 +1306,8 @@ static bool virtqueue_map_desc(VirtIODevice *vdev, unsigned int *p_num_sg,
iov[num_sg].iov_base = dma_memory_map(vdev->dma_as, pa, &len,
is_write ?
DMA_DIRECTION_FROM_DEVICE :
- DMA_DIRECTION_TO_DEVICE);
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
if (!iov[num_sg].iov_base) {
virtio_error(vdev, "virtio: bogus descriptor or out of resources");
goto out;
@@ -1355,7 +1356,8 @@ static void virtqueue_map_iovec(VirtIODevice *vdev, struct iovec *sg,
sg[i].iov_base = dma_memory_map(vdev->dma_as,
addr[i], &len, is_write ?
DMA_DIRECTION_FROM_DEVICE :
- DMA_DIRECTION_TO_DEVICE);
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
if (!sg[i].iov_base) {
error_report("virtio: error trying to map MMIO memory");
exit(1);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c72d61bfd8..c3d5e06364 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -890,7 +890,8 @@ static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr,
{
void *buf;
- buf = dma_memory_map(pci_get_address_space(dev), addr, plen, dir);
+ buf = dma_memory_map(pci_get_address_space(dev), addr, plen, dir,
+ MEMTXATTRS_UNSPECIFIED);
return buf;
}
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 522682bf38..97ff6f29f8 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -202,16 +202,17 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
* @addr: address within that address space
* @len: pointer to length of buffer; updated on return
* @dir: indicates the transfer direction
+ * @attrs: memory attributes
*/
static inline void *dma_memory_map(AddressSpace *as,
dma_addr_t addr, dma_addr_t *len,
- DMADirection dir)
+ DMADirection dir, MemTxAttrs attrs)
{
hwaddr xlen = *len;
void *p;
p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
+ attrs);
*len = xlen;
return p;
}
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 5bf76fff6b..3c06a2fedd 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -143,7 +143,8 @@ static void dma_blk_cb(void *opaque, int ret)
while (dbs->sg_cur_index < dbs->sg->nsg) {
cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;
- mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir);
+ mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir,
+ MEMTXATTRS_UNSPECIFIED);
/*
* Make reads deterministic in icount mode. Windows sometimes issues
* disk read requests with overlapping SGs. It leads
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
From a3bdca7d4684ecb0b785f14020e68b4ba80831b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 3 Sep 2020 09:37:43 +0200
Subject: [PATCH 05/25] dma: Let dma_memory_rw() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_memory_rw().
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20211223115554.3155328-5-philmd@redhat.com>
---
hw/intc/spapr_xive.c | 3 ++-
hw/usb/hcd-ohci.c | 10 ++++++----
include/hw/pci/pci.h | 3 ++-
include/sysemu/dma.h | 11 ++++++-----
softmmu/dma-helpers.c | 3 ++-
5 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 4ec659b93e..eae95c716f 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -1684,7 +1684,8 @@ static target_ulong h_int_esb(PowerPCCPU *cpu,
mmio_addr = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + offset;
if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8,
- (flags & SPAPR_XIVE_ESB_STORE))) {
+ (flags & SPAPR_XIVE_ESB_STORE),
+ MEMTXATTRS_UNSPECIFIED)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%"
HWADDR_PRIx "\n", mmio_addr);
return H_HARDWARE;
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 1cf2816772..56e2315c73 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -586,7 +586,8 @@ static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
if (n > len)
n = len;
- if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+ n, dir, MEMTXATTRS_UNSPECIFIED)) {
return -1;
}
if (n == len) {
@@ -595,7 +596,7 @@ static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
ptr = td->be & ~0xfffu;
buf += n;
if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
- len - n, dir)) {
+ len - n, dir, MEMTXATTRS_UNSPECIFIED)) {
return -1;
}
return 0;
@@ -613,7 +614,8 @@ static int ohci_copy_iso_td(OHCIState *ohci,
if (n > len)
n = len;
- if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+ n, dir, MEMTXATTRS_UNSPECIFIED)) {
return -1;
}
if (n == len) {
@@ -622,7 +624,7 @@ static int ohci_copy_iso_td(OHCIState *ohci,
ptr = end_addr & ~0xfffu;
buf += n;
if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
- len - n, dir)) {
+ len - n, dir, MEMTXATTRS_UNSPECIFIED)) {
return -1;
}
return 0;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 809eb32f4a..c72d61bfd8 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -823,7 +823,8 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
void *buf, dma_addr_t len,
DMADirection dir)
{
- return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir);
+ return dma_memory_rw(pci_get_address_space(dev), addr, buf, len,
+ dir, MEMTXATTRS_UNSPECIFIED);
}
/**
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 3be803cf3f..e8ad42226f 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -121,15 +121,15 @@ static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
* @buf: buffer with the data transferred
* @len: the number of bytes to read or write
* @dir: indicates the transfer direction
+ * @attrs: memory transaction attributes
*/
static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
void *buf, dma_addr_t len,
- DMADirection dir)
+ DMADirection dir, MemTxAttrs attrs)
{
dma_barrier(as, dir);
- return dma_memory_rw_relaxed(as, addr, buf, len, dir,
- MEMTXATTRS_UNSPECIFIED);
+ return dma_memory_rw_relaxed(as, addr, buf, len, dir, attrs);
}
/**
@@ -147,7 +147,8 @@ static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr,
void *buf, dma_addr_t len)
{
- return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
+ return dma_memory_rw(as, addr, buf, len,
+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
}
/**
@@ -166,7 +167,7 @@ static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr,
const void *buf, dma_addr_t len)
{
return dma_memory_rw(as, addr, (void *)buf, len,
- DMA_DIRECTION_FROM_DEVICE);
+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
}
/**
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 1f07217ad4..5bf76fff6b 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -305,7 +305,8 @@ static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg,
while (len > 0) {
ScatterGatherEntry entry = sg->sg[sg_cur_index++];
int32_t xfer = MIN(len, entry.len);
- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir);
+ dma_memory_rw(sg->as, entry.base, ptr, xfer, dir,
+ MEMTXATTRS_UNSPECIFIED);
ptr += xfer;
len -= xfer;
resid -= xfer;
--
2.27.0

View File

@ -0,0 +1,75 @@
From 167e155f710ec769a1db9df92ad6a077bf6225a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 3 Sep 2020 09:30:10 +0200
Subject: [PATCH 04/25] dma: Let dma_memory_rw_relaxed() take MemTxAttrs
argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We will add the MemTxAttrs argument to dma_memory_rw() in
the next commit. Since dma_memory_rw_relaxed() is only used
by dma_memory_rw(), modify it first in a separate commit to
keep the next commit easier to review.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20211223115554.3155328-4-philmd@redhat.com>
---
include/sysemu/dma.h | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index d23516f020..3be803cf3f 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -83,9 +83,10 @@ static inline bool dma_memory_valid(AddressSpace *as,
static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as,
dma_addr_t addr,
void *buf, dma_addr_t len,
- DMADirection dir)
+ DMADirection dir,
+ MemTxAttrs attrs)
{
- return address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
+ return address_space_rw(as, addr, attrs,
buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
}
@@ -93,7 +94,9 @@ static inline MemTxResult dma_memory_read_relaxed(AddressSpace *as,
dma_addr_t addr,
void *buf, dma_addr_t len)
{
- return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
+ return dma_memory_rw_relaxed(as, addr, buf, len,
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
}
static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
@@ -102,7 +105,8 @@ static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
dma_addr_t len)
{
return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
- DMA_DIRECTION_FROM_DEVICE);
+ DMA_DIRECTION_FROM_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
}
/**
@@ -124,7 +128,8 @@ static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
{
dma_barrier(as, dir);
- return dma_memory_rw_relaxed(as, addr, buf, len, dir);
+ return dma_memory_rw_relaxed(as, addr, buf, len, dir,
+ MEMTXATTRS_UNSPECIFIED);
}
/**
--
2.27.0

View File

@ -0,0 +1,94 @@
From ba242eb5be5fdfdccf22d2d818880ed9c89ababd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 3 Sep 2020 10:28:32 +0200
Subject: [PATCH 03/25] dma: Let dma_memory_set() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_memory_set().
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20211223115554.3155328-3-philmd@redhat.com>
---
hw/nvram/fw_cfg.c | 3 ++-
include/hw/ppc/spapr_vio.h | 3 ++-
include/sysemu/dma.h | 3 ++-
softmmu/dma-helpers.c | 5 ++---
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index c06b30de11..f7803fe3c3 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -399,7 +399,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
* tested before.
*/
if (read) {
- if (dma_memory_set(s->dma_as, dma.address, 0, len)) {
+ if (dma_memory_set(s->dma_as, dma.address, 0, len,
+ MEMTXATTRS_UNSPECIFIED)) {
dma.control |= FW_CFG_DMA_CTL_ERROR;
}
}
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 4c45f1579f..c90e74a67d 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -111,7 +111,8 @@ static inline int spapr_vio_dma_write(SpaprVioDevice *dev, uint64_t taddr,
static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
uint8_t c, uint32_t size)
{
- return (dma_memory_set(&dev->as, taddr, c, size) != 0) ?
+ return (dma_memory_set(&dev->as, taddr,
+ c, size, MEMTXATTRS_UNSPECIFIED) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 296f3b57c9..d23516f020 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -175,9 +175,10 @@ static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr,
* @addr: address within that address space
* @c: constant byte to fill the memory
* @len: the number of bytes to fill with the constant byte
+ * @attrs: memory transaction attributes
*/
MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
- uint8_t c, dma_addr_t len);
+ uint8_t c, dma_addr_t len, MemTxAttrs attrs);
/**
* address_space_map: Map a physical memory region into a host virtual address.
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 7d766a5e89..1f07217ad4 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -19,7 +19,7 @@
/* #define DEBUG_IOMMU */
MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
- uint8_t c, dma_addr_t len)
+ uint8_t c, dma_addr_t len, MemTxAttrs attrs)
{
dma_barrier(as, DMA_DIRECTION_FROM_DEVICE);
@@ -31,8 +31,7 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
memset(fillbuf, c, FILLBUF_SIZE);
while (len > 0) {
l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
- error |= address_space_write(as, addr, MEMTXATTRS_UNSPECIFIED,
- fillbuf, l);
+ error |= address_space_write(as, addr, attrs, fillbuf, l);
len -= l;
addr += l;
}
--
2.27.0

View File

@ -0,0 +1,56 @@
From 46e7b55f326a115f42019add488a1ca1887aa89c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 3 Sep 2020 09:28:49 +0200
Subject: [PATCH 02/25] dma: Let dma_memory_valid() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling
dma_memory_valid().
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20211223115554.3155328-2-philmd@redhat.com>
---
include/hw/ppc/spapr_vio.h | 2 +-
include/sysemu/dma.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 4bea87f39c..4c45f1579f 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -91,7 +91,7 @@ static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev)
static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
uint32_t size, DMADirection dir)
{
- return dma_memory_valid(&dev->as, taddr, size, dir);
+ return dma_memory_valid(&dev->as, taddr, size, dir, MEMTXATTRS_UNSPECIFIED);
}
static inline int spapr_vio_dma_read(SpaprVioDevice *dev, uint64_t taddr,
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 3201e7901d..296f3b57c9 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -73,11 +73,11 @@ static inline void dma_barrier(AddressSpace *as, DMADirection dir)
* dma_memory_{read,write}() and check for errors */
static inline bool dma_memory_valid(AddressSpace *as,
dma_addr_t addr, dma_addr_t len,
- DMADirection dir)
+ DMADirection dir, MemTxAttrs attrs)
{
return address_space_access_valid(as, addr, len,
dir == DMA_DIRECTION_FROM_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
+ attrs);
}
static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as,
--
2.27.0

View File

@ -0,0 +1,171 @@
From e52e5e44ca9afd06639cc166b60cc8fbdb081593 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 22:31:11 +0100
Subject: [PATCH 18/25] dma: Let ld*_dma() propagate MemTxResult
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
dma_memory_read() returns a MemTxResult type. Do not discard
it, return it to the caller.
Update the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-19-philmd@redhat.com>
---
hw/intc/pnv_xive.c | 8 ++++----
hw/usb/hcd-xhci.c | 7 ++++---
include/hw/pci/pci.h | 6 ++++--
include/hw/ppc/spapr_vio.h | 6 +++++-
include/sysemu/dma.h | 25 ++++++++++++-------------
5 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index d9249bbc0c..bb207514f2 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
/* Get the page size of the indirect table. */
vsd_addr = vsd & VSD_ADDRESS_MASK;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd, MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
@@ -195,8 +195,8 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
/* Load the VSD we are looking for, if not already done */
if (vsd_idx) {
vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr,
- MEMTXATTRS_UNSPECIFIED);
+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd,
+ MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
@@ -543,7 +543,7 @@ static uint64_t pnv_xive_vst_per_subpage(PnvXive *xive, uint32_t type)
/* Get the page size of the indirect table. */
vsd_addr = vsd & VSD_ADDRESS_MASK;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd, MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 1f7b796ce3..30c477f36e 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2063,7 +2063,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
assert(slotid >= 1 && slotid <= xhci->numslots);
dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
- poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid, MEMTXATTRS_UNSPECIFIED);
+ ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &poctx, MEMTXATTRS_UNSPECIFIED);
ictx = xhci_mask64(pictx);
octx = xhci_mask64(poctx);
@@ -3433,6 +3433,7 @@ static int usb_xhci_post_load(void *opaque, int version_id)
uint32_t slot_ctx[4];
uint32_t ep_ctx[5];
int slotid, epid, state;
+ uint64_t addr;
dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
@@ -3441,8 +3442,8 @@ static int usb_xhci_post_load(void *opaque, int version_id)
if (!slot->addressed) {
continue;
}
- slot->ctx = xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid,
- MEMTXATTRS_UNSPECIFIED));
+ ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &addr, MEMTXATTRS_UNSPECIFIED);
+ slot->ctx = xhci_mask64(addr);
xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx));
slot->uport = xhci_lookup_uport(xhci, slot_ctx);
if (!slot->uport) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index b287b3a19f..71c6513641 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -869,8 +869,10 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \
dma_addr_t addr) \
{ \
- return ld##_l##_dma(pci_get_address_space(dev), addr, \
- MEMTXATTRS_UNSPECIFIED); \
+ uint##_bits##_t val; \
+ ld##_l##_dma(pci_get_address_space(dev), addr, &val, \
+ MEMTXATTRS_UNSPECIFIED); \
+ return val; \
} \
static inline void st##_s##_pci_dma(PCIDevice *dev, \
dma_addr_t addr, uint##_bits##_t val) \
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index d2ec9b0637..7eae1a4847 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -127,7 +127,11 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
#define vio_stq(_dev, _addr, _val) \
(stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
#define vio_ldq(_dev, _addr) \
- (ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED))
+ ({ \
+ uint64_t _val; \
+ ldq_be_dma(&(_dev)->as, (_addr), &_val, MEMTXATTRS_UNSPECIFIED); \
+ _val; \
+ })
int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 895044d747..b3faef41b2 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -240,14 +240,15 @@ static inline void dma_memory_unmap(AddressSpace *as,
}
#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
- static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \
- dma_addr_t addr, \
- MemTxAttrs attrs) \
- { \
- uint##_bits##_t val; \
- dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \
- return _end##_bits##_to_cpu(val); \
- } \
+ static inline MemTxResult ld##_lname##_##_end##_dma(AddressSpace *as, \
+ dma_addr_t addr, \
+ uint##_bits##_t *pval, \
+ MemTxAttrs attrs) \
+ { \
+ MemTxResult res = dma_memory_read(as, addr, pval, (_bits) / 8, attrs); \
+ _end##_bits##_to_cpus(pval); \
+ return res; \
+ } \
static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
dma_addr_t addr, \
uint##_bits##_t val, \
@@ -257,12 +258,10 @@ static inline void dma_memory_unmap(AddressSpace *as,
return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
}
-static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs)
+static inline MemTxResult ldub_dma(AddressSpace *as, dma_addr_t addr,
+ uint8_t *val, MemTxAttrs attrs)
{
- uint8_t val;
-
- dma_memory_read(as, addr, &val, 1, attrs);
- return val;
+ return dma_memory_read(as, addr, val, 1, attrs);
}
static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,
--
2.27.0

View File

@ -0,0 +1,147 @@
From 52cca6d99c5c59d6550d3729f84ffcba50ff4ed3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 22:18:07 +0100
Subject: [PATCH 16/25] dma: Let ld*_dma() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling ld*_dma().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-17-philmd@redhat.com>
---
hw/intc/pnv_xive.c | 7 ++++---
hw/usb/hcd-xhci.c | 6 +++---
include/hw/pci/pci.h | 3 ++-
include/hw/ppc/spapr_vio.h | 3 ++-
include/sysemu/dma.h | 11 ++++++-----
5 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index ad43483612..d9249bbc0c 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
/* Get the page size of the indirect table. */
vsd_addr = vsd & VSD_ADDRESS_MASK;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+ vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
@@ -195,7 +195,8 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
/* Load the VSD we are looking for, if not already done */
if (vsd_idx) {
vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+ vsd = ldq_be_dma(&address_space_memory, vsd_addr,
+ MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
@@ -542,7 +543,7 @@ static uint64_t pnv_xive_vst_per_subpage(PnvXive *xive, uint32_t type)
/* Get the page size of the indirect table. */
vsd_addr = vsd & VSD_ADDRESS_MASK;
- vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+ vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED);
if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE_DEBUG
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index c76091c657..1f7b796ce3 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2063,7 +2063,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
assert(slotid >= 1 && slotid <= xhci->numslots);
dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
- poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid);
+ poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid, MEMTXATTRS_UNSPECIFIED);
ictx = xhci_mask64(pictx);
octx = xhci_mask64(poctx);
@@ -3441,8 +3441,8 @@ static int usb_xhci_post_load(void *opaque, int version_id)
if (!slot->addressed) {
continue;
}
- slot->ctx =
- xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid));
+ slot->ctx = xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid,
+ MEMTXATTRS_UNSPECIFIED));
xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx));
slot->uport = xhci_lookup_uport(xhci, slot_ctx);
if (!slot->uport) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 52e2ca2f2e..b287b3a19f 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -869,7 +869,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \
dma_addr_t addr) \
{ \
- return ld##_l##_dma(pci_get_address_space(dev), addr); \
+ return ld##_l##_dma(pci_get_address_space(dev), addr, \
+ MEMTXATTRS_UNSPECIFIED); \
} \
static inline void st##_s##_pci_dma(PCIDevice *dev, \
dma_addr_t addr, uint##_bits##_t val) \
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index e87f8e6f59..d2ec9b0637 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -126,7 +126,8 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
(stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
#define vio_stq(_dev, _addr, _val) \
(stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
-#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
+#define vio_ldq(_dev, _addr) \
+ (ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED))
int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 009dd3ca96..d1635f5587 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -241,10 +241,11 @@ static inline void dma_memory_unmap(AddressSpace *as,
#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \
- dma_addr_t addr) \
+ dma_addr_t addr, \
+ MemTxAttrs attrs) \
{ \
uint##_bits##_t val; \
- dma_memory_read(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \
+ dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \
return _end##_bits##_to_cpu(val); \
} \
static inline void st##_sname##_##_end##_dma(AddressSpace *as, \
@@ -253,14 +254,14 @@ static inline void dma_memory_unmap(AddressSpace *as,
MemTxAttrs attrs) \
{ \
val = cpu_to_##_end##_bits(val); \
- dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
+ dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
}
-static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)
+static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs)
{
uint8_t val;
- dma_memory_read(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED);
+ dma_memory_read(as, addr, &val, 1, attrs);
return val;
}
--
2.27.0

View File

@ -0,0 +1,61 @@
From 323fc6abd2b727d888acaec1788bb7b7aefa295b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 23:56:14 +0100
Subject: [PATCH 17/25] dma: Let st*_dma() propagate MemTxResult
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
dma_memory_write() returns a MemTxResult type. Do not discard
it, return it to the caller.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-18-philmd@redhat.com>
---
include/sysemu/dma.h | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index d1635f5587..895044d747 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -248,13 +248,13 @@ static inline void dma_memory_unmap(AddressSpace *as,
dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \
return _end##_bits##_to_cpu(val); \
} \
- static inline void st##_sname##_##_end##_dma(AddressSpace *as, \
- dma_addr_t addr, \
- uint##_bits##_t val, \
- MemTxAttrs attrs) \
- { \
- val = cpu_to_##_end##_bits(val); \
- dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
+ static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
+ dma_addr_t addr, \
+ uint##_bits##_t val, \
+ MemTxAttrs attrs) \
+ { \
+ val = cpu_to_##_end##_bits(val); \
+ return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
}
static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs)
@@ -265,10 +265,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs att
return val;
}
-static inline void stb_dma(AddressSpace *as, dma_addr_t addr,
- uint8_t val, MemTxAttrs attrs)
+static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,
+ uint8_t val, MemTxAttrs attrs)
{
- dma_memory_write(as, addr, &val, 1, attrs);
+ return dma_memory_write(as, addr, &val, 1, attrs);
}
DEFINE_LDST_DMA(uw, w, 16, le);
--
2.27.0

View File

@ -0,0 +1,116 @@
From c9fb8525402c4a3d3e3f5c104a289fbf080fcda3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 23:53:34 +0100
Subject: [PATCH 15/25] dma: Let st*_dma() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling st*_dma().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-16-philmd@redhat.com>
---
hw/nvram/fw_cfg.c | 4 ++--
include/hw/pci/pci.h | 3 ++-
include/hw/ppc/spapr_vio.h | 12 ++++++++----
include/sysemu/dma.h | 10 ++++++----
4 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 9b91b15cb0..e5f3c98184 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -360,7 +360,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
if (dma_memory_read(s->dma_as, dma_addr,
&dma, sizeof(dma), MEMTXATTRS_UNSPECIFIED)) {
stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
- FW_CFG_DMA_CTL_ERROR);
+ FW_CFG_DMA_CTL_ERROR, MEMTXATTRS_UNSPECIFIED);
return;
}
@@ -446,7 +446,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
}
stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
- dma.control);
+ dma.control, MEMTXATTRS_UNSPECIFIED);
trace_fw_cfg_read(s, 0);
}
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c7177646a4..52e2ca2f2e 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -874,7 +874,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
static inline void st##_s##_pci_dma(PCIDevice *dev, \
dma_addr_t addr, uint##_bits##_t val) \
{ \
- st##_s##_dma(pci_get_address_space(dev), addr, val); \
+ st##_s##_dma(pci_get_address_space(dev), addr, val, \
+ MEMTXATTRS_UNSPECIFIED); \
}
PCI_DMA_DEFINE_LDST(ub, b, 8);
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 5d2ea8e665..e87f8e6f59 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -118,10 +118,14 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
H_DEST_PARM : H_SUCCESS;
}
-#define vio_stb(_dev, _addr, _val) (stb_dma(&(_dev)->as, (_addr), (_val)))
-#define vio_sth(_dev, _addr, _val) (stw_be_dma(&(_dev)->as, (_addr), (_val)))
-#define vio_stl(_dev, _addr, _val) (stl_be_dma(&(_dev)->as, (_addr), (_val)))
-#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val)))
+#define vio_stb(_dev, _addr, _val) \
+ (stb_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_sth(_dev, _addr, _val) \
+ (stw_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_stl(_dev, _addr, _val) \
+ (stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
+#define vio_stq(_dev, _addr, _val) \
+ (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED))
#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index fd8f16003d..009dd3ca96 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -249,10 +249,11 @@ static inline void dma_memory_unmap(AddressSpace *as,
} \
static inline void st##_sname##_##_end##_dma(AddressSpace *as, \
dma_addr_t addr, \
- uint##_bits##_t val) \
+ uint##_bits##_t val, \
+ MemTxAttrs attrs) \
{ \
val = cpu_to_##_end##_bits(val); \
- dma_memory_write(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \
+ dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
}
static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)
@@ -263,9 +264,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)
return val;
}
-static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val)
+static inline void stb_dma(AddressSpace *as, dma_addr_t addr,
+ uint8_t val, MemTxAttrs attrs)
{
- dma_memory_write(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED);
+ dma_memory_write(as, addr, &val, 1, attrs);
}
DEFINE_LDST_DMA(uw, w, 16, le);
--
2.27.0

View File

@ -0,0 +1,70 @@
From 2defe49a69b324499953c9b8c55f18e22ca74631 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Sat, 18 Dec 2021 17:09:10 +0100
Subject: [PATCH 23/25] hw/audio/intel-hda: Do not ignore DMA overrun errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per the "High Definition Audio Specification" manual (rev. 1.0a),
section "3.3.30 Offset 5Dh: RIRBSTS - RIRB Status":
Response Overrun Interrupt Status (RIRBOIS):
Hardware sets this bit to a 1 when an overrun occurs in the RIRB.
An interrupt may be generated if the Response Overrun Interrupt
Control bit is set.
This bit will be set if the RIRB DMA engine is not able to write
the incoming responses to memory before additional incoming
responses overrun the internal FIFO.
When hardware detects an overrun, it will drop the responses which
overrun the buffer and set the RIRBOIS status bit to indicate the
error condition. Optionally, if the RIRBOIC is set, the hardware
will also generate an error to alert software to the problem.
QEMU emulates the DMA engine with the stl_le_pci_dma() calls. This
function returns a MemTxResult indicating whether the DMA access
was successful.
Handle any MemTxResult error as "DMA engine is not able to write the
incoming responses to memory" and raise the Overrun Interrupt flag
when this case occurs.
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211218160912.1591633-2-philmd@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/audio/intel-hda.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 2b55d52150..0c1017edbb 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -350,6 +350,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
hwaddr addr;
uint32_t wp, ex;
+ MemTxResult res = MEMTX_OK;
if (d->ics & ICH6_IRS_BUSY) {
dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
@@ -368,8 +369,12 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
wp = (d->rirb_wp + 1) & 0xff;
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
- stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs);
- stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs);
+ res |= stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs);
+ res |= stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs);
+ if (res != MEMTX_OK && (d->rirb_ctl & ICH6_RBCTL_OVERRUN_EN)) {
+ d->rirb_sts |= ICH6_RBSTS_OVERRUN;
+ intel_hda_update_irq(d);
+ }
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
--
2.27.0

View File

@ -0,0 +1,41 @@
From f8b3b2e8d09320cab4cccab2dcbaab799d2dbd7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Sat, 18 Dec 2021 17:09:11 +0100
Subject: [PATCH 24/25] hw/audio/intel-hda: Restrict DMA engine to memories
(not MMIO devices)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Issue #542 reports a reentrancy problem when the DMA engine accesses
the HDA controller I/O registers. Fix by restricting the DMA engine
to memories regions (forbidding MMIO devices such the HDA controller).
Reported-by: OSS-Fuzz (Issue 28435)
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/542
CVE: CVE-2021-3611
Message-Id: <20211218160912.1591633-3-philmd@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/audio/intel-hda.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 0c1017edbb..3aa57d274e 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -345,7 +345,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response)
{
- const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+ const MemTxAttrs attrs = { .memory = true };
HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
hwaddr addr;
--
2.27.0

View File

@ -0,0 +1,79 @@
From e430aa3df353a19370ebd91421f5a545fa4ce211 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 22:43:05 +0100
Subject: [PATCH 01/25] hw/scsi/megasas: Use uint32_t for reply queue head/tail
values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While the reply queue values fit in 16-bit, they are accessed
as 32-bit:
661: s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa);
662: s->reply_queue_head %= MEGASAS_MAX_FRAMES;
663: s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
664: s->reply_queue_tail %= MEGASAS_MAX_FRAMES;
Having:
41:#define MEGASAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */
In order to update the ld/st*_pci_dma() API to pass the address
of the value to access, it is simpler to have the head/tail declared
as 32-bit values. Replace the uint16_t by uint32_t, wasting 4 bytes in
the MegasasState structure.
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-20-philmd@redhat.com>
---
hw/scsi/megasas.c | 4 ++--
hw/scsi/trace-events | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 4ff51221d4..6d21bf9fdd 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -109,8 +109,8 @@ struct MegasasState {
uint64_t reply_queue_pa;
void *reply_queue;
uint16_t reply_queue_len;
- uint16_t reply_queue_head;
- uint16_t reply_queue_tail;
+ uint32_t reply_queue_head;
+ uint32_t reply_queue_tail;
uint64_t consumer_pa;
uint64_t producer_pa;
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 92d5b40f89..ae8551f279 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -42,18 +42,18 @@ mptsas_config_sas_phy(void *dev, int address, int port, int phy_handle, int dev_
# megasas.c
megasas_init_firmware(uint64_t pa) "pa 0x%" PRIx64 " "
-megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at 0x%" PRIx64 " len %d head 0x%" PRIx64 " tail 0x%" PRIx64 " flags 0x%x"
+megasas_init_queue(uint64_t queue_pa, int queue_len, uint32_t head, uint32_t tail, uint32_t flags) "queue at 0x%" PRIx64 " len %d head 0x%" PRIx32 " tail 0x%" PRIx32 " flags 0x%x"
megasas_initq_map_failed(int frame) "scmd %d: failed to map queue"
megasas_initq_mapped(uint64_t pa) "queue already mapped at 0x%" PRIx64
megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d"
megasas_qf_mapped(unsigned int index) "skip mapped frame 0x%x"
megasas_qf_new(unsigned int index, uint64_t frame) "frame 0x%x addr 0x%" PRIx64
megasas_qf_busy(unsigned long pa) "all frames busy for frame 0x%lx"
-megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int head, unsigned int tail, int busy) "frame 0x%x count %d context 0x%" PRIx64 " head 0x%x tail 0x%x busy %d"
-megasas_qf_update(unsigned int head, unsigned int tail, unsigned int busy) "head 0x%x tail 0x%x busy %d"
+megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, uint32_t head, uint32_t tail, unsigned int busy) "frame 0x%x count %d context 0x%" PRIx64 " head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u"
+megasas_qf_update(uint32_t head, uint32_t tail, unsigned int busy) "head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u"
megasas_qf_map_failed(int cmd, unsigned long frame) "scmd %d: frame %lu"
megasas_qf_complete_noirq(uint64_t context) "context 0x%" PRIx64 " "
-megasas_qf_complete(uint64_t context, unsigned int head, unsigned int tail, int busy) "context 0x%" PRIx64 " head 0x%x tail 0x%x busy %d"
+megasas_qf_complete(uint64_t context, uint32_t head, uint32_t tail, int busy) "context 0x%" PRIx64 " head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u"
megasas_frame_busy(uint64_t addr) "frame 0x%" PRIx64 " busy"
megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) "scmd %d: MFI cmd 0x%x"
megasas_handle_scsi(const char *frame, int bus, int dev, int lun, void *sdev, unsigned long size) "%s dev %x/%x/%x sdev %p xfer %lu"
--
2.27.0

View File

@ -0,0 +1,292 @@
From d7e2bb6bba0b5b77b296ca99b26c0d0a4db0d9f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 23:49:30 +0100
Subject: [PATCH 22/25] pci: Let ld*_pci_dma() propagate MemTxResult
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ld*_dma() returns a MemTxResult type. Do not discard
it, return it to the caller.
Update the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-24-philmd@redhat.com>
---
hw/audio/intel-hda.c | 2 +-
hw/net/eepro100.c | 25 ++++++++++---------------
hw/net/tulip.c | 16 ++++++++--------
hw/scsi/megasas.c | 21 ++++++++++++---------
hw/scsi/mptsas.c | 16 +++++++++++-----
hw/scsi/vmw_pvscsi.c | 16 ++++++++++------
include/hw/pci/pci.h | 17 ++++++++---------
7 files changed, 60 insertions(+), 53 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index e34b7ab0e9..2b55d52150 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -335,7 +335,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
rp = (d->corb_rp + 1) & 0xff;
addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
- verb = ldl_le_pci_dma(&d->pci, addr + 4 * rp, MEMTXATTRS_UNSPECIFIED);
+ ldl_le_pci_dma(&d->pci, addr + 4 * rp, &verb, MEMTXATTRS_UNSPECIFIED);
d->corb_rp = rp;
dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb);
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 36dc1e22d7..9c178c1448 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -772,18 +772,16 @@ static void tx_command(EEPRO100State *s)
} else {
/* Flexible mode. */
uint8_t tbd_count = 0;
+ uint32_t tx_buffer_address;
+ uint16_t tx_buffer_size;
+ uint16_t tx_buffer_el;
+
if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) {
/* Extended Flexible TCB. */
for (; tbd_count < 2; tbd_count++) {
- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev,
- tbd_address,
- attrs);
- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev,
- tbd_address + 4,
- attrs);
- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev,
- tbd_address + 6,
- attrs);
+ ldl_le_pci_dma(&s->dev, tbd_address, &tx_buffer_address, attrs);
+ lduw_le_pci_dma(&s->dev, tbd_address + 4, &tx_buffer_size, attrs);
+ lduw_le_pci_dma(&s->dev, tbd_address + 6, &tx_buffer_el, attrs);
tbd_address += 8;
TRACE(RXTX, logout
("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
@@ -799,12 +797,9 @@ static void tx_command(EEPRO100State *s)
}
tbd_address = tbd_array;
for (; tbd_count < s->tx.tbd_count; tbd_count++) {
- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address,
- attrs);
- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4,
- attrs);
- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6,
- attrs);
+ ldl_le_pci_dma(&s->dev, tbd_address, &tx_buffer_address, attrs);
+ lduw_le_pci_dma(&s->dev, tbd_address + 4, &tx_buffer_size, attrs);
+ lduw_le_pci_dma(&s->dev, tbd_address + 6, &tx_buffer_el, attrs);
tbd_address += 8;
TRACE(RXTX, logout
("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index c76e4868f7..d5b6cc5ee6 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -73,15 +73,15 @@ static void tulip_desc_read(TULIPState *s, hwaddr p,
const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
if (s->csr[0] & CSR0_DBO) {
- desc->status = ldl_be_pci_dma(&s->dev, p, attrs);
- desc->control = ldl_be_pci_dma(&s->dev, p + 4, attrs);
- desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8, attrs);
- desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12, attrs);
+ ldl_be_pci_dma(&s->dev, p, &desc->status, attrs);
+ ldl_be_pci_dma(&s->dev, p + 4, &desc->control, attrs);
+ ldl_be_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs);
+ ldl_be_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs);
} else {
- desc->status = ldl_le_pci_dma(&s->dev, p, attrs);
- desc->control = ldl_le_pci_dma(&s->dev, p + 4, attrs);
- desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8, attrs);
- desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12, attrs);
+ ldl_le_pci_dma(&s->dev, p, &desc->status, attrs);
+ ldl_le_pci_dma(&s->dev, p + 4, &desc->control, attrs);
+ ldl_le_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs);
+ ldl_le_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs);
}
}
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 23380008e1..946050bf83 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -202,9 +202,12 @@ static uint64_t megasas_frame_get_context(MegasasState *s,
unsigned long frame)
{
PCIDevice *pci = &s->parent_obj;
- return ldq_le_pci_dma(pci,
- frame + offsetof(struct mfi_frame_header, context),
- MEMTXATTRS_UNSPECIFIED);
+ uint64_t val;
+
+ ldq_le_pci_dma(pci, frame + offsetof(struct mfi_frame_header, context),
+ &val, MEMTXATTRS_UNSPECIFIED);
+
+ return val;
}
static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd)
@@ -535,8 +538,8 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
s->busy++;
if (s->consumer_pa) {
- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa,
- MEMTXATTRS_UNSPECIFIED);
+ ldl_le_pci_dma(pcid, s->consumer_pa, &s->reply_queue_tail,
+ MEMTXATTRS_UNSPECIFIED);
}
trace_megasas_qf_enqueue(cmd->index, cmd->count, cmd->context,
s->reply_queue_head, s->reply_queue_tail, s->busy);
@@ -567,14 +570,14 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset,
context, attrs);
}
- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs);
+ ldl_le_pci_dma(pci_dev, s->consumer_pa, &s->reply_queue_tail, attrs);
trace_megasas_qf_complete(context, s->reply_queue_head,
s->reply_queue_tail, s->busy);
}
if (megasas_intr_enabled(s)) {
/* Update reply queue pointer */
- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs);
+ ldl_le_pci_dma(pci_dev, s->consumer_pa, &s->reply_queue_tail, attrs);
tail = s->reply_queue_head;
s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds);
trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail,
@@ -678,9 +681,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
pa_lo = le32_to_cpu(initq->pi_addr_lo);
pa_hi = le32_to_cpu(initq->pi_addr_hi);
s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo;
- s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa, attrs);
+ ldl_le_pci_dma(pcid, s->producer_pa, &s->reply_queue_head, attrs);
s->reply_queue_head %= MEGASAS_MAX_FRAMES;
- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, attrs);
+ ldl_le_pci_dma(pcid, s->consumer_pa, &s->reply_queue_tail, attrs);
s->reply_queue_tail %= MEGASAS_MAX_FRAMES;
flags = le32_to_cpu(initq->flags);
if (flags & MFI_QUEUE_FLAG_CONTEXT64) {
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index ac9f4dfcd2..5181b0c0b0 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -177,10 +177,16 @@ static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length,
dma_addr_t addr;
if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
- addr = ldq_le_pci_dma(pci, *sgaddr + 4, attrs);
+ uint64_t addr64;
+
+ ldq_le_pci_dma(pci, *sgaddr + 4, &addr64, attrs);
+ addr = addr64;
*sgaddr += 12;
} else {
- addr = ldl_le_pci_dma(pci, *sgaddr + 4, attrs);
+ uint32_t addr32;
+
+ ldl_le_pci_dma(pci, *sgaddr + 4, &addr32, attrs);
+ addr = addr32;
*sgaddr += 8;
}
return addr;
@@ -204,7 +210,7 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr)
dma_addr_t addr, len;
uint32_t flags_and_length;
- flags_and_length = ldl_le_pci_dma(pci, sgaddr, MEMTXATTRS_UNSPECIFIED);
+ ldl_le_pci_dma(pci, sgaddr, &flags_and_length, MEMTXATTRS_UNSPECIFIED);
len = flags_and_length & MPI_SGE_LENGTH_MASK;
if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
!= MPI_SGE_FLAGS_SIMPLE_ELEMENT ||
@@ -235,8 +241,8 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr)
break;
}
- flags_and_length = ldl_le_pci_dma(pci, next_chain_addr,
- MEMTXATTRS_UNSPECIFIED);
+ ldl_le_pci_dma(pci, next_chain_addr, &flags_and_length,
+ MEMTXATTRS_UNSPECIFIED);
if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
!= MPI_SGE_FLAGS_CHAIN_ELEMENT) {
return MPI_IOCSTATUS_INVALID_SGL;
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 33e16f9111..4d9969f3b1 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -50,10 +50,10 @@
#define PVSCSI_MAX_CMD_DATA_WORDS \
(sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t))
-#define RS_GET_FIELD(m, field) \
- (ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
+#define RS_GET_FIELD(pval, m, field) \
+ ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
(m)->rs_pa + offsetof(struct PVSCSIRingsState, field), \
- MEMTXATTRS_UNSPECIFIED))
+ pval, MEMTXATTRS_UNSPECIFIED)
#define RS_SET_FIELD(m, field, val) \
(stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
(m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \
@@ -249,10 +249,11 @@ pvscsi_ring_cleanup(PVSCSIRingInfo *mgr)
static hwaddr
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
{
- uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);
+ uint32_t ready_ptr;
uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING
* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
+ RS_GET_FIELD(&ready_ptr, mgr, reqProdIdx);
if (ready_ptr != mgr->consumed_ptr
&& ready_ptr - mgr->consumed_ptr < ring_size) {
uint32_t next_ready_ptr =
@@ -323,8 +324,11 @@ pvscsi_ring_flush_cmp(PVSCSIRingInfo *mgr)
static bool
pvscsi_ring_msg_has_room(PVSCSIRingInfo *mgr)
{
- uint32_t prodIdx = RS_GET_FIELD(mgr, msgProdIdx);
- uint32_t consIdx = RS_GET_FIELD(mgr, msgConsIdx);
+ uint32_t prodIdx;
+ uint32_t consIdx;
+
+ RS_GET_FIELD(&prodIdx, mgr, msgProdIdx);
+ RS_GET_FIELD(&consIdx, mgr, msgConsIdx);
return (prodIdx - consIdx) < (mgr->msg_len_mask + 1);
}
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index a9834e17e2..bfe3a6bca7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -865,15 +865,14 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
}
-#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
- static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \
- dma_addr_t addr, \
- MemTxAttrs attrs) \
- { \
- uint##_bits##_t val; \
- ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \
- return val; \
- } \
+#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
+ static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \
+ dma_addr_t addr, \
+ uint##_bits##_t *val, \
+ MemTxAttrs attrs) \
+ { \
+ return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \
+ } \
static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \
dma_addr_t addr, \
uint##_bits##_t val, \
--
2.27.0

View File

@ -0,0 +1,267 @@
From 0317671b81ebbff7187a1b836a2adde4fe16b762 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 23:45:06 +0100
Subject: [PATCH 20/25] pci: Let ld*_pci_dma() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling ld*_pci_dma().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-22-philmd@redhat.com>
---
hw/audio/intel-hda.c | 2 +-
hw/net/eepro100.c | 19 +++++++++++++------
hw/net/tulip.c | 18 ++++++++++--------
hw/scsi/megasas.c | 16 ++++++++++------
hw/scsi/mptsas.c | 10 ++++++----
hw/scsi/vmw_pvscsi.c | 3 ++-
hw/usb/hcd-xhci.c | 1 +
include/hw/pci/pci.h | 6 +++---
8 files changed, 46 insertions(+), 29 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 3309ae0ea1..e34b7ab0e9 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -335,7 +335,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
rp = (d->corb_rp + 1) & 0xff;
addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
- verb = ldl_le_pci_dma(&d->pci, addr + 4*rp);
+ verb = ldl_le_pci_dma(&d->pci, addr + 4 * rp, MEMTXATTRS_UNSPECIFIED);
d->corb_rp = rp;
dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb);
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 160b9b0b4c..36dc1e22d7 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -740,6 +740,7 @@ static void read_cb(EEPRO100State *s)
static void tx_command(EEPRO100State *s)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
uint32_t tbd_array = s->tx.tbd_array_addr;
uint16_t tcb_bytes = s->tx.tcb_bytes & 0x3fff;
/* Sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes. */
@@ -775,11 +776,14 @@ static void tx_command(EEPRO100State *s)
/* Extended Flexible TCB. */
for (; tbd_count < 2; tbd_count++) {
uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev,
- tbd_address);
+ tbd_address,
+ attrs);
uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev,
- tbd_address + 4);
+ tbd_address + 4,
+ attrs);
uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev,
- tbd_address + 6);
+ tbd_address + 6,
+ attrs);
tbd_address += 8;
TRACE(RXTX, logout
("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
@@ -795,9 +799,12 @@ static void tx_command(EEPRO100State *s)
}
tbd_address = tbd_array;
for (; tbd_count < s->tx.tbd_count; tbd_count++) {
- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address);
- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4);
- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6);
+ uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address,
+ attrs);
+ uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4,
+ attrs);
+ uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6,
+ attrs);
tbd_address += 8;
TRACE(RXTX, logout
("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 1f2c79dd58..c76e4868f7 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -70,16 +70,18 @@ static const VMStateDescription vmstate_pci_tulip = {
static void tulip_desc_read(TULIPState *s, hwaddr p,
struct tulip_descriptor *desc)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+
if (s->csr[0] & CSR0_DBO) {
- desc->status = ldl_be_pci_dma(&s->dev, p);
- desc->control = ldl_be_pci_dma(&s->dev, p + 4);
- desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8);
- desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12);
+ desc->status = ldl_be_pci_dma(&s->dev, p, attrs);
+ desc->control = ldl_be_pci_dma(&s->dev, p + 4, attrs);
+ desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8, attrs);
+ desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12, attrs);
} else {
- desc->status = ldl_le_pci_dma(&s->dev, p);
- desc->control = ldl_le_pci_dma(&s->dev, p + 4);
- desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8);
- desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12);
+ desc->status = ldl_le_pci_dma(&s->dev, p, attrs);
+ desc->control = ldl_le_pci_dma(&s->dev, p + 4, attrs);
+ desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8, attrs);
+ desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12, attrs);
}
}
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index b4d448370f..23380008e1 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -202,7 +202,9 @@ static uint64_t megasas_frame_get_context(MegasasState *s,
unsigned long frame)
{
PCIDevice *pci = &s->parent_obj;
- return ldq_le_pci_dma(pci, frame + offsetof(struct mfi_frame_header, context));
+ return ldq_le_pci_dma(pci,
+ frame + offsetof(struct mfi_frame_header, context),
+ MEMTXATTRS_UNSPECIFIED);
}
static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd)
@@ -533,7 +535,8 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
s->busy++;
if (s->consumer_pa) {
- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
+ s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa,
+ MEMTXATTRS_UNSPECIFIED);
}
trace_megasas_qf_enqueue(cmd->index, cmd->count, cmd->context,
s->reply_queue_head, s->reply_queue_tail, s->busy);
@@ -564,14 +567,14 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset,
context, attrs);
}
- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa);
+ s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs);
trace_megasas_qf_complete(context, s->reply_queue_head,
s->reply_queue_tail, s->busy);
}
if (megasas_intr_enabled(s)) {
/* Update reply queue pointer */
- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa);
+ s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs);
tail = s->reply_queue_head;
s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds);
trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail,
@@ -636,6 +639,7 @@ static void megasas_abort_command(MegasasCmd *cmd)
static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
PCIDevice *pcid = PCI_DEVICE(s);
uint32_t pa_hi, pa_lo;
hwaddr iq_pa, initq_size = sizeof(struct mfi_init_qinfo);
@@ -674,9 +678,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
pa_lo = le32_to_cpu(initq->pi_addr_lo);
pa_hi = le32_to_cpu(initq->pi_addr_hi);
s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo;
- s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa);
+ s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa, attrs);
s->reply_queue_head %= MEGASAS_MAX_FRAMES;
- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
+ s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, attrs);
s->reply_queue_tail %= MEGASAS_MAX_FRAMES;
flags = le32_to_cpu(initq->flags);
if (flags & MFI_QUEUE_FLAG_CONTEXT64) {
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index f6c7765544..ac9f4dfcd2 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -172,14 +172,15 @@ static const int mpi_request_sizes[] = {
static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length,
dma_addr_t *sgaddr)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
PCIDevice *pci = (PCIDevice *) s;
dma_addr_t addr;
if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
- addr = ldq_le_pci_dma(pci, *sgaddr + 4);
+ addr = ldq_le_pci_dma(pci, *sgaddr + 4, attrs);
*sgaddr += 12;
} else {
- addr = ldl_le_pci_dma(pci, *sgaddr + 4);
+ addr = ldl_le_pci_dma(pci, *sgaddr + 4, attrs);
*sgaddr += 8;
}
return addr;
@@ -203,7 +204,7 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr)
dma_addr_t addr, len;
uint32_t flags_and_length;
- flags_and_length = ldl_le_pci_dma(pci, sgaddr);
+ flags_and_length = ldl_le_pci_dma(pci, sgaddr, MEMTXATTRS_UNSPECIFIED);
len = flags_and_length & MPI_SGE_LENGTH_MASK;
if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
!= MPI_SGE_FLAGS_SIMPLE_ELEMENT ||
@@ -234,7 +235,8 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr)
break;
}
- flags_and_length = ldl_le_pci_dma(pci, next_chain_addr);
+ flags_and_length = ldl_le_pci_dma(pci, next_chain_addr,
+ MEMTXATTRS_UNSPECIFIED);
if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
!= MPI_SGE_FLAGS_CHAIN_ELEMENT) {
return MPI_IOCSTATUS_INVALID_SGL;
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 59c3e8ba04..33e16f9111 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -52,7 +52,8 @@
#define RS_GET_FIELD(m, field) \
(ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
- (m)->rs_pa + offsetof(struct PVSCSIRingsState, field)))
+ (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), \
+ MEMTXATTRS_UNSPECIFIED))
#define RS_SET_FIELD(m, field, val) \
(stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
(m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 30c477f36e..47fb79aa4d 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3444,6 +3444,7 @@ static int usb_xhci_post_load(void *opaque, int version_id)
}
ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &addr, MEMTXATTRS_UNSPECIFIED);
slot->ctx = xhci_mask64(addr);
+
xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx));
slot->uport = xhci_lookup_uport(xhci, slot_ctx);
if (!slot->uport) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index f6b0e843c1..d0f0d9bd50 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -867,11 +867,11 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \
- dma_addr_t addr) \
+ dma_addr_t addr, \
+ MemTxAttrs attrs) \
{ \
uint##_bits##_t val; \
- ld##_l##_dma(pci_get_address_space(dev), addr, &val, \
- MEMTXATTRS_UNSPECIFIED); \
+ ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \
return val; \
} \
static inline void st##_s##_pci_dma(PCIDevice *dev, \
--
2.27.0

View File

@ -0,0 +1,88 @@
From de60977c6a41b6de65e74918024c150e44311940 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Wed, 15 Dec 2021 22:18:19 +0100
Subject: [PATCH 10/25] pci: Let pci_dma_rw() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling pci_dma_rw().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-10-philmd@redhat.com>
---
hw/audio/intel-hda.c | 3 ++-
hw/scsi/esp-pci.c | 2 +-
include/hw/pci/pci.h | 10 ++++++----
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 8ce9df64e3..fb3d34a4a0 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -427,7 +427,8 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
dprint(d, 3, "dma: entry %d, pos %d/%d, copy %d\n",
st->be, st->bp, st->bpl[st->be].len, copy);
- pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output);
+ pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output,
+ MEMTXATTRS_UNSPECIFIED);
st->lpib += copy;
st->bp += copy;
buf += copy;
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index dac054aeed..1792f84cea 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -280,7 +280,7 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
len = pci->dma_regs[DMA_WBC];
}
- pci_dma_rw(PCI_DEVICE(pci), addr, buf, len, dir);
+ pci_dma_rw(PCI_DEVICE(pci), addr, buf, len, dir, MEMTXATTRS_UNSPECIFIED);
/* update status registers */
pci->dma_regs[DMA_WBC] -= len;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c3d5e06364..c7177646a4 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -821,10 +821,10 @@ static inline AddressSpace *pci_get_address_space(PCIDevice *dev)
*/
static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
void *buf, dma_addr_t len,
- DMADirection dir)
+ DMADirection dir, MemTxAttrs attrs)
{
return dma_memory_rw(pci_get_address_space(dev), addr, buf, len,
- dir, MEMTXATTRS_UNSPECIFIED);
+ dir, attrs);
}
/**
@@ -842,7 +842,8 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr,
void *buf, dma_addr_t len)
{
- return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
+ return pci_dma_rw(dev, addr, buf, len,
+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
}
/**
@@ -860,7 +861,8 @@ static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr,
static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
const void *buf, dma_addr_t len)
{
- return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE);
+ return pci_dma_rw(dev, addr, (void *) buf, len,
+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
}
#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
--
2.27.0

View File

@ -0,0 +1,43 @@
From b498014d3214e053cfc97d0d48bcaae3176764ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 23:47:30 +0100
Subject: [PATCH 21/25] pci: Let st*_pci_dma() propagate MemTxResult
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
st*_dma() returns a MemTxResult type. Do not discard
it, return it to the caller.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-23-philmd@redhat.com>
---
include/hw/pci/pci.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index d0f0d9bd50..a9834e17e2 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -874,12 +874,12 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \
return val; \
} \
- static inline void st##_s##_pci_dma(PCIDevice *dev, \
- dma_addr_t addr, \
- uint##_bits##_t val, \
- MemTxAttrs attrs) \
+ static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \
+ dma_addr_t addr, \
+ uint##_bits##_t val, \
+ MemTxAttrs attrs) \
{ \
- st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \
+ return st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \
}
PCI_DMA_DEFINE_LDST(ub, b, 8);
--
2.27.0

View File

@ -0,0 +1,299 @@
From b823af328bc872734b0a2e4b0db3c5d2ec27a83f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Fri, 17 Dec 2021 22:39:42 +0100
Subject: [PATCH 19/25] pci: Let st*_pci_dma() take MemTxAttrs argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let devices specify transaction attributes when calling st*_pci_dma().
Keep the default MEMTXATTRS_UNSPECIFIED in the few callers.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211223115554.3155328-21-philmd@redhat.com>
---
hw/audio/intel-hda.c | 10 ++++++----
hw/net/eepro100.c | 29 ++++++++++++++++++-----------
hw/net/tulip.c | 18 ++++++++++--------
hw/scsi/megasas.c | 15 ++++++++++-----
hw/scsi/vmw_pvscsi.c | 3 ++-
include/hw/pci/pci.h | 11 ++++++-----
6 files changed, 52 insertions(+), 34 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index fb3d34a4a0..3309ae0ea1 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -345,6 +345,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
hwaddr addr;
@@ -367,8 +368,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
wp = (d->rirb_wp + 1) & 0xff;
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
- stl_le_pci_dma(&d->pci, addr + 8*wp, response);
- stl_le_pci_dma(&d->pci, addr + 8*wp + 4, ex);
+ stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs);
+ stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs);
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
@@ -394,6 +395,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
uint8_t *buf, uint32_t len)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
hwaddr addr;
@@ -428,7 +430,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
st->be, st->bp, st->bpl[st->be].len, copy);
pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output,
- MEMTXATTRS_UNSPECIFIED);
+ attrs);
st->lpib += copy;
st->bp += copy;
buf += copy;
@@ -451,7 +453,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
if (d->dp_lbase & 0x01) {
s = st - d->st;
addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);
- stl_le_pci_dma(&d->pci, addr + 8*s, st->lpib);
+ stl_le_pci_dma(&d->pci, addr + 8 * s, st->lpib, attrs);
}
dprint(d, 3, "dma: --\n");
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 2474cf3dc2..160b9b0b4c 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -703,6 +703,8 @@ static void set_ru_state(EEPRO100State * s, ru_state_t state)
static void dump_statistics(EEPRO100State * s)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+
/* Dump statistical data. Most data is never changed by the emulation
* and always 0, so we first just copy the whole block and then those
* values which really matter.
@@ -710,16 +712,18 @@ static void dump_statistics(EEPRO100State * s)
*/
pci_dma_write(&s->dev, s->statsaddr, &s->statistics, s->stats_size);
stl_le_pci_dma(&s->dev, s->statsaddr + 0,
- s->statistics.tx_good_frames);
+ s->statistics.tx_good_frames, attrs);
stl_le_pci_dma(&s->dev, s->statsaddr + 36,
- s->statistics.rx_good_frames);
+ s->statistics.rx_good_frames, attrs);
stl_le_pci_dma(&s->dev, s->statsaddr + 48,
- s->statistics.rx_resource_errors);
+ s->statistics.rx_resource_errors, attrs);
stl_le_pci_dma(&s->dev, s->statsaddr + 60,
- s->statistics.rx_short_frame_errors);
+ s->statistics.rx_short_frame_errors, attrs);
#if 0
- stw_le_pci_dma(&s->dev, s->statsaddr + 76, s->statistics.xmt_tco_frames);
- stw_le_pci_dma(&s->dev, s->statsaddr + 78, s->statistics.rcv_tco_frames);
+ stw_le_pci_dma(&s->dev, s->statsaddr + 76,
+ s->statistics.xmt_tco_frames, attrs);
+ stw_le_pci_dma(&s->dev, s->statsaddr + 78,
+ s->statistics.rcv_tco_frames, attrs);
missing("CU dump statistical counters");
#endif
}
@@ -836,6 +840,7 @@ static void set_multicast_list(EEPRO100State *s)
static void action_command(EEPRO100State *s)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
/* The loop below won't stop if it gets special handcrafted data.
Therefore we limit the number of iterations. */
unsigned max_loop_count = 16;
@@ -922,7 +927,7 @@ static void action_command(EEPRO100State *s)
}
/* Write new status. */
stw_le_pci_dma(&s->dev, s->cb_address,
- s->tx.status | ok_status | STATUS_C);
+ s->tx.status | ok_status | STATUS_C, attrs);
if (bit_i) {
/* CU completed action. */
eepro100_cx_interrupt(s);
@@ -949,6 +954,7 @@ static void action_command(EEPRO100State *s)
static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
cu_state_t cu_state;
switch (val) {
case CU_NOP:
@@ -998,7 +1004,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
/* Dump statistical counters. */
TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));
dump_statistics(s);
- stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005);
+ stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005, attrs);
break;
case CU_CMD_BASE:
/* Load CU base. */
@@ -1009,7 +1015,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
/* Dump and reset statistical counters. */
TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));
dump_statistics(s);
- stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007);
+ stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007, attrs);
memset(&s->statistics, 0, sizeof(s->statistics));
break;
case CU_SRESUME:
@@ -1624,6 +1630,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
* - Magic packets should set bit 30 in power management driver register.
* - Interesting packets should set bit 29 in power management driver register.
*/
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
EEPRO100State *s = qemu_get_nic_opaque(nc);
uint16_t rfd_status = 0xa000;
#if defined(CONFIG_PAD_RECEIVED_FRAMES)
@@ -1738,9 +1745,9 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",
rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset +
- offsetof(eepro100_rx_t, status), rfd_status);
+ offsetof(eepro100_rx_t, status), rfd_status, attrs);
stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset +
- offsetof(eepro100_rx_t, count), size);
+ offsetof(eepro100_rx_t, count), size, attrs);
/* Early receive interrupt not supported. */
#if 0
eepro100_er_interrupt(s);
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index ca69f7ea5e..1f2c79dd58 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -86,16 +86,18 @@ static void tulip_desc_read(TULIPState *s, hwaddr p,
static void tulip_desc_write(TULIPState *s, hwaddr p,
struct tulip_descriptor *desc)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
+
if (s->csr[0] & CSR0_DBO) {
- stl_be_pci_dma(&s->dev, p, desc->status);
- stl_be_pci_dma(&s->dev, p + 4, desc->control);
- stl_be_pci_dma(&s->dev, p + 8, desc->buf_addr1);
- stl_be_pci_dma(&s->dev, p + 12, desc->buf_addr2);
+ stl_be_pci_dma(&s->dev, p, desc->status, attrs);
+ stl_be_pci_dma(&s->dev, p + 4, desc->control, attrs);
+ stl_be_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs);
+ stl_be_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs);
} else {
- stl_le_pci_dma(&s->dev, p, desc->status);
- stl_le_pci_dma(&s->dev, p + 4, desc->control);
- stl_le_pci_dma(&s->dev, p + 8, desc->buf_addr1);
- stl_le_pci_dma(&s->dev, p + 12, desc->buf_addr2);
+ stl_le_pci_dma(&s->dev, p, desc->status, attrs);
+ stl_le_pci_dma(&s->dev, p + 4, desc->control, attrs);
+ stl_le_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs);
+ stl_le_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs);
}
}
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index f1c4d5782b..b4d448370f 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -168,14 +168,16 @@ static void megasas_frame_set_cmd_status(MegasasState *s,
unsigned long frame, uint8_t v)
{
PCIDevice *pci = &s->parent_obj;
- stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, cmd_status), v);
+ stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, cmd_status),
+ v, MEMTXATTRS_UNSPECIFIED);
}
static void megasas_frame_set_scsi_status(MegasasState *s,
unsigned long frame, uint8_t v)
{
PCIDevice *pci = &s->parent_obj;
- stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status), v);
+ stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status),
+ v, MEMTXATTRS_UNSPECIFIED);
}
static inline const char *mfi_frame_desc(unsigned int cmd)
@@ -541,6 +543,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
static void megasas_complete_frame(MegasasState *s, uint64_t context)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
PCIDevice *pci_dev = PCI_DEVICE(s);
int tail, queue_offset;
@@ -554,10 +557,12 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
*/
if (megasas_use_queue64(s)) {
queue_offset = s->reply_queue_head * sizeof(uint64_t);
- stq_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, context);
+ stq_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset,
+ context, attrs);
} else {
queue_offset = s->reply_queue_head * sizeof(uint32_t);
- stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, context);
+ stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset,
+ context, attrs);
}
s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa);
trace_megasas_qf_complete(context, s->reply_queue_head,
@@ -571,7 +576,7 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)
s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds);
trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail,
s->busy);
- stl_le_pci_dma(pci_dev, s->producer_pa, s->reply_queue_head);
+ stl_le_pci_dma(pci_dev, s->producer_pa, s->reply_queue_head, attrs);
/* Notify HBA */
if (msix_enabled(pci_dev)) {
trace_megasas_msix_raise(0);
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index cd76bd67ab..59c3e8ba04 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -55,7 +55,8 @@
(m)->rs_pa + offsetof(struct PVSCSIRingsState, field)))
#define RS_SET_FIELD(m, field, val) \
(stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
- (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val))
+ (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \
+ MEMTXATTRS_UNSPECIFIED))
struct PVSCSIClass {
PCIDeviceClass parent_class;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 71c6513641..f6b0e843c1 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -874,11 +874,12 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
MEMTXATTRS_UNSPECIFIED); \
return val; \
} \
- static inline void st##_s##_pci_dma(PCIDevice *dev, \
- dma_addr_t addr, uint##_bits##_t val) \
- { \
- st##_s##_dma(pci_get_address_space(dev), addr, val, \
- MEMTXATTRS_UNSPECIFIED); \
+ static inline void st##_s##_pci_dma(PCIDevice *dev, \
+ dma_addr_t addr, \
+ uint##_bits##_t val, \
+ MemTxAttrs attrs) \
+ { \
+ st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \
}
PCI_DMA_DEFINE_LDST(ub, b, 8);
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: qemu Name: qemu
Version: 6.2.0 Version: 6.2.0
Release: 38 Release: 39
Epoch: 2 Epoch: 2
Summary: QEMU is a generic and open source machine emulator and virtualizer Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -254,6 +254,31 @@ Patch0240: tests-acpi-add-SLIC-table-test.patch
Patch0241: tests-acpi-SLIC-update-expected-blobs.patch Patch0241: tests-acpi-SLIC-update-expected-blobs.patch
Patch0242: hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch Patch0242: hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch
Patch0243: tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch Patch0243: tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch
Patch0244: hw-scsi-megasas-Use-uint32_t-for-reply-queue-head-ta.patch
Patch0245: dma-Let-dma_memory_valid-take-MemTxAttrs-argument.patch
Patch0246: dma-Let-dma_memory_set-take-MemTxAttrs-argument.patch
Patch0247: dma-Let-dma_memory_rw_relaxed-take-MemTxAttrs-argume.patch
Patch0248: dma-Let-dma_memory_rw-take-MemTxAttrs-argument.patch
Patch0249: dma-Let-dma_memory_read-write-take-MemTxAttrs-argume.patch
Patch0250: dma-Let-dma_memory_map-take-MemTxAttrs-argument.patch
Patch0251: dma-Have-dma_buf_rw-take-a-void-pointer.patch
Patch0252: dma-Have-dma_buf_read-dma_buf_write-take-a-void-poin.patch
Patch0253: pci-Let-pci_dma_rw-take-MemTxAttrs-argument.patch
Patch0254: dma-Let-dma_buf_rw-take-MemTxAttrs-argument.patch
Patch0255: dma-Let-dma_buf_write-take-MemTxAttrs-argument.patch
Patch0256: dma-Let-dma_buf_read-take-MemTxAttrs-argument.patch
Patch0257: dma-Let-dma_buf_rw-propagate-MemTxResult.patch
Patch0258: dma-Let-st-_dma-take-MemTxAttrs-argument.patch
Patch0259: dma-Let-ld-_dma-take-MemTxAttrs-argument.patch
Patch0260: dma-Let-st-_dma-propagate-MemTxResult.patch
Patch0261: dma-Let-ld-_dma-propagate-MemTxResult.patch
Patch0262: pci-Let-st-_pci_dma-take-MemTxAttrs-argument.patch
Patch0263: pci-Let-ld-_pci_dma-take-MemTxAttrs-argument.patch
Patch0264: pci-Let-st-_pci_dma-propagate-MemTxResult.patch
Patch0265: pci-Let-ld-_pci_dma-propagate-MemTxResult.patch
Patch0266: hw-audio-intel-hda-Do-not-ignore-DMA-overrun-errors.patch
Patch0267: hw-audio-intel-hda-Restrict-DMA-engine-to-memories-n.patch
Patch0268: tests-qtest-intel-hda-test-Add-reproducer-for-issue-.patch
BuildRequires: flex BuildRequires: flex
BuildRequires: gcc BuildRequires: gcc
@ -745,6 +770,33 @@ getent passwd qemu >/dev/null || \
%endif %endif
%changelog %changelog
* Thu Jun 09 2022 yezengruan <yezengruan@huawei.com> - 2:6.2.0-39
- hw/scsi/megasas: Use uint32_t for reply queue head/tail values
- dma: Let dma_memory_valid() take MemTxAttrs argument
- dma: Let dma_memory_set() take MemTxAttrs argument
- dma: Let dma_memory_rw_relaxed() take MemTxAttrs argument
- dma: Let dma_memory_rw() take MemTxAttrs argument
- dma: Let dma_memory_read/write() take MemTxAttrs argument
- dma: Let dma_memory_map() take MemTxAttrs argument
- dma: Have dma_buf_rw() take a void pointer
- dma: Have dma_buf_read() / dma_buf_write() take a void pointer
- pci: Let pci_dma_rw() take MemTxAttrs argument
- dma: Let dma_buf_rw() take MemTxAttrs argument
- dma: Let dma_buf_write() take MemTxAttrs argument
- dma: Let dma_buf_read() take MemTxAttrs argument
- dma: Let dma_buf_rw() propagate MemTxResult
- dma: Let st*_dma() take MemTxAttrs argument
- dma: Let ld*_dma() take MemTxAttrs argument
- dma: Let st*_dma() propagate MemTxResult
- dma: Let ld*_dma() propagate MemTxResult
- pci: Let st*_pci_dma() take MemTxAttrs argument
- pci: Let ld*_pci_dma() take MemTxAttrs argument
- pci: Let st*_pci_dma() propagate MemTxResult
- pci: Let ld*_pci_dma() propagate MemTxResult
- hw/audio/intel-hda: Do not ignore DMA overrun errors
- hw/audio/intel-hda: Restrict DMA engine to memories (not MMIO devices)
- tests/qtest/intel-hda-test: Add reproducer for issue #542
* Mon May 30 2022 yezengruan <yezengruan@huawei.com> - 2:6.2.0-38 * Mon May 30 2022 yezengruan <yezengruan@huawei.com> - 2:6.2.0-38
- acpi: fix QEMU crash when started with SLIC table - acpi: fix QEMU crash when started with SLIC table
- tests: acpi: whitelist expected blobs before changing them - tests: acpi: whitelist expected blobs before changing them

View File

@ -0,0 +1,135 @@
From 16c1b4c9124da1b1e5fe123c9c9df683372f64a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Sat, 18 Dec 2021 17:09:12 +0100
Subject: [PATCH 25/25] tests/qtest/intel-hda-test: Add reproducer for issue
#542
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Include the qtest reproducer provided by Alexander Bulekov
in https://gitlab.com/qemu-project/qemu/-/issues/542.
Without the previous commit, we get:
$ make check-qtest-i386
...
Running test tests/qtest/intel-hda-test
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1580408==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc3d566fe0
#0 0x63d297cf in address_space_translate_internal softmmu/physmem.c:356
#1 0x63d27260 in flatview_do_translate softmmu/physmem.c:499:15
#2 0x63d27af5 in flatview_translate softmmu/physmem.c:565:15
#3 0x63d4ce84 in flatview_write softmmu/physmem.c:2850:10
#4 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18
#5 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16
#6 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12
#7 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12
#8 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12
#9 0x62ae5ec0 in stl_le_dma include/sysemu/dma.h:275:1
#10 0x62ae5ba2 in stl_le_pci_dma include/hw/pci/pci.h:871:1
#11 0x62ad59a6 in intel_hda_response hw/audio/intel-hda.c:372:12
#12 0x62ad2afb in hda_codec_response hw/audio/intel-hda.c:107:5
#13 0x62aec4e1 in hda_audio_command hw/audio/hda-codec.c:655:5
#14 0x62ae05d9 in intel_hda_send_command hw/audio/intel-hda.c:307:5
#15 0x62adff54 in intel_hda_corb_run hw/audio/intel-hda.c:342:9
#16 0x62adc13b in intel_hda_set_corb_wp hw/audio/intel-hda.c:548:5
#17 0x62ae5942 in intel_hda_reg_write hw/audio/intel-hda.c:977:9
#18 0x62ada10a in intel_hda_mmio_write hw/audio/intel-hda.c:1054:5
#19 0x63d8f383 in memory_region_write_accessor softmmu/memory.c:492:5
#20 0x63d8ecc1 in access_with_adjusted_size softmmu/memory.c:554:18
#21 0x63d8d5d6 in memory_region_dispatch_write softmmu/memory.c:1504:16
#22 0x63d5e85e in flatview_write_continue softmmu/physmem.c:2812:23
#23 0x63d4d05b in flatview_write softmmu/physmem.c:2854:12
#24 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18
#25 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16
#26 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12
#27 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12
#28 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12
#29 0x62ae5ec0 in stl_le_dma include/sysemu/dma.h:275:1
#30 0x62ae5ba2 in stl_le_pci_dma include/hw/pci/pci.h:871:1
#31 0x62ad59a6 in intel_hda_response hw/audio/intel-hda.c:372:12
#32 0x62ad2afb in hda_codec_response hw/audio/intel-hda.c:107:5
#33 0x62aec4e1 in hda_audio_command hw/audio/hda-codec.c:655:5
#34 0x62ae05d9 in intel_hda_send_command hw/audio/intel-hda.c:307:5
#35 0x62adff54 in intel_hda_corb_run hw/audio/intel-hda.c:342:9
#36 0x62adc13b in intel_hda_set_corb_wp hw/audio/intel-hda.c:548:5
#37 0x62ae5942 in intel_hda_reg_write hw/audio/intel-hda.c:977:9
#38 0x62ada10a in intel_hda_mmio_write hw/audio/intel-hda.c:1054:5
#39 0x63d8f383 in memory_region_write_accessor softmmu/memory.c:492:5
#40 0x63d8ecc1 in access_with_adjusted_size softmmu/memory.c:554:18
#41 0x63d8d5d6 in memory_region_dispatch_write softmmu/memory.c:1504:16
#42 0x63d5e85e in flatview_write_continue softmmu/physmem.c:2812:23
#43 0x63d4d05b in flatview_write softmmu/physmem.c:2854:12
#44 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18
#45 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16
#46 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12
#47 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12
#48 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12
...
SUMMARY: AddressSanitizer: stack-overflow softmmu/physmem.c:356 in address_space_translate_internal
==1580408==ABORTING
Broken pipe
Aborted (core dumped)
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20211218160912.1591633-4-philmd@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/qtest/intel-hda-test.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c
index fc25ccc33c..a58c98e4d1 100644
--- a/tests/qtest/intel-hda-test.c
+++ b/tests/qtest/intel-hda-test.c
@@ -29,11 +29,45 @@ static void ich9_test(void)
qtest_end();
}
+/*
+ * https://gitlab.com/qemu-project/qemu/-/issues/542
+ * Used to trigger:
+ * AddressSanitizer: stack-overflow
+ */
+static void test_issue542_ich6(void)
+{
+ QTestState *s;
+
+ s = qtest_init("-nographic -nodefaults -M pc-q35-6.2 "
+ "-device intel-hda,id=" HDA_ID CODEC_DEVICES);
+
+ qtest_outl(s, 0xcf8, 0x80000804);
+ qtest_outw(s, 0xcfc, 0x06);
+ qtest_bufwrite(s, 0xff0d060f, "\x03", 1);
+ qtest_bufwrite(s, 0x0, "\x12", 1);
+ qtest_bufwrite(s, 0x2, "\x2a", 1);
+ qtest_writeb(s, 0x0, 0x12);
+ qtest_writeb(s, 0x2, 0x2a);
+ qtest_outl(s, 0xcf8, 0x80000811);
+ qtest_outl(s, 0xcfc, 0x006a4400);
+ qtest_bufwrite(s, 0x6a44005a, "\x01", 1);
+ qtest_bufwrite(s, 0x6a44005c, "\x02", 1);
+ qtest_bufwrite(s, 0x6a442050, "\x00\x00\x44\x6a", 4);
+ qtest_bufwrite(s, 0x6a44204a, "\x01", 1);
+ qtest_bufwrite(s, 0x6a44204c, "\x02", 1);
+ qtest_bufwrite(s, 0x6a44005c, "\x02", 1);
+ qtest_bufwrite(s, 0x6a442050, "\x00\x00\x44\x6a", 4);
+ qtest_bufwrite(s, 0x6a44204a, "\x01", 1);
+ qtest_bufwrite(s, 0x6a44204c, "\x02", 1);
+ qtest_quit(s);
+}
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
qtest_add_func("/intel-hda/ich6", ich6_test);
qtest_add_func("/intel-hda/ich9", ich9_test);
+ qtest_add_func("/intel-hda/fuzz/issue542", test_issue542_ich6);
return g_test_run();
}
--
2.27.0