From: Daniel Gomez <[email protected]> Commit 53493c1f83 ("hw/nvme: cap MDTS value for internal limitation") capped MDTS so the worst-case PRP count would fit in IOV_MAX, leaving transfers limited to 2 MiB.
Now that dma_blk_cb() can batch IOs up to IOV_MAX instead of limiting to IOV_MAX, raise the limit via a new NVME_MDTS_MAX = 11 (i.e. 8 MiB) to match Linux's NVME_MAX_BYTES. Per spec, MDTS=0 means "that there is no maximum data transfer size". With the dma_blk_cb() changes, we can potentionally honor that literally, however Linux host driver will clamp requests at NVME_MAX_BYTES regardless of the advertised MDTS. Coerce mdts=0 to NVME_MDTS_MAX so the value the guest sees matches the current Linux ceiling and document it. Signed-off-by: Daniel Gomez <[email protected]> --- hw/nvme/ctrl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 00995d9808f..123f969cc03 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -104,6 +104,9 @@ * as a power of two (2^n) and is in units of the minimum memory page size * (CAP.MPSMIN). The default value is 7 (i.e. 512 KiB). * + * NOTE: A value of 0 means "that there is no maximum data transfer size" per + * spec, but here it is coerced to 11 (i.e. 8 MiB). + * * - `vsl` * Indicates the maximum data size limit for the Verify command. Like `mdts`, * this value is specified as a power of two (2^n) and is in units of the @@ -226,6 +229,7 @@ #define NVME_VF_RES_GRANULARITY 1 #define NVME_VF_OFFSET 0x1 #define NVME_VF_STRIDE 1 +#define NVME_MDTS_MAX 11 #define NVME_GUEST_ERR(trace, fmt, ...) \ do { \ @@ -8624,10 +8628,13 @@ static bool nvme_check_params(NvmeCtrl *n, Error **errp) host_memory_backend_set_mapped(n->pmr.dev, true); } - if (!n->params.mdts || ((1 << n->params.mdts) + 1) > IOV_MAX) { - error_setg(errp, "mdts exceeds IOV_MAX"); + if (n->params.mdts > NVME_MDTS_MAX) { + error_setg(errp, "mdts must be in [0, %u]", NVME_MDTS_MAX); return false; } + if (n->params.mdts == 0) { + n->params.mdts = NVME_MDTS_MAX; + } if (n->params.zasl > n->params.mdts) { error_setg(errp, "zoned.zasl (Zone Append Size Limit) must be less " -- 2.53.0
