Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1307491

[PATCH 3/3] pci: set VPD size to '0' if PCI_VPD_FLAGS_VPD_REF_F0 is set

From Hannes Reinecke <hare@suse.de>
Newsgroups linux.kernel
Subject [PATCH 3/3] pci: set VPD size to '0' if PCI_VPD_FLAGS_VPD_REF_F0 is set
Date 2016-01-12 15:50 +0100
Message-ID <qQ8qJ-2kQ-1@gated-at.bofh.it> (permalink)
References <qQ8qJ-2kQ-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


If the VPD data is accessed via another PCI function than 0
the access is redirected to function 0. However, we shouldn't
calculate the actual size as we did for function 0, as there
is no guarantee that function 0 is already initialized and
VPD access is very costly and error prone.

So to avoid all this we set the size to '0' in sysfs, but only return
the valid bytes from the underlying function 0.

Cc: Alexander Duyck <alexander.duyck@gmail.com>
Cc: Bjorn Helgaas <helgaas@kernel.org>
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/pci/access.c    | 11 ++++++++++-
 drivers/pci/pci-sysfs.c | 20 ++++++++++++--------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index ce1b0cb..9fe19be 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -337,9 +337,16 @@ static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count,
 	loff_t end = pos + count;
 	u8 *buf = arg;
 
-	if (pos < 0 || pos > vpd->base.len || end > vpd->base.len)
+	if (pos < 0)
 		return -EINVAL;
 
+	if (end > vpd->base.len) {
+		if (pos > vpd->base.len)
+			return 0;
+		end = vpd->base.len;
+		count = end - pos;
+	}
+
 	if (mutex_lock_killable(&vpd->lock))
 		return -EINTR;
 
@@ -554,6 +561,8 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
 	dev->vpd = &vpd->base;
 	if (!(dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0))
 		vpd->base.len = pci_vpd_pci22_size(dev);
+	else
+		vpd->base.len = 0;
 	return 0;
 }
 
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index eead54c..de327c3 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -772,10 +772,12 @@ static ssize_t read_vpd_attr(struct file *filp, struct kobject *kobj,
 	struct pci_dev *dev =
 		to_pci_dev(container_of(kobj, struct device, kobj));
 
-	if (off > bin_attr->size)
-		count = 0;
-	else if (count > bin_attr->size - off)
-		count = bin_attr->size - off;
+	if (bin_attr->size > 0) {
+		if (off > bin_attr->size)
+			count = 0;
+		else if (count > bin_attr->size - off)
+			count = bin_attr->size - off;
+	}
 
 	return pci_read_vpd(dev, off, count, buf);
 }
@@ -787,10 +789,12 @@ static ssize_t write_vpd_attr(struct file *filp, struct kobject *kobj,
 	struct pci_dev *dev =
 		to_pci_dev(container_of(kobj, struct device, kobj));
 
-	if (off > bin_attr->size)
-		count = 0;
-	else if (count > bin_attr->size - off)
-		count = bin_attr->size - off;
+	if (bin_attr->size > 0) {
+		if (off > bin_attr->size)
+			count = 0;
+		else if (count > bin_attr->size - off)
+			count = bin_attr->size - off;
+	}
 
 	return pci_write_vpd(dev, off, count, buf);
 }
-- 
1.8.5.6

Back to linux.kernel | Previous | Next | Find similar | Unroll thread


Thread

[PATCH 3/3] pci: set VPD size to '0' if PCI_VPD_FLAGS_VPD_REF_F0 is set Hannes Reinecke <hare@suse.de> - 2016-01-12 15:50 +0100

csiph-web