linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Abhishek Sahu <abhsahu@nvidia.com>
To: Alex Williamson <alex.williamson@redhat.com>,
	Cornelia Huck <cohuck@redhat.com>,
	Yishai Hadas <yishaih@nvidia.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
	Kevin Tian <kevin.tian@intel.com>,
	"Rafael J . Wysocki" <rafael@kernel.org>
Cc: Max Gurtovoy <mgurtovoy@nvidia.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	<linux-kernel@vger.kernel.org>, <kvm@vger.kernel.org>,
	<linux-pm@vger.kernel.org>, <linux-pci@vger.kernel.org>,
	Abhishek Sahu <abhsahu@nvidia.com>
Subject: [PATCH v3 1/8] vfio/pci: Invalidate mmaps and block the access in D3hot power state
Date: Mon, 25 Apr 2022 14:56:08 +0530	[thread overview]
Message-ID: <20220425092615.10133-2-abhsahu@nvidia.com> (raw)
In-Reply-To: <20220425092615.10133-1-abhsahu@nvidia.com>

According to [PCIe v5 5.3.1.4.1] for D3hot state

 "Configuration and Message requests are the only TLPs accepted by a
  Function in the D3Hot state. All other received Requests must be
  handled as Unsupported Requests, and all received Completions may
  optionally be handled as Unexpected Completions."

Currently, if the vfio PCI device has been put into D3hot state and if
user makes non-config related read/write request in D3hot state, these
requests will be forwarded to the host and this access may cause
issues on a few systems.

This patch leverages the memory-disable support added in commit
'abafbc551fdd ("vfio-pci: Invalidate mmaps and block MMIO access on
disabled memory")' to generate page fault on mmap access and
return error for the direct read/write. If the device is D3hot state,
then the error will be returned for MMIO access. The IO access generally
does not make the system unresponsive so the IO access can still happen
in D3hot state. The default value should be returned in this case
without bringing down the complete system.

Also, the power related structure fields need to be protected so
we can use the same 'memory_lock' to protect these fields also.
This protection is mainly needed when user changes the PCI
power state by writing into PCI_PM_CTRL register.
vfio_lock_and_set_power_state() wrapper function will take the
required locks and then it will invoke the vfio_pci_set_power_state().

Signed-off-by: Abhishek Sahu <abhsahu@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_config.c | 19 ++++++++++++++++++-
 drivers/vfio/pci/vfio_pci_core.c   |  4 +++-
 drivers/vfio/pci/vfio_pci_rdwr.c   |  6 ++++--
 include/linux/vfio_pci_core.h      |  1 +
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 6e58b4bf7a60..dd557edae6e1 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -692,6 +692,23 @@ static int __init init_pci_cap_basic_perm(struct perm_bits *perm)
 	return 0;
 }
 
+/*
+ * It takes all the required locks to protect the access of power related
+ * variables and then invokes vfio_pci_set_power_state().
+ */
+static void
+vfio_lock_and_set_power_state(struct vfio_pci_core_device *vdev,
+			      pci_power_t state)
+{
+	if (state >= PCI_D3hot)
+		vfio_pci_zap_and_down_write_memory_lock(vdev);
+	else
+		down_write(&vdev->memory_lock);
+
+	vfio_pci_set_power_state(vdev, state);
+	up_write(&vdev->memory_lock);
+}
+
 static int vfio_pm_config_write(struct vfio_pci_core_device *vdev, int pos,
 				int count, struct perm_bits *perm,
 				int offset, __le32 val)
@@ -718,7 +735,7 @@ static int vfio_pm_config_write(struct vfio_pci_core_device *vdev, int pos,
 			break;
 		}
 
