From: Daniel Gomez <[email protected]>
NvmeCmd, NvmeRwCmd, and NvmeIdCtrl are NVMe data structures in
little-endian, fix the cases where their fields are used as host values.
Note that in the case of nvme_atomic_configure_max_write_size() we now
pass the clamped AWUPF instead of the unclamped one.
Fixes: ebd1568fc732 ("hw/nvme: add atomic write support")
Fixes: 3b41acc96299 ("hw/nvme: enable ns atomic writes")
Signed-off-by: Daniel Gomez <[email protected]>
---
hw/nvme/ctrl.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 4893cf7e741..c884ca8a181 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -7832,7 +7832,7 @@ static int nvme_atomic_write_check(NvmeCtrl *n, NvmeCmd
*cmd,
int i;
if ((cmd->opcode == NVME_CMD_READ) || ((cmd->opcode == NVME_CMD_WRITE) &&
- ((rw->nlb + 1) > atomic->atomic_max_write_size))) {
+ ((nlb + 1) > atomic->atomic_max_write_size))) {
cmd_atomic_wr = false;
}
@@ -7869,7 +7869,7 @@ static int nvme_atomic_write_check(NvmeCtrl *n, NvmeCmd
*cmd,
if (((req_rw->opcode == NVME_CMD_WRITE) ||
(req_rw->opcode == NVME_CMD_READ)) &&
- (cmd->nsid == req->ns->params.nsid)) {
+ (le32_to_cpu(cmd->nsid) == req->ns->params.nsid)) {
req_slba = le64_to_cpu(req_rw->slba);
req_nlb = (uint32_t)le16_to_cpu(req_rw->nlb);
req_elba = req_slba + req_nlb;
@@ -7895,7 +7895,7 @@ static int nvme_atomic_write_check(NvmeCtrl *n, NvmeCmd
*cmd,
static NvmeAtomic *nvme_get_atomic(NvmeCtrl *n, NvmeCmd *cmd)
{
- NvmeNamespace *ns = nvme_ns(n, cmd->nsid);
+ NvmeNamespace *ns = nvme_ns(n, le32_to_cpu(cmd->nsid));
if (ns && ns->atomic.atomic_writes) {
return &ns->atomic;
@@ -8889,6 +8889,7 @@ static void nvme_init_state(NvmeCtrl *n)
NvmeSecCtrlEntry *sctrl;
PCIDevice *pci = PCI_DEVICE(n);
NvmeIdCtrl *id = &n->id_ctrl;
+ uint16_t awun, awupf;
uint8_t max_vfs;
int i;
@@ -8950,19 +8951,20 @@ static void nvme_init_state(NvmeCtrl *n)
}
/* Atomic Write */
- id->awun = cpu_to_le16(n->params.atomic_awun);
- id->awupf = cpu_to_le16(n->params.atomic_awupf);
n->dn = n->params.atomic_dn;
+ awun = n->params.atomic_awun;
+ awupf = n->params.atomic_awupf;
- if (id->awun || id->awupf) {
- if (id->awupf > id->awun) {
- id->awupf = 0;
+ if (awun || awupf) {
+ if (awupf > awun) {
+ awupf = 0;
}
- nvme_atomic_configure_max_write_size(n->dn, n->params.atomic_awun,
- n->params.atomic_awupf,
- &n->atomic);
+ nvme_atomic_configure_max_write_size(n->dn, awun, awupf, &n->atomic);
}
+
+ id->awun = cpu_to_le16(awun);
+ id->awupf = cpu_to_le16(awupf);
}
static void nvme_init_cmb(NvmeCtrl *n, PCIDevice *pci_dev)
--
2.55.0