public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
@ 2023-04-06 11:05 David Laight
  2023-04-06 15:07 ` Bjorn Helgaas
  2023-04-06 19:35 ` Linus Torvalds
  0 siblings, 2 replies; 12+ messages in thread
From: David Laight @ 2023-04-06 11:05 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas
  Cc: Linus Torvalds, Christoph Hellwig

The change in bab65e48cb064 breaks pci_enable_msix_range().
The intent is to optimise the sanity checks, but it is
somewhat overenthusiastic.

The interface allows you to ask for a lot of vectors and
returns the number that were allocated.
However, after the change, you can't request a vector
that is higher than the largest the hardware supports.
Which makes that rather pointless.

So code like:
	for (i = 0; i < 16; i++)
		msix_tbl[i].entry = i;
	nvec = pci_enable_msix_range(dev, msix_tbl, 1, 16);
Now returns -22 if the hardware only supports 8 interrupts.

Previously it returned 8.

I can fix my driver, but I suspect that any code that relies
on a smaller number of vectors being returned is now broken.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 11:05 revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks David Laight
@ 2023-04-06 15:07 ` Bjorn Helgaas
  2023-04-06 15:36   ` David Laight
  2023-04-06 19:46   ` Thomas Gleixner
  2023-04-06 19:35 ` Linus Torvalds
  1 sibling, 2 replies; 12+ messages in thread
From: Bjorn Helgaas @ 2023-04-06 15:07 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas, Linus Torvalds, Christoph Hellwig, linux-pci,
	regressions

[+cc linux-pci, regressions]

On Thu, Apr 06, 2023 at 11:05:14AM +0000, David Laight wrote:
> The change in bab65e48cb064 breaks pci_enable_msix_range().
> The intent is to optimise the sanity checks, but it is
> somewhat overenthusiastic.
> 
> The interface allows you to ask for a lot of vectors and
> returns the number that were allocated.
> However, after the change, you can't request a vector
> that is higher than the largest the hardware supports.
> Which makes that rather pointless.
> 
> So code like:
> 	for (i = 0; i < 16; i++)
> 		msix_tbl[i].entry = i;
> 	nvec = pci_enable_msix_range(dev, msix_tbl, 1, 16);
> Now returns -22 if the hardware only supports 8 interrupts.
> 
> Previously it returned 8.
> 
> I can fix my driver, but I suspect that any code that relies
> on a smaller number of vectors being returned is now broken.

Thanks for the report!  bab65e48cb06 ("PCI/MSI: Sanitize MSI-X
checks") appeared in v6.2-rc1, so this is a recent regression and it
would be good to fix it for v6.3.

bab65e48cb06 only touches drivers/pci/msi/msi.c, but since it didn't
go through the PCI tree, I'll let Thomas handle any revert (or better,
an improvement to pci_msix_validate_entries()) since he wrote and
applied the original.

