All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
	linux-pci@vger.kernel.org,
	Mark D Rustad <mark.d.rustad@intel.com>,
	Alexander Duyck <alexanderduyck@fb.com>,
	Jesse Brandeburg <jesse.brandeburg@intel.com>,
	Alex Williamson <alex.williamson@redhat.com>
Subject: Re: [PATCH 2/6] PCI/VPD: Remove struct pci_vpd_ops
Date: Wed, 11 Aug 2021 17:00:47 -0500	[thread overview]
Message-ID: <20210811220047.GA2407168@bjorn-Precision-5520> (raw)
In-Reply-To: <b2532a41-df8b-860f-461f-d5c066c819d0@gmail.com>

[+cc Mark, Alex D, Jesse, Alex W]

On Sun, Aug 08, 2021 at 07:20:05PM +0200, Heiner Kallweit wrote:
> Code can be significantly simplified by removing struct pci_vpd_ops and
> avoiding the indirect calls.

I really like this patch.

Nothing to do with *this* patch, but I have a little heartburn about
the "access somebody else's VPD" approach.

I think the beginning of this was Mark's post [1].  IIUC, there are
Intel multifunction NICs that share some VPD hardware between
functions, and concurrent accesses to VPD of different functions
doesn't work correctly.

I'm pretty sure this is a defect per spec, because PCIe r5.0, sec
7.9.19 doesn't say anything about having to treat VPD on
multi-function devices specially.

The current solution is for all Intel multi-function NICs to redirect
VPD access to function 0.  That single-threads VPD access across all
the functions because we hold function 0's vpd->lock mutex while
reading or writing.

But I think we still have the problem that this implicit sharing of
function 0's VPD opens a channel between functions: if functions are
assigned to different VMs, the VMs can communicate by reading and
writing VPD.

So I wonder if we should just disallow VPD access for these NICs
except on function 0.  There was a little bit of discussion in that
direction at [2].

[1] https://lore.kernel.org/linux-pci/20150519000037.56109.68356.stgit@mdrustad-wks.jf.intel.com/
[2] https://lore.kernel.org/linux-pci/20150519160158.00002cd6@unknown/

> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
>  drivers/pci/vpd.c | 90 ++++++++++++++++++-----------------------------
>  1 file changed, 34 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
> index e87f299ee..6a0d617b2 100644
> --- a/drivers/pci/vpd.c
> +++ b/drivers/pci/vpd.c
> @@ -13,13 +13,7 @@
>  
>  /* VPD access through PCI 2.2+ VPD capability */
>  
> -struct pci_vpd_ops {
> -	ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
> -	ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
> -};
> -
>  struct pci_vpd {
> -	const struct pci_vpd_ops *ops;
>  	struct mutex	lock;
>  	unsigned int	len;
>  	u8		cap;
> @@ -123,11 +117,16 @@ static int pci_vpd_wait(struct pci_dev *dev, bool set)
>  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
>  			    void *arg)
>  {
> -	struct pci_vpd *vpd = dev->vpd;
> +	struct pci_vpd *vpd;
>  	int ret = 0;
>  	loff_t end = pos + count;
>  	u8 *buf = arg;
>  
> +	if (!dev || !dev->vpd)
> +		return -ENODEV;
> +
> +	vpd = dev->vpd;
> +
>  	if (pos < 0)
>  		return -EINVAL;
>  
> @@ -189,11 +188,16 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
>  static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
>  			     const void *arg)
>  {
> -	struct pci_vpd *vpd = dev->vpd;
> +	struct pci_vpd *vpd;
>  	const u8 *buf = arg;
>  	loff_t end = pos + count;
>  	int ret = 0;
>  
> +	if (!dev || !dev->vpd)
> +		return -ENODEV;
> +
> +	vpd = dev->vpd;
> +
>  	if (pos < 0 || (pos & 3) || (count & 3))
>  		return -EINVAL;
>  
> @@ -238,44 +242,6 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
>  	return ret ? ret : count;
>  }
>  
> -static const struct pci_vpd_ops pci_vpd_ops = {
> -	.read = pci_vpd_read,
> -	.write = pci_vpd_write,
> -};
> -
> -static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
> -			       void *arg)
> -{
> -	struct pci_dev *tdev = pci_get_func0_dev(dev);
> -	ssize_t ret;
> -
> -	if (!tdev)
> -		return -ENODEV;
> -
> -	ret = pci_read_vpd(tdev, pos, count, arg);
> -	pci_dev_put(tdev);
> -	return ret;
> -}
> -
> -static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
> -				const void *arg)
> -{
> -	struct pci_dev *tdev = pci_get_func0_dev(dev);
> -	ssize_t ret;
> -
> -	if (!tdev)
> -		return -ENODEV;
> -
> -	ret = pci_write_vpd(tdev, pos, count, arg);
> -	pci_dev_put(tdev);
> -	return ret;
> -}
> -
> -static const struct pci_vpd_ops pci_vpd_f0_ops = {
> -	.read = pci_vpd_f0_read,
> -	.write = pci_vpd_f0_write,
> -};
> -
>  void pci_vpd_init(struct pci_dev *dev)
>  {
>  	struct pci_vpd *vpd;
> @@ -290,10 +256,6 @@ void pci_vpd_init(struct pci_dev *dev)
>  		return;
>  
>  	vpd->len = PCI_VPD_MAX_SIZE;
> -	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0)
> -		vpd->ops = &pci_vpd_f0_ops;
> -	else
> -		vpd->ops = &pci_vpd_ops;
>  	mutex_init(&vpd->lock);
>  	vpd->cap = cap;
>  	vpd->valid = 0;
> @@ -388,9 +350,17 @@ EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);
>   */
>  ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf)
>  {
> -	if (!dev->vpd || !dev->vpd->ops)
> -		return -ENODEV;
> -	return dev->vpd->ops->read(dev, pos, count, buf);
> +	ssize_t ret;
> +
> +	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) {
> +		dev = pci_get_func0_dev(dev);
> +		ret = pci_vpd_read(dev, pos, count, buf);
> +		pci_dev_put(dev);
> +	} else {
> +		ret = pci_vpd_read(dev, pos, count, buf);
> +	}
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL(pci_read_vpd);
>  
> @@ -403,9 +373,17 @@ EXPORT_SYMBOL(pci_read_vpd);
>   */
>  ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf)
>  {
> -	if (!dev->vpd || !dev->vpd->ops)
> -		return -ENODEV;
> -	return dev->vpd->ops->write(dev, pos, count, buf);
> +	ssize_t ret;
> +
> +	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) {
> +		dev = pci_get_func0_dev(dev);
> +		ret = pci_vpd_write(dev, pos, count, buf);
> +		pci_dev_put(dev);
> +	} else {
> +		ret = pci_vpd_write(dev, pos, count, buf);
> +	}
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL(pci_write_vpd);
>  
> -- 
> 2.32.0
> 
> 

  reply	other threads:[~2021-08-11 22:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-08 17:18 [PATCH 0/6] PCI/VPD: Further improvements Heiner Kallweit
2021-08-08 17:19 ` [PATCH 1/6] PCI/VPD: Move pci_read/write_vpd in the code Heiner Kallweit
2021-08-08 17:20 ` [PATCH 2/6] PCI/VPD: Remove struct pci_vpd_ops Heiner Kallweit
2021-08-11 22:00   ` Bjorn Helgaas [this message]
2021-08-11 23:43     ` Rustad, Mark D
2021-08-11 23:58       ` Alex Williamson
2021-08-08 17:21 ` [PATCH 3/6] PCI/VPD: Remove member valid from struct pci_vpd Heiner Kallweit
2021-08-08 17:21 ` [PATCH 4/6] PCI/VPD: Embed struct pci_vpd member in struct pci_dev Heiner Kallweit
2021-08-08 17:22 ` [PATCH 5/6] PCI/VPD: Determine VPD size in pci_vpd_init already Heiner Kallweit
2021-08-08 17:23 ` [PATCH 6/6] PCI/VPD: Treat invalid VPD like no VPD capability Heiner Kallweit
2021-08-12 17:53 ` [PATCH 0/6] PCI/VPD: Further improvements Bjorn Helgaas

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=20210811220047.GA2407168@bjorn-Precision-5520 \
    --to=helgaas@kernel.org \
    --cc=alex.williamson@redhat.com \
    --cc=alexanderduyck@fb.com \
    --cc=bhelgaas@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=jesse.brandeburg@intel.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=mark.d.rustad@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.