@@ -721,47 +721,31 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
721721 return ret ;
722722}
723723
724- static int __pci_enable_msix (struct pci_dev * dev , struct msix_entry * entries ,
725- int nvec , struct irq_affinity * affd , int flags )
724+ static bool pci_msix_validate_entries (struct msix_entry * entries , int nvec , int hwsize )
726725{
727- int nr_entries ;
728726 int i , j ;
729727
730- if (!pci_msi_supported ( dev , nvec ) || dev -> current_state != PCI_D0 )
731- return - EINVAL ;
728+ if (!entries )
729+ return true ;
732730
733- nr_entries = pci_msix_vec_count (dev );
734- if (nr_entries < 0 )
735- return nr_entries ;
736- if (nvec > nr_entries && !(flags & PCI_IRQ_VIRTUAL ))
737- return nr_entries ;
731+ for (i = 0 ; i < nvec ; i ++ ) {
732+ /* Entry within hardware limit? */
733+ if (entries [i ].entry >= hwsize )
734+ return false;
738735
739- if (entries ) {
740- /* Check for any invalid entries */
741- for (i = 0 ; i < nvec ; i ++ ) {
742- if (entries [i ].entry >= nr_entries )
743- return - EINVAL ; /* invalid entry */
744- for (j = i + 1 ; j < nvec ; j ++ ) {
745- if (entries [i ].entry == entries [j ].entry )
746- return - EINVAL ; /* duplicate entry */
747- }
736+ /* Check for duplicate entries */
737+ for (j = i + 1 ; j < nvec ; j ++ ) {
738+ if (entries [i ].entry == entries [j ].entry )
739+ return false;
748740 }
749741 }
750-
751- /* Check whether driver already requested for MSI IRQ */
752- if (dev -> msi_enabled ) {
753- pci_info (dev , "can't enable MSI-X (MSI IRQ already assigned)\n" );
754- return - EINVAL ;
755- }
756- return msix_capability_init (dev , entries , nvec , affd );
742+ return true;
757743}
758744
759- int __pci_enable_msix_range (struct pci_dev * dev ,
760- struct msix_entry * entries , int minvec ,
761- int maxvec , struct irq_affinity * affd ,
762- int flags )
745+ int __pci_enable_msix_range (struct pci_dev * dev , struct msix_entry * entries , int minvec ,
746+ int maxvec , struct irq_affinity * affd , int flags )
763747{
764- int rc , nvec = maxvec ;
748+ int hwsize , rc , nvec = maxvec ;
765749
766750 if (maxvec < minvec )
767751 return - ERANGE ;
@@ -774,6 +758,23 @@ int __pci_enable_msix_range(struct pci_dev *dev,
774758 if (WARN_ON_ONCE (dev -> msix_enabled ))
775759 return - EINVAL ;
776760
761+ if (!pci_msi_supported (dev , nvec ) || dev -> current_state != PCI_D0 )
762+ return - EINVAL ;
763+
764+ hwsize = pci_msix_vec_count (dev );
765+ if (hwsize < 0 )
766+ return hwsize ;
767+
768+ if (!pci_msix_validate_entries (entries , nvec , hwsize ))
769+ return - EINVAL ;
770+
771+ /* PCI_IRQ_VIRTUAL is a horrible hack! */
772+ if (nvec > hwsize && !(flags & PCI_IRQ_VIRTUAL ))
773+ nvec = hwsize ;
774+
775+ if (nvec < minvec )
776+ return - ENOSPC ;
777+
777778 rc = pci_setup_msi_context (dev );
778779 if (rc )
779780 return rc ;
@@ -785,7 +786,7 @@ int __pci_enable_msix_range(struct pci_dev *dev,
785786 return - ENOSPC ;
786787 }
787788
788- rc = __pci_enable_msix (dev , entries , nvec , affd , flags );
789+ rc = msix_capability_init (dev , entries , nvec , affd );
789790 if (rc == 0 )
790791 return nvec ;
791792
0 commit comments