Bjorn

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 15:07 ` Bjorn Helgaas
@ 2023-04-06 15:36   ` David Laight
  2023-04-06 19:46   ` Thomas Gleixner
  1 sibling, 0 replies; 12+ messages in thread
From: David Laight @ 2023-04-06 15:36 UTC (permalink / raw)
  To: 'Bjorn Helgaas'
  Cc: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas, Linus Torvalds, Christoph Hellwig,
	linux-pci@vger.kernel.org, regressions@lists.linux.dev

From: Bjorn Helgaas
> Sent: 06 April 2023 16:08
> 
> [+cc linux-pci, regressions]
> 
> On Thu, Apr 06, 2023 at 11:05:14AM +0000, David Laight wrote:
> > The change in bab65e48cb064 breaks pci_enable_msix_range().
> > The intent is to optimise the sanity checks, but it is
> > somewhat overenthusiastic.
> >
> > The interface allows you to ask for a lot of vectors and
> > returns the number that were allocated.
> > However, after the change, you can't request a vector
> > that is higher than the largest the hardware supports.
> > Which makes that rather pointless.
> >
> > So code like:
> > 	for (i = 0; i < 16; i++)
> > 		msix_tbl[i].entry = i;
> > 	nvec = pci_enable_msix_range(dev, msix_tbl, 1, 16);
> > Now returns -22 if the hardware only supports 8 interrupts.
> >
> > Previously it returned 8.
> >
> > I can fix my driver, but I suspect that any code that relies
> > on a smaller number of vectors being returned is now broken.
> 
> Thanks for the report!  bab65e48cb06 ("PCI/MSI: Sanitize MSI-X
> checks") appeared in v6.2-rc1, so this is a recent regression and it
> would be good to fix it for v6.3.

I do try to test every release at around rc3.

> bab65e48cb06 only touches drivers/pci/msi/msi.c, but since it didn't
> go through the PCI tree, I'll let Thomas handle any revert (or better,
> an improvement to pci_msix_validate_entries()) since he wrote and
> applied the original.

Looking it:

static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
				      int nvec, int hwsize)
{
	bool nogap;
	int i, j;

	if (!entries)
		return true;

	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);

	for (i = 0; i < nvec; i++) {
		/* Entry within hardware limit? */
		if (entries[i].entry >= hwsize)
			return false;

		/* Check for duplicate entries */
		for (j = i + 1; j < nvec; j++) {
			if (entries[i].entry == entries[j].entry)
				return false;
		}
		/* Check for unsupported gaps */
		if (nogap && entries[i].entry != i)
			return false;
	}
	return true;
}

It probably needs to return an updated 'nvec'.
The gap/duplicate check is also a bit horrid, why not:
		if (nogap) {
			if (entries[i].entry != i)
				return false;
			continue;
		}

		if (!i || entries[i].entry > entries[i - 1].entry)
			continue;

		horrid, expensive loop...

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 11:05 revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks David Laight
  2023-04-06 15:07 ` Bjorn Helgaas
@ 2023-04-06 19:35 ` Linus Torvalds
  2023-04-06 21:06   ` Thomas Gleixner
  2023-04-07 12:25   ` David Laight
  1 sibling, 2 replies; 12+ messages in thread
From: Linus Torvalds @ 2023-04-06 19:35 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas, Christoph Hellwig

[-- Attachment #1: Type: text/plain, Size: 865 bytes --]

On Thu, Apr 6, 2023 at 4:05 AM David Laight <David.Laight@aculab.com> wrote:
>
> So code like:
>         for (i = 0; i < 16; i++)
>                 msix_tbl[i].entry = i;
>         nvec = pci_enable_msix_range(dev, msix_tbl, 1, 16);
> Now returns -22 if the hardware only supports 8 interrupts.
>
> Previously it returned 8.

Does just moving the pci_msix_validate_entries() down to below the
hwsize update code fix it?

IOW, something like this attached patch?

ENTIRELY UNTESTED! This may be seriously broken for some reason, but
it does seem like the current code makes no sense (that "Keep the IRQ
virtual hackery working" comment seems to not possibly be true since
the MSIX nvec has effectively been checked against hwsize by the
pci_msix_validate_entries() code before).

I don't know this code. Thomas?

                     Linus

[-- Attachment #2: patch.diff --]
[-- Type: text/x-patch, Size: 847 bytes --]

 drivers/pci/msi/msi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 1f716624ca56..8edc7beebf6f 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -805,9 +805,6 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
-		return -EINVAL;
-
 	if (hwsize < nvec) {
 		/* Keep the IRQ virtual hackery working */
 		if (flags & PCI_IRQ_VIRTUAL)
@@ -819,6 +816,9 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
 	if (nvec < minvec)
 		return -ENOSPC;
 
+	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+		return -EINVAL;
+
 	rc = pci_setup_msi_context(dev);
 	if (rc)
 		return rc;

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 15:07 ` Bjorn Helgaas
  2023-04-06 15:36   ` David Laight
@ 2023-04-06 19:46   ` Thomas Gleixner
  1 sibling, 0 replies; 12+ messages in thread
From: Thomas Gleixner @ 2023-04-06 19:46 UTC (permalink / raw)
  To: Bjorn Helgaas, David Laight
  Cc: linux-kernel@vger.kernel.org, Jason Gunthorpe, Bjorn Helgaas,
	Linus Torvalds, Christoph Hellwig, linux-pci, regressions

