[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2] nvme: Check PSDT flag for admin and rw command
From: |
Qu Wenruo |
Subject: |
[Qemu-devel] [PATCH 2/2] nvme: Check PSDT flag for admin and rw command |
Date: |
Tue, 6 Jun 2017 15:38:06 +0800 |
Check PRP or SGL for Data Transfer(PSDT) flag for admin and read/write
commands.
For NVMe-over-PCIE, admin sq entry should not set SGL bits.
and rw sq entry PSDT flag should not be set beyond controller support.
Although currently either linux kernel NVMe-over-PCIE host driver uses
SGL nor qemu nvme controller supports it, it's never a bad idea to
enhance the check.
Signed-off-by: Qu Wenruo <address@hidden>
---
hw/block/nvme.c | 11 +++++++++++
hw/block/nvme.h | 7 ++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index fa1069160e..b2579594d9 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -284,6 +284,10 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns,
NvmeCmd *cmd,
block_acct_invalid(blk_get_stats(n->conf.blk), acct);
return NVME_LBA_RANGE | NVME_DNR;
}
+ if (!n->id_ctrl.sgls && NVME_CMD_FLAGS_PSDT(rw->flags)) {
+ block_acct_invalid(blk_get_stats(n->conf.blk), acct);
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
if (nvme_map_prp(&req->qsg, prp1, prp2, data_size, n)) {
block_acct_invalid(blk_get_stats(n->conf.blk), acct);
@@ -618,6 +622,11 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd
*cmd, NvmeRequest *req)
static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
{
+ /* Admin cmd for NVMe-over-PCIE should NOT use SGL */
+ if (NVME_CMD_FLAGS_PSDT(cmd->flags)) {
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
+
switch (cmd->opcode) {
case NVME_ADM_CMD_DELETE_SQ:
return nvme_del_sq(n, cmd);
@@ -967,6 +976,8 @@ static int nvme_init(PCIDevice *pci_dev)
if (blk_enable_write_cache(n->conf.blk)) {
id->vwc = 1;
}
+ /* TODO: Support SGL in NVMe-over-PCIE in both qemu and kernel */
+ id->sgls = 0;
n->bar.cap = 0;
NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 26be663d2d..caf21c5f94 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -229,9 +229,14 @@ typedef union NvmeDataPtr{
NvmeKeyedSGLDesc ksgl;
} NvmeDataPtr;
+#define _NVME_CMD_FLAGS_FUSE_MASK ((1 << 0) + (1 << 1))
+#define _NVME_CMD_FLAGS_PSDT_MASK ((1 << 15) + (1 << 14))
+#define NVME_CMD_FLAGS_FUSE(flags) ((flags) & _NVME_CMD_FLAGS_FUSE_MASK)
+#define NVME_CMD_FLAGS_PSDT(flags) ((flags) & _NVME_CMD_FLAGS_PSDT_MASK)
+
typedef struct NvmeCmd {
uint8_t opcode;
- uint8_t fuse;
+ uint8_t flags;
uint16_t cid;
uint32_t nsid;
uint64_t res1;
--
2.13.0