[RFC PATCH 3/4] nvme: export helpers to implement vfio-nvme lm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Export the nvme_error_status() function to allow error status
translation from external modules such as VFIO-based drivers.

Add helper functions in nvme-pci to support virtual function (VF)
command submission and controller ID retrieval:

  - nvme_submit_vf_cmd() submits a synchronous admin command
    from a VF context using the PF's admin queue.
  - nvme_get_ctrl_id() returns the controller ID associated
    with a PCI device.

These changes support VFIO NVMe Live Migration workflows and
infrastructure by enabling necessary low-level admin command access.

Signed-off-by: Lei Rao <lei.rao@xxxxxxxxx>
Signed-off-by: Max Gurtovoy <mgurtovoy@xxxxxxxxxx>
Signed-off-by: Chaitanya Kulkarni <kch@xxxxxxxxxx>
---
 drivers/nvme/host/core.c |  3 ++-
 drivers/nvme/host/nvme.h |  5 +++++
 drivers/nvme/host/pci.c  | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2445862ac7d4..3620e7cb21d1 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -278,7 +278,7 @@ void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl)
 	nvme_put_ctrl(ctrl);
 }
 
-static blk_status_t nvme_error_status(u16 status)
+blk_status_t nvme_error_status(u16 status)
 {
 	switch (status & NVME_SCT_SC_MASK) {
 	case NVME_SC_SUCCESS:
@@ -318,6 +318,7 @@ static blk_status_t nvme_error_status(u16 status)
 		return BLK_STS_IOERR;
 	}
 }
+EXPORT_SYMBOL_GPL(nvme_error_status);
 
 static void nvme_retry_req(struct request *req)
 {
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index cfd2b5b90b91..5549c7e3bcd3 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -1218,4 +1218,9 @@ static inline bool nvme_multi_css(struct nvme_ctrl *ctrl)
 	return (ctrl->ctrl_config & NVME_CC_CSS_MASK) == NVME_CC_CSS_CSI;
 }
 
+blk_status_t nvme_error_status(u16 status);
+int nvme_submit_vf_cmd(struct pci_dev *dev, struct nvme_command *cmd,
+		       size_t *result, void *buffer, unsigned int bufflen);
+u16 nvme_get_ctrl_id(struct pci_dev *dev);
+
 #endif /* _NVME_H */
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 4cf87fb5d857..b239d38485ee 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3936,6 +3936,40 @@ static struct pci_driver nvme_driver = {
 	.err_handler	= &nvme_err_handler,
 };
 
+u16 nvme_get_ctrl_id(struct pci_dev *dev)
+{
+	struct nvme_dev *ndev = pci_iov_get_pf_drvdata(dev, &nvme_driver);
+
+	return ndev->ctrl.cntlid;
+}
+EXPORT_SYMBOL_GPL(nvme_get_ctrl_id);
+
+int nvme_submit_vf_cmd(struct pci_dev *dev, struct nvme_command *cmd,
+		size_t *result, void *buffer, unsigned int bufflen)
+{
+	struct nvme_dev *ndev = NULL;
+	union nvme_result res = { };
+	int ret;
+
+	ndev = pci_iov_get_pf_drvdata(dev, &nvme_driver);
+	if (IS_ERR(ndev))
+		return PTR_ERR(ndev);
+	ret = __nvme_submit_sync_cmd(ndev->ctrl.admin_q, cmd, &res, buffer,
+					bufflen, NVME_QID_ANY, 0);
+	if (ret < 0)
+		return ret;
+
+	if (ret > 0) {
+		ret = blk_status_to_errno(nvme_error_status(ret));
+		return ret;
+	}
+
+	if (result)
+		*result = le32_to_cpu(res.u32);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nvme_submit_vf_cmd);
+
 static int __init nvme_init(void)
 {
 	BUILD_BUG_ON(sizeof(struct nvme_create_cq) != 64);
-- 
2.40.0





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux