PCI: Add pci_rebar_size_supported() helper

Many callers of pci_rebar_get_possible_sizes() are interested in finding
out if a particular encoded BAR Size (PCIe r7.0, sec 7.8.6.3) is supported
by the particular BAR.

Add pci_rebar_size_supported() into PCI core to make it easy for the
drivers to determine if the BAR size is supported or not.

Use the new function in pci_resize_resource() and in
pci_iov_vf_bar_set_size().

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20251113180053.27944-6-ilpo.jarvinen@linux.intel.com
This commit is contained in:
Ilpo Järvinen 2025-11-13 20:00:47 +02:00 committed by Bjorn Helgaas
parent ce04b2f9b0
commit bb1fabd0d9
3 changed files with 21 additions and 13 deletions

View File

@ -1339,19 +1339,13 @@ EXPORT_SYMBOL_GPL(pci_sriov_configure_simple);
*/ */
int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size) int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size)
{ {
u32 sizes;
if (!pci_resource_is_iov(resno)) if (!pci_resource_is_iov(resno))
return -EINVAL; return -EINVAL;
if (pci_iov_is_memory_decoding_enabled(dev)) if (pci_iov_is_memory_decoding_enabled(dev))
return -EBUSY; return -EBUSY;
sizes = pci_rebar_get_possible_sizes(dev, resno); if (!pci_rebar_size_supported(dev, resno, size))
if (!sizes)
return -ENOTSUPP;
if (!(sizes & BIT(size)))
return -EINVAL; return -EINVAL;
return pci_rebar_set_size(dev, resno, size); return pci_rebar_set_size(dev, resno, size);

View File

@ -3,6 +3,7 @@
* PCI Resizable BAR Extended Capability handling. * PCI Resizable BAR Extended Capability handling.
*/ */
#include <linux/bits.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/export.h> #include <linux/export.h>
@ -124,6 +125,23 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
} }
EXPORT_SYMBOL(pci_rebar_get_possible_sizes); EXPORT_SYMBOL(pci_rebar_get_possible_sizes);
/**
* pci_rebar_size_supported - check if size is supported for BAR
* @pdev: PCI device
* @bar: BAR to check
* @size: encoded size as defined in the PCIe spec (0=1MB, 31=128TB)
*
* Return: %true if @bar is resizable and @size is supported, otherwise
* %false.
*/
bool pci_rebar_size_supported(struct pci_dev *pdev, int bar, int size)
{
u64 sizes = pci_rebar_get_possible_sizes(pdev, bar);
return BIT(size) & sizes;
}
EXPORT_SYMBOL_GPL(pci_rebar_size_supported);
/** /**
* pci_rebar_get_current_size - get the current size of a Resizable BAR * pci_rebar_get_current_size - get the current size of a Resizable BAR
* @pdev: PCI device * @pdev: PCI device
@ -252,7 +270,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
{ {
struct pci_host_bridge *host; struct pci_host_bridge *host;
int old, ret; int old, ret;
u32 sizes;
/* Check if we must preserve the firmware's resource assignment */ /* Check if we must preserve the firmware's resource assignment */
host = pci_find_host_bridge(dev->bus); host = pci_find_host_bridge(dev->bus);
@ -262,11 +279,7 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
if (pci_resize_is_memory_decoding_enabled(dev, resno)) if (pci_resize_is_memory_decoding_enabled(dev, resno))
return -EBUSY; return -EBUSY;
sizes = pci_rebar_get_possible_sizes(dev, resno); if (!pci_rebar_size_supported(dev, resno, size))
if (!sizes)
return -ENOTSUPP;
if (!(sizes & BIT(size)))
return -EINVAL; return -EINVAL;
old = pci_rebar_get_current_size(dev, resno); old = pci_rebar_get_current_size(dev, resno);

View File

@ -1424,6 +1424,7 @@ int pci_release_resource(struct pci_dev *dev, int resno);
int pci_rebar_bytes_to_size(u64 bytes); int pci_rebar_bytes_to_size(u64 bytes);
resource_size_t pci_rebar_size_to_bytes(int size); resource_size_t pci_rebar_size_to_bytes(int size);
u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar); u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar);
bool pci_rebar_size_supported(struct pci_dev *pdev, int bar, int size);
int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size, int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size,
int exclude_bars); int exclude_bars);