-		vfio_pci_set_power_state(vdev, state);
+		vfio_lock_and_set_power_state(vdev, state);
 	}
 
 	return count;
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 06b6f3594a13..f3dfb033e1c4 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -230,6 +230,8 @@ int vfio_pci_set_power_state(struct vfio_pci_core_device *vdev, pci_power_t stat
 	ret = pci_set_power_state(pdev, state);
 
 	if (!ret) {
+		vdev->power_state_d3 = (pdev->current_state >= PCI_D3hot);
+
 		/* D3 might be unsupported via quirk, skip unless in D3 */
 		if (needs_save && pdev->current_state >= PCI_D3hot) {
 			/*
@@ -1398,7 +1400,7 @@ static vm_fault_t vfio_pci_mmap_fault(struct vm_fault *vmf)
 	mutex_lock(&vdev->vma_lock);
 	down_read(&vdev->memory_lock);
 
-	if (!__vfio_pci_memory_enabled(vdev)) {
+	if (!__vfio_pci_memory_enabled(vdev) || vdev->power_state_d3) {
 		ret = VM_FAULT_SIGBUS;
 		goto up_out;
 	}
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index 82ac1569deb0..fac6bb40a4ce 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -43,7 +43,8 @@ static int vfio_pci_iowrite##size(struct vfio_pci_core_device *vdev,		\
 {									\
 	if (test_mem) {							\
 		down_read(&vdev->memory_lock);				\
-		if (!__vfio_pci_memory_enabled(vdev)) {			\
+		if (!__vfio_pci_memory_enabled(vdev) ||			\
+		    vdev->power_state_d3) {				\
 			up_read(&vdev->memory_lock);			\
 			return -EIO;					\
 		}							\
@@ -70,7 +71,8 @@ static int vfio_pci_ioread##size(struct vfio_pci_core_device *vdev,		\
 {									\
 	if (test_mem) {							\
 		down_read(&vdev->memory_lock);				\
-		if (!__vfio_pci_memory_enabled(vdev)) {			\
+		if (!__vfio_pci_memory_enabled(vdev) ||			\
+		    vdev->power_state_d3) {				\
 			up_read(&vdev->memory_lock);			\
 			return -EIO;					\
 		}							\
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 48f2dd3c568c..505b2a74a479 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -124,6 +124,7 @@ struct vfio_pci_core_device {
 	bool			needs_reset;
 	bool			nointx;
 	bool			needs_pm_restore;
+	bool			power_state_d3;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
 	int			ioeventfds_nr;
-- 
2.17.1


  reply	other threads:[~2022-04-25  9:26 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-25  9:26 [PATCH v3 0/8] vfio/pci: power management changes Abhishek Sahu
2022-04-25  9:26 ` Abhishek Sahu [this message]
2022-04-26  1:42   ` [PATCH v3 1/8] vfio/pci: Invalidate mmaps and block the access in D3hot power state kernel test robot
2022-04-26 14:14     ` Bjorn Helgaas
2022-04-25  9:26 ` [PATCH v3 2/8] vfio/pci: Change the PF power state to D0 before enabling VFs Abhishek Sahu
2022-04-25  9:26 ` [PATCH v3 3/8] vfio/pci: Virtualize PME related registers bits and initialize to zero Abhishek Sahu
2022-04-25  9:26 ` [PATCH v3 4/8] vfio/pci: Add support for setting driver data inside core layer Abhishek Sahu
2022-05-03 17:11   ` Alex Williamson
2022-05-04  0:20     ` Jason Gunthorpe
2022-05-04 10:32       ` Abhishek Sahu
2022-04-25  9:26 ` [PATCH v3 5/8] vfio/pci: Enable runtime PM for vfio_pci_core based drivers Abhishek Sahu
2022-05-04 19:42   ` Alex Williamson
2022-05-05  9:07     ` Abhishek Sahu
2022-04-25  9:26 ` [PATCH v3 6/8] vfio: Invoke runtime PM API for IOCTL request Abhishek Sahu
2022-05-04 19:42   ` Alex Williamson
2022-05-05  9:40     ` Abhishek Sahu
2022-05-09 22:30       ` Alex Williamson
2022-04-25  9:26 ` [PATCH v3 7/8] vfio/pci: Mask INTx during runtime suspend Abhishek Sahu
2022-04-25  9:26 ` [PATCH v3 8/8] vfio/pci: Add the support for PCI D3cold state Abhishek Sahu
2022-05-04 19:45   ` Alex Williamson
2022-05-05 12:16     ` Abhishek Sahu
2022-05-09 21:48       ` Alex Williamson
2022-05-10 13:26         ` Abhishek Sahu
2022-05-10 13:30           ` Jason Gunthorpe
2022-05-12 12:27             ` Abhishek Sahu
2022-05-12 12:47               ` Jason Gunthorpe
2022-05-30 11:15           ` Abhishek Sahu
2022-05-30 12:25             ` Jason Gunthorpe
2022-05-31 12:14               ` Abhishek Sahu
2022-05-31 19:43                 ` Jason Gunthorpe
2022-05-31 22:52                   ` Alex Williamson
2022-06-01  9:49                     ` Abhishek Sahu
2022-06-01 16:21                       ` Alex Williamson
2022-06-01 17:30                         ` Jason Gunthorpe
2022-06-01 18:15                           ` Alex Williamson
2022-06-01 23:17                             ` Jason Gunthorpe
2022-06-02 11:52                         ` Abhishek Sahu
2022-06-02 17:44                           ` Alex Williamson
2022-06-03 10:19                             ` Abhishek Sahu
2022-06-07 21:50                               ` Alex Williamson
2022-06-08 10:12                                 ` Abhishek Sahu

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=20220425092615.10133-2-abhsahu@nvidia.com \
    --to=abhsahu@nvidia.com \
    --cc=alex.williamson@redhat.com \
    --cc=bhelgaas@google.com \
    --cc=cohuck@redhat.com \
    --cc=jgg@nvidia.com \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mgurtovoy@nvidia.com \
    --cc=rafael@kernel.org \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=yishaih@nvidia.com \
    /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;
as well as URLs for NNTP newsgroup(s).