mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Emily Deng <Emily.Deng@amd.com>
To: <bhelgaas@google.com>, <alex.williamson@redhat.com>,
	<linux-pci@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<kvm@vger.kernel.org>
Cc: <Jerry.Jiang@amd.com>, <Andy.Zhang@amd.com>,
	<HaiJun.Chang@amd.com>, <Monk.Liu@amd.com>, <Horace.Chen@amd.com>,
	<ZhenGuo.Yin@amd.com>, Emily Deng <Emily.Deng@amd.com>
Subject: [PATCH 2/2] VFIO/PCI: Add VF reset notification to PF's VFIO user mode driver
Date: Mon, 5 Feb 2024 15:15:38 +0800	[thread overview]
Message-ID: <20240205071538.2665628-2-Emily.Deng@amd.com> (raw)
In-Reply-To: <20240205071538.2665628-1-Emily.Deng@amd.com>

VF doesn't have the ability to reset itself completely which will cause the
hardware in unstable state. So notify PF driver when the VF has been reset
to let the PF resets the VF completely, and remove the VF out of schedule.

How to implement this?
Add the reset callback function in pci_driver

Implement the callback functin in VFIO_PCI driver.

Add the VF RESET IRQ for user mode driver to let the user mode driver
know the VF has been reset.

Signed-off-by: Emily Deng <Emily.Deng@amd.com>
---
 drivers/vfio/pci/vfio_pci.c       | 14 ++++++++++++++
 drivers/vfio/pci/vfio_pci_core.c  | 26 ++++++++++++++++++++++++++
 drivers/vfio/pci/vfio_pci_intrs.c | 30 ++++++++++++++++++++++++++++++
 include/linux/vfio_pci_core.h     |  1 +
 include/uapi/linux/vfio.h         |  1 +
 5 files changed, 72 insertions(+)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 29091ee2e984..25b8d0a69532 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -185,6 +185,19 @@ static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn)
 	return vfio_pci_core_sriov_configure(vdev, nr_virtfn);
 }
 
+static void  vfio_pci_vf_reset_notification(struct pci_dev *pf, struct pci_dev *vf)
+{
+	struct vfio_pci_core_device *vdev = dev_get_drvdata(&pf->dev);
+	int i = pci_iov_vf_id(vf);
+
+	mutex_lock(&vdev->igate);
+
+	if (pf->is_physfn && vdev->vf_reset_trigger && vdev->vf_reset_trigger[i])
+		eventfd_signal(vdev->vf_reset_trigger[i], 1);
+
+	mutex_unlock(&vdev->igate);
+}
+
 static const struct pci_device_id vfio_pci_table[] = {
 	{ PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_ANY_ID, PCI_ANY_ID) }, /* match all by default */
 	{}
@@ -198,6 +211,7 @@ static struct pci_driver vfio_pci_driver = {
 	.probe			= vfio_pci_probe,
 	.remove			= vfio_pci_remove,
 	.sriov_configure	= vfio_pci_sriov_configure,
+	.sriov_vf_reset_notification = vfio_pci_vf_reset_notification,
 	.err_handler		= &vfio_pci_core_err_handlers,
 	.driver_managed_dma	= true,
 };
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 20d7b69ea6ff..1740d41231c9 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -686,6 +686,7 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev)
 {
 	struct vfio_pci_core_device *vdev =
 		container_of(core_vdev, struct vfio_pci_core_device, vdev);
+	int i;
 
 	if (vdev->sriov_pf_core_dev) {
 		mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock);
@@ -707,6 +708,17 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev)
 		eventfd_ctx_put(vdev->req_trigger);
 		vdev->req_trigger = NULL;
 	}
+
+	if (vdev->pdev->is_physfn) {
+		for (i = 0; i < pci_sriov_get_totalvfs(vdev->pdev); i++) {
+			if (vdev->vf_reset_trigger && vdev->vf_reset_trigger[i]) {
+				eventfd_ctx_put(vdev->vf_reset_trigger[i]);
+				vdev->vf_reset_trigger[i] = NULL;
+			}
+		}
+		if (vdev->vf_reset_trigger)
+			kfree(vdev->vf_reset_trigger);
+	}
 	mutex_unlock(&vdev->igate);
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_close_device);
@@ -718,6 +730,13 @@ void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev)
 	eeh_dev_open(vdev->pdev);
 #endif
 