On Thu, Apr 06 2023 at 10:07, Bjorn Helgaas wrote:
> On Thu, Apr 06, 2023 at 11:05:14AM +0000, David Laight wrote:
> Thanks for the report!  bab65e48cb06 ("PCI/MSI: Sanitize MSI-X
> checks") appeared in v6.2-rc1, so this is a recent regression and it
> would be good to fix it for v6.3.
>
> bab65e48cb06 only touches drivers/pci/msi/msi.c, but since it didn't
> go through the PCI tree, I'll let Thomas handle any revert (or better,
> an improvement to pci_msix_validate_entries()) since he wrote and
> applied the original.

Right. The fix is trivial as the hardware size check in this validation
function is pointless.

The point is that for a range allocation with and entries array, _all_
entries up to max_vec must be correct independent of the actual hardware
size.

So the fix is simply removing the hardware size check from the
validation function.

The hardware size checking happens afterwards anyway.

Thanks,

        tglx
---
 drivers/pci/msi/msi.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,8 +750,7 @@ static int msix_capability_init(struct p
 	return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvev)
 {
 	bool nogap;
 	int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(st
 	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
 	for (i = 0; i < nvec; i++) {
-		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
-
 		/* Check for duplicate entries */
 		for (j = i + 1; j < nvec; j++) {
 			if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_d
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+	if (!pci_msix_validate_entries(dev, entries, nvec))
 		return -EINVAL;
 
 	if (hwsize < nvec) {

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 19:35 ` Linus Torvalds
@ 2023-04-06 21:06   ` Thomas Gleixner
  2023-04-07 12:25   ` David Laight
  1 sibling, 0 replies; 12+ messages in thread
From: Thomas Gleixner @ 2023-04-06 21:06 UTC (permalink / raw)
  To: Linus Torvalds, David Laight
  Cc: linux-kernel@vger.kernel.org, Jason Gunthorpe, Bjorn Helgaas,
	Christoph Hellwig

On Thu, Apr 06 2023 at 12:35, Linus Torvalds wrote:
>> Previously it returned 8.
>
> Does just moving the pci_msix_validate_entries() down to below the
> hwsize update code fix it?
>
> IOW, something like this attached patch?
>
> ENTIRELY UNTESTED! This may be seriously broken for some reason, but
> it does seem like the current code makes no sense (that "Keep the IRQ
> virtual hackery working" comment seems to not possibly be true since
> the MSIX nvec has effectively been checked against hwsize by the
> pci_msix_validate_entries() code before).

Yes, that works too. But I rather remove the hwsize check from the
validation function as I explained in my earlier reply to Bjorn in that
thread.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-06 19:35 ` Linus Torvalds
  2023-04-06 21:06   ` Thomas Gleixner
@ 2023-04-07 12:25   ` David Laight
  2023-04-07 19:26     ` Linus Torvalds
  1 sibling, 1 reply; 12+ messages in thread
From: David Laight @ 2023-04-07 12:25 UTC (permalink / raw)
  To: 'Linus Torvalds'
  Cc: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas, Christoph Hellwig

From: Linus Torvalds
> Sent: 06 April 2023 20:36
> 
> On Thu, Apr 6, 2023 at 4:05 AM David Laight <David.Laight@aculab.com> wrote:
> >
> > So code like:
> >         for (i = 0; i < 16; i++)
> >                 msix_tbl[i].entry = i;
> >         nvec = pci_enable_msix_range(dev, msix_tbl, 1, 16);
> > Now returns -22 if the hardware only supports 8 interrupts.
> >
> > Previously it returned 8.
> 
> Does just moving the pci_msix_validate_entries() down to below the
> hwsize update code fix it?

I think it depends on why the driver is asking for more
interrupts than the hardware supports.
Potentially the driver could do:
	for (i = 0; i < 8; i++)
		msix_tbl[i].entry = 2 * i;
if the hardware supports 8 interrupts perhaps it
should return 4?

In my case both the MSI-X logic on the fpga and the driver
support 16 interrupts, but PCIe config space reports 8.
The high numbered interrupts aren't used very often and get
multiplexed onto the highest 'real' interrupt.
(The fpga build makes it pretty much impossible to tie
together the config space value and the size of the MSI-X
table.)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-07 12:25   ` David Laight
@ 2023-04-07 19:26     ` Linus Torvalds
  2023-04-07 21:31       ` Thomas Gleixner
  0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2023-04-07 19:26 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel@vger.kernel.org, Thomas Gleixner, Jason Gunthorpe,
	Bjorn Helgaas, Christoph Hellwig

[-- Attachment #1: Type: text/plain, Size: 982 bytes --]

On Fri, Apr 7, 2023 at 5:25 AM David Laight <David.Laight@aculab.com> wrote:
>
> I think it depends on why the driver is asking for more
> interrupts than the hardware supports.
> Potentially the driver could do:
>         for (i = 0; i < 8; i++)
>                 msix_tbl[i].entry = 2 * i;
> if the hardware supports 8 interrupts perhaps it
> should return 4?

Hmm.

Something like this might get that case right too. Again - entirely
untested, but looks superficially sane to me.

It just returns how many of the msix_entry[] entries can be used (or
negative for error). So then the (only) caller can just say "is that
still enough for what we required". Seems reasonable, and would get
that non-contiguous case right, I think.

Thomas?

I'm going to drop this and assume I'll get a pull from you with what
you consider the proper fix, but since I was looking at this anyway, I
decided I might as well send out this RFC patch.

                Linus

[-- Attachment #2: patch.diff --]
[-- Type: text/x-patch, Size: 1911 bytes --]

 drivers/pci/msi/msi.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 1f716624ca56..d151bde8b8e0 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,32 +750,33 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
 	return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static int pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
+				     int nvec, int hwsize)
 {
 	bool nogap;
-	int i, j;
+	int maxvec;
 
 	if (!entries)
-		return true;
+		return nvec;
 
 	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
-	for (i = 0; i < nvec; i++) {
+	maxvec = -EINVAL;
+	for (int i = 0; i < nvec; i++) {
 		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
+		if (entries[i].entry < hwsize)
+			maxvec = i+1;
 
 		/* Check for duplicate entries */
-		for (j = i + 1; j < nvec; j++) {
+		for (int j = i + 1; j < nvec; j++) {
 			if (entries[i].entry == entries[j].entry)
-				return false;
+				return -EINVAL;
 		}
 		/* Check for unsupported gaps */
 		if (nogap && entries[i].entry != i)
-			return false;
+			return -EINVAL;
 	}
-	return true;
+	return maxvec;
 }
 
 int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec,
@@ -805,8 +806,11 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
-		return -EINVAL;
+	nvec = pci_msix_validate_entries(dev, entries, nvec, hwsize);
+	if (nvec < 0)
+		return nvec;
+	if (nvec < minvec)
+		return -ENOSPC;
 
 	if (hwsize < nvec) {
 		/* Keep the IRQ virtual hackery working */

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks
  2023-04-07 19:26     ` Linus Torvalds
@ 2023-04-07 21:31       ` Thomas Gleixner
  2023-04-10 19:14         ` [PATCH] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries() Thomas Gleixner
  0 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2023-04-07 21:31 UTC (permalink / raw)
  To: Linus Torvalds, David Laight
  Cc: linux-kernel@vger.kernel.org, Jason Gunthorpe, Bjorn Helgaas,
	Christoph Hellwig

Linus!

On Fri, Apr 07 2023 at 12:26, Linus Torvalds wrote:
> On Fri, Apr 7, 2023 at 5:25 AM David Laight <David.Laight@aculab.com> wrote:
>>
>> I think it depends on why the driver is asking for more
>> interrupts than the hardware supports.
>> Potentially the driver could do:
>>         for (i = 0; i < 8; i++)
>>                 msix_tbl[i].entry = 2 * i;
>> if the hardware supports 8 interrupts perhaps it
>> should return 4?
>
> Hmm.
>
> Something like this might get that case right too. Again - entirely
> untested, but looks superficially sane to me.
>
> It just returns how many of the msix_entry[] entries can be used (or
> negative for error). So then the (only) caller can just say "is that
> still enough for what we required". Seems reasonable, and would get
> that non-contiguous case right, I think.

Probably, but the point is that a driver should not hand in invalid data
in the first place. Even if the hardware does not provide enough space
for the requested maximum range then the handed in entries array should
not contain any invalid data, right?

Ergo the hwsize check in that function is bogus. No idea what I was
thinking there.

So the simple and IMO correct solution is to drop that hwsize check from
the validation function and validate up to the

The point is that for a range allocation with and entries array, _all_
entries up to max_vec must be correct independent of the actual hardware
size.

So the fix is simply removing the hardware size check from the
validation function. The hardware size checking happens afterwards
anyway.

Let me write up a proper changelog for that.

Thanks,

	tglx
---
 drivers/pci/msi/msi.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,8 +750,7 @@ static int msix_capability_init(struct p
	return ret;
 }

-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvev)
 {
	bool nogap;
	int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(st
	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);

	for (i = 0; i < nvec; i++) {
-		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
-
		/* Check for duplicate entries */
		for (j = i + 1; j < nvec; j++) {
			if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_d
	if (hwsize < 0)
		return hwsize;

-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+	if (!pci_msix_validate_entries(dev, entries, nvec))
		return -EINVAL;

	if (hwsize < nvec) {

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries()
  2023-04-07 21:31       ` Thomas Gleixner
@ 2023-04-10 19:14         ` Thomas Gleixner
  2023-04-15 21:21           ` [tip: irq/urgent] " tip-bot2 for Thomas Gleixner
  2023-04-16 12:18           ` tip-bot2 for Thomas Gleixner
  0 siblings, 2 replies; 12+ messages in thread
From: Thomas Gleixner @ 2023-04-10 19:14 UTC (permalink / raw)
  To: Linus Torvalds, David Laight
  Cc: linux-kernel@vger.kernel.org, Jason Gunthorpe, Bjorn Helgaas,
	Christoph Hellwig

pci_msix_validate_entries() validates the entries array which is handed in
by the caller for a MSI-X interrupt allocation. Aside of consistency
failures it also detects a failure when the size of the MSI-X hardware table
in the device is smaller than the size of the entries array.

That's wrong for the case of range allocations where the caller provides
the minimum and the maximum number of vectors to allocate, when the
hardware size is greater or equal to the mininum, but smaller than the
maximum.

Remove the hardware size check completely from that function and just
ensure that the entires array up to the maximum size is consistent.

The limitation and range checking versus the hardware size happens
independently of that afterwards anyway because the entries array is
optional.

Fixes: 4644d22eb673 ("PCI/MSI: Validate MSI-X contiguous restriction early")
Reported-by: David Laight <David.Laight@aculab.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---

David, can you please confirm that this fixes your issue?

---
 drivers/pci/msi/msi.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,8 +750,7 @@ static int msix_capability_init(struct p
 	return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvev)
 {
 	bool nogap;
 	int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(st
 	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
 	for (i = 0; i < nvec; i++) {
-		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
-
 		/* Check for duplicate entries */
 		for (j = i + 1; j < nvec; j++) {
 			if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_d
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+	if (!pci_msix_validate_entries(dev, entries, nvec))
 		return -EINVAL;
 
 	if (hwsize < nvec) {

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip: irq/urgent] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries()
  2023-04-10 19:14         ` [PATCH] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries() Thomas Gleixner
@ 2023-04-15 21:21           ` tip-bot2 for Thomas Gleixner
  2023-04-16 12:18           ` tip-bot2 for Thomas Gleixner
  1 sibling, 0 replies; 12+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2023-04-15 21:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: David Laight, Thomas Gleixner, stable, x86, linux-kernel, maz

The following commit has been merged into the irq/urgent branch of tip:

Commit-ID:     84d9651e13fb9820041d19262a55906851524c0f
Gitweb:        https://git.kernel.org/tip/84d9651e13fb9820041d19262a55906851524c0f
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Mon, 10 Apr 2023 21:14:45 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Sat, 15 Apr 2023 23:17:32 +02:00

PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries()

pci_msix_validate_entries() validates the entries array which is handed in
by the caller for a MSI-X interrupt allocation. Aside of consistency
failures it also detects a failure when the size of the MSI-X hardware table
in the device is smaller than the size of the entries array.

That's wrong for the case of range allocations where the caller provides
the minimum and the maximum number of vectors to allocate, when the
hardware size is greater or equal than the mininum, but smaller than the
maximum.

Remove the hardware size check completely from that function and just
ensure that the entires array up to the maximum size is consistent.

The limitation and range checking versus the hardware size happens
independently of that afterwards anyway because the entries array is
optional.

Fixes: 4644d22eb673 ("PCI/MSI: Validate MSI-X contiguous restriction early")
Reported-by: David Laight <David.Laight@aculab.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/87v8i3sg62.ffs@tglx
---
 drivers/pci/msi/msi.c |  9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 1f71662..24899d9 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,8 +750,7 @@ out_disable:
 	return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvev)
 {
 	bool nogap;
 	int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *en
 	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
 	for (i = 0; i < nvec; i++) {
-		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
-
 		/* Check for duplicate entries */
 		for (j = i + 1; j < nvec; j++) {
 			if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+	if (!pci_msix_validate_entries(dev, entries, nvec))
 		return -EINVAL;
 
 	if (hwsize < nvec) {

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip: irq/urgent] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries()
  2023-04-10 19:14         ` [PATCH] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries() Thomas Gleixner
  2023-04-15 21:21           ` [tip: irq/urgent] " tip-bot2 for Thomas Gleixner
@ 2023-04-16 12:18           ` tip-bot2 for Thomas Gleixner
  1 sibling, 0 replies; 12+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2023-04-16 12:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: David Laight, Thomas Gleixner, stable, x86, linux-kernel, maz

The following commit has been merged into the irq/urgent branch of tip:

Commit-ID:     e3c026be4d3ca046799fde55ccbae9d0f059fb93
Gitweb:        https://git.kernel.org/tip/e3c026be4d3ca046799fde55ccbae9d0f059fb93
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Mon, 10 Apr 2023 21:14:45 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Sun, 16 Apr 2023 14:11:51 +02:00

PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries()

pci_msix_validate_entries() validates the entries array which is handed in
by the caller for a MSI-X interrupt allocation. Aside of consistency
failures it also detects a failure when the size of the MSI-X hardware table
in the device is smaller than the size of the entries array.

That's wrong for the case of range allocations where the caller provides
the minimum and the maximum number of vectors to allocate, when the
hardware size is greater or equal than the mininum, but smaller than the
maximum.

Remove the hardware size check completely from that function and just
ensure that the entires array up to the maximum size is consistent.

The limitation and range checking versus the hardware size happens
independently of that afterwards anyway because the entries array is
optional.

Fixes: 4644d22eb673 ("PCI/MSI: Validate MSI-X contiguous restriction early")
Reported-by: David Laight <David.Laight@aculab.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/87v8i3sg62.ffs@tglx

---
 drivers/pci/msi/msi.c |  9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 1f71662..ef1d885 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -750,8 +750,7 @@ out_disable:
 	return ret;
 }
 
-static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries,
-				      int nvec, int hwsize)
+static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 {
 	bool nogap;
 	int i, j;
@@ -762,10 +761,6 @@ static bool pci_msix_validate_entries(struct pci_dev *dev, struct msix_entry *en
 	nogap = pci_msi_domain_supports(dev, MSI_FLAG_MSIX_CONTIGUOUS, DENY_LEGACY);
 
 	for (i = 0; i < nvec; i++) {
-		/* Entry within hardware limit? */
-		if (entries[i].entry >= hwsize)
-			return false;
-
 		/* Check for duplicate entries */
 		for (j = i + 1; j < nvec; j++) {
 			if (entries[i].entry == entries[j].entry)
@@ -805,7 +800,7 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int
 	if (hwsize < 0)
 		return hwsize;
 
-	if (!pci_msix_validate_entries(dev, entries, nvec, hwsize))
+	if (!pci_msix_validate_entries(dev, entries, nvec))
 		return -EINVAL;
 
 	if (hwsize < nvec) {

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-04-16 12:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-06 11:05 revert bab65e48cb064 PCI/MSI Sanitize MSI-X checks David Laight
2023-04-06 15:07 ` Bjorn Helgaas
2023-04-06 15:36   ` David Laight
2023-04-06 19:46   ` Thomas Gleixner
2023-04-06 19:35 ` Linus Torvalds
2023-04-06 21:06   ` Thomas Gleixner
2023-04-07 12:25   ` David Laight
2023-04-07 19:26     ` Linus Torvalds
2023-04-07 21:31       ` Thomas Gleixner
2023-04-10 19:14         ` [PATCH] PCI/MSI: Remove over-zealous hardware size check in pci_msix_validate_entries() Thomas Gleixner
2023-04-15 21:21           ` [tip: irq/urgent] " tip-bot2 for Thomas Gleixner
2023-04-16 12:18           ` tip-bot2 for Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox