ACK: [SRU][F][G][PATCH v3 1/1] s390/pci: Fix zpci_alloc_domain() over allocation

Stefan Bader stefan.bader at canonical.com
Wed May 13 12:14:51 UTC 2020


On 06.05.20 09:21, frank.heimes at canonical.com wrote:
> From: Niklas Schnelle <schnelle at linux.ibm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1874057
> 
> Until now zpci_alloc_domain() only prevented more than
> CONFIG_PCI_NR_FUNCTIONS from being added when using automatic domain
> allocation. When explicit UIDs were defined UIDs above
> CONFIG_PCI_NR_FUNCTIONS were not counted at all.
> When more PCI functions are added this could lead to various errors
> including under sized IRQ vectors and similar issues.
> 
> Fix this by explicitly tracking the number of allocated domains.
> 
> Signed-off-by: Niklas Schnelle <schnelle at linux.ibm.com>
> Reviewed-by: Pierre Morel <pmorel at linux.ibm.com>
> Signed-off-by: Vasily Gorbik <gor at linux.ibm.com>
> (backported from commit 969ae01bab2fe938b4c8324836038b5ac1c78fac)
> Signed-off-by: Frank Heimes <frank.heimes at canonical.com>
Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
>  arch/s390/include/asm/pci.h |  1 +
>  arch/s390/pci/pci.c         | 34 ++++++++++++++++++++--------------
>  2 files changed, 21 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
> index 6087a4e9b2bf..7850e8c8c79a 100644
> --- a/arch/s390/include/asm/pci.h
> +++ b/arch/s390/include/asm/pci.h
> @@ -28,6 +28,7 @@ int pci_proc_domain(struct pci_bus *);
>  
>  #define ZPCI_NR_DMA_SPACES		1
>  #define ZPCI_NR_DEVICES			CONFIG_PCI_NR_FUNCTIONS
> +#define ZPCI_DOMAIN_BITMAP_SIZE		(1 << 16)
>  
>  /* PCI Function Controls */
>  #define ZPCI_FC_FN_ENABLED		0x80
> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> index 6105b1b6e49b..0af46683dd66 100644
> --- a/arch/s390/pci/pci.c
> +++ b/arch/s390/pci/pci.c
> @@ -39,8 +39,9 @@
>  static LIST_HEAD(zpci_list);
>  static DEFINE_SPINLOCK(zpci_list_lock);
>  
> -static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
> +static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE);
>  static DEFINE_SPINLOCK(zpci_domain_lock);
> +static unsigned int zpci_num_domains_allocated;
>  
>  #define ZPCI_IOMAP_ENTRIES						\
>  	min(((unsigned long) ZPCI_NR_DEVICES * PCI_BAR_COUNT / 2),	\
> @@ -651,39 +652,44 @@ struct dev_pm_ops pcibios_pm_ops = {
>  
>  static int zpci_alloc_domain(struct zpci_dev *zdev)
>  {
> +	spin_lock(&zpci_domain_lock);
> +	if (zpci_num_domains_allocated > (ZPCI_NR_DEVICES - 1)) {
> +		spin_unlock(&zpci_domain_lock);
> +		pr_err("Adding PCI function %08x failed because the configured limit of %d is reached\n",
> +			zdev->fid, ZPCI_NR_DEVICES);
> +		return -ENOSPC;
> +	}
> +
>  	if (zpci_unique_uid) {
>  		zdev->domain = (u16) zdev->uid;
> -		if (zdev->domain >= ZPCI_NR_DEVICES)
> -			return 0;
> -
> -		spin_lock(&zpci_domain_lock);
>  		if (test_bit(zdev->domain, zpci_domain)) {
>  			spin_unlock(&zpci_domain_lock);
> +			pr_err("Adding PCI function %08x failed because domain %04x is already assigned\n",
> +				zdev->fid, zdev->domain);
>  			return -EEXIST;
>  		}
>  		set_bit(zdev->domain, zpci_domain);
> +		zpci_num_domains_allocated++;
>  		spin_unlock(&zpci_domain_lock);
>  		return 0;
>  	}
> -
> -	spin_lock(&zpci_domain_lock);
> +	/*
> +	 * We can always auto allocate domains below ZPCI_NR_DEVICES.
> +	 * There is either a free domain or we have reached the maximum in
> +	 * which case we would have bailed earlier.
> +	 */
>  	zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
> -	if (zdev->domain == ZPCI_NR_DEVICES) {
> -		spin_unlock(&zpci_domain_lock);
> -		return -ENOSPC;
> -	}
>  	set_bit(zdev->domain, zpci_domain);
> +	zpci_num_domains_allocated++;
>  	spin_unlock(&zpci_domain_lock);
>  	return 0;
>  }
>  
>  static void zpci_free_domain(struct zpci_dev *zdev)
>  {
> -	if (zdev->domain >= ZPCI_NR_DEVICES)
> -		return;
> -
>  	spin_lock(&zpci_domain_lock);
>  	clear_bit(zdev->domain, zpci_domain);
> +	zpci_num_domains_allocated--;
>  	spin_unlock(&zpci_domain_lock);
>  }
>  
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20200513/f761734b/attachment.sig>


More information about the kernel-team mailing list