+	if (vdev->pdev->is_physfn) {
+		vdev->vf_reset_trigger = kzalloc(pci_sriov_get_totalvfs(vdev->pdev) *
+			sizeof(*vdev->vf_reset_trigger), GFP_KERNEL);
+		if (!vdev->vf_reset_trigger)
+			pci_info(vdev->pdev, "%s: couldn't enable vf reset interrupt\n", __func__);
+	}
+
 	if (vdev->sriov_pf_core_dev) {
 		mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock);
 		vdev->sriov_pf_core_dev->vf_token->users++;
@@ -764,6 +783,9 @@ static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_typ
 			return 1;
 	} else if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) {
 		return 1;
+	} else if (irq_type == VFIO_PCI_VF_RESET_IRQ_INDEX) {
+		if (vdev->pdev->is_physfn)
+			return pci_sriov_get_totalvfs(vdev->pdev);
 	}
 
 	return 0;
@@ -1141,6 +1163,10 @@ static int vfio_pci_ioctl_get_irq_info(struct vfio_pci_core_device *vdev,
 		if (pci_is_pcie(vdev->pdev))
 			break;
 		fallthrough;
+	case VFIO_PCI_VF_RESET_IRQ_INDEX:
+		if (vdev->pdev->is_physfn)
+			break;
+		fallthrough;
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index cbb4bcbfbf83..afca7eb1aa3a 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -776,6 +776,28 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_core_device *vdev,
 					       count, flags, data);
 }
 
+static int vfio_pci_vf_reset_trigger(struct vfio_pci_core_device *vdev,
+				    unsigned index, unsigned start,
+				    unsigned count, uint32_t flags, void *data)
+{
+	int i;
+	int ret;
+	int *fd = data;
+
+	if (!vdev->vf_reset_trigger || index != VFIO_PCI_VF_RESET_IRQ_INDEX ||
+		start != 0 || count > pci_sriov_get_totalvfs(vdev->pdev))
+		return -EINVAL;
+
+	for (i = start; i < count; i++) {
+		ret = vfio_pci_set_ctx_trigger_single(&vdev->vf_reset_trigger[i],
+					       1, flags, &fd[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags,
 			    unsigned index, unsigned start, unsigned count,
 			    void *data)
@@ -825,6 +847,14 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags,
 			break;
 		}
 		break;
+	case VFIO_PCI_VF_RESET_IRQ_INDEX:
+		switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+		case VFIO_IRQ_SET_ACTION_TRIGGER:
+			if (vdev->pdev->is_physfn)
+				func = vfio_pci_vf_reset_trigger;
+			break;
+		}
+		break;
 	}
 
 	if (!func)
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 562e8754869d..f188c99dd82f 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -85,6 +85,7 @@ struct vfio_pci_core_device {
 	int			ioeventfds_nr;
 	struct eventfd_ctx	*err_trigger;
 	struct eventfd_ctx	*req_trigger;
+	struct eventfd_ctx	**vf_reset_trigger;
 	struct eventfd_ctx	*pm_wake_eventfd_ctx;
 	struct list_head	dummy_resources_list;
 	struct mutex		ioeventfds_lock;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 20c804bdc09c..e2504182b34d 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -643,6 +643,7 @@ enum {
 	VFIO_PCI_MSIX_IRQ_INDEX,
 	VFIO_PCI_ERR_IRQ_INDEX,
 	VFIO_PCI_REQ_IRQ_INDEX,
+	VFIO_PCI_VF_RESET_IRQ_INDEX,
 	VFIO_PCI_NUM_IRQS
 };
 
-- 
2.36.1


  reply	other threads:[~2024-02-05  7:16 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-05  7:15 [PATCH 1/2] PCI: " Emily Deng
2024-02-05  7:15 ` Emily Deng [this message]
2024-02-05  9:04 ` Leon Romanovsky
     [not found]   ` <BL1PR12MB526972B4E7CF6B2C993A2E6984462@BL1PR12MB5269.namprd12.prod.outlook.com>
2024-02-06 20:06     ` Alex Williamson
2024-02-05 16:43 ` Alex Williamson
     [not found]   ` <BL1PR12MB52695A24DBFFDB9809444D2284462@BL1PR12MB5269.namprd12.prod.outlook.com>
2024-02-06 19:38     ` Alex Williamson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240205071538.2665628-2-Emily.Deng@amd.com \
    --to=emily.deng@amd.com \
    --cc=Andy.Zhang@amd.com \
    --cc=HaiJun.Chang@amd.com \
    --cc=Horace.Chen@amd.com \
    --cc=Jerry.Jiang@amd.com \
    --cc=Monk.Liu@amd.com \
    --cc=ZhenGuo.Yin@amd.com \
    --cc=alex.williamson@redhat.com \
    --cc=bhelgaas@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®