Re: [PATCH] vfio: fix config virtualization, esp command byte

Previous thread: [RFC/Requirements/Design] h/w error reporting by Luck, Tony on Tuesday, November 9, 2010 - 5:56 pm. (50 messages)

Next thread: [PATCH] drivers/pcmcia/soc_common.c: Use printf extension %pV by Joe Perches on Tuesday, November 9, 2010 - 6:14 pm. (1 message)
From: Tom Lyon
Date: Tuesday, November 9, 2010 - 6:09 pm

Cleans up config space virtualization, especialy handling of bytes
which have some virtual and some real bits, like PCI_COMMAND.

Alex, I hope you can test this with your setups.

Signed-off-by: Tom Lyon <pugs@cisco.com>
---
 drivers/vfio/vfio_pci_config.c |  166 +++++++++++++---------------------------
 1 files changed, 53 insertions(+), 113 deletions(-)

diff --git a/drivers/vfio/vfio_pci_config.c b/drivers/vfio/vfio_pci_config.c
index 8304316..7132ac4 100644
--- a/drivers/vfio/vfio_pci_config.c
+++ b/drivers/vfio/vfio_pci_config.c
@@ -745,6 +745,8 @@ static int vfio_virt_init(struct vfio_dev *vdev)
  */
 static void vfio_bar_restore(struct vfio_dev *vdev)
 {
+	if (vdev->pdev->is_virtfn)
+		return;
 	printk(KERN_WARNING "%s: reset recovery - restoring bars\n", __func__);
 
 #define do_bar(off, which) \
@@ -815,26 +817,15 @@ static inline int vfio_read_config_byte(struct vfio_dev *vdev,
 static inline int vfio_write_config_byte(struct vfio_dev *vdev,
 					int pos, u8 val)
 {
-	vdev->vconfig[pos] = val;
 	return pci_user_write_config_byte(vdev->pdev, pos, val);
 }
 
 /* handle virtualized fields in the basic config space */
-static u8 vfio_virt_basic(struct vfio_dev *vdev, int write,
-				u16 pos, u16 off, u8 val, u8 newval)
+static void vfio_virt_basic(struct vfio_dev *vdev, int write, u16 pos, u8 *rbp)
 {
-	switch (off) {
-	/*
-	 * vendor and device are virt because they don't
-	 * show up otherwise for sr-iov vfs
-	 */
-	case PCI_VENDOR_ID:
-	case PCI_VENDOR_ID + 1:
-	case PCI_DEVICE_ID:
-	case PCI_DEVICE_ID + 1:
-		/* read only */
-		val = vdev->vconfig[pos];
-		break;
+	u8 val;
+
+	switch (pos) {
 	case PCI_COMMAND:
 		/*
 		 * If the real mem or IO enable bits are zero
@@ -842,100 +833,58 @@ static u8 vfio_virt_basic(struct vfio_dev *vdev, int write,
 		 * Restore the real BARs before allowing those
 		 * bits to re-enable
 		 */
+		val = vdev->vconfig[pos];
 		if (vdev->pdev->is_virtfn)
 			val |= PCI_COMMAND_MEMORY;
 		if (write) {
-			int ...
From: Alex Williamson
Date: Tuesday, November 16, 2010 - 10:54 am

Sorry for the delay.  FWIW, I'm not having much luck with this, I'll try
to debug the problem.  Thanks,




--

From: Alex Williamson
Date: Tuesday, November 16, 2010 - 11:57 am

This seems to be the bug.  Thanks,

Alex

vfio: Don't write random bits on read

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

diff --git a/drivers/vfio/vfio_pci_config.c b/drivers/vfio/vfio_pci_config.c
index 7132ac4..422d7b1 100644
--- a/drivers/vfio/vfio_pci_config.c
+++ b/drivers/vfio/vfio_pci_config.c
@@ -964,11 +964,6 @@ static int vfio_config_rwbyte(int write,
 		return 0;
 	}
 
-	if (write) {
-		if (copy_from_user(&newval, buf, 1))
-			return -EFAULT;
-	}
-
 	if (~virt) {	/* mix of real and virt bits */
 		/* update vconfig with latest hw bits */
 		ret = vfio_read_config_byte(vdev, pos, &realbits);
@@ -978,9 +973,14 @@ static int vfio_config_rwbyte(int write,
 			(vdev->vconfig[pos] & virt) | (realbits & ~virt);
 	}
 
-	/* update vconfig with writeable bits */
-	vdev->vconfig[pos] =
-		(vdev->vconfig[pos] & ~wr) | (newval & wr);
+	if (write) {
+		if (copy_from_user(&newval, buf, 1))
+			return -EFAULT;
+
+		/* update vconfig with writeable bits */
+		vdev->vconfig[pos] =
+			(vdev->vconfig[pos] & ~wr) | (newval & wr);
+        }
 
 	/*
 	 * Now massage virtual fields


--

From: Tom Lyon
Date: Tuesday, November 16, 2010 - 10:14 pm

Applied.

--

Previous thread: [RFC/Requirements/Design] h/w error reporting by Luck, Tony on Tuesday, November 9, 2010 - 5:56 pm. (50 messages)

Next thread: [PATCH] drivers/pcmcia/soc_common.c: Use printf extension %pV by Joe Perches on Tuesday, November 9, 2010 - 6:14 pm. (1 message)