Skip to content

Commit 52132f3

Browse files
floatiouskwilczynski
authored andcommitted
PCI: endpoint: Allow EPF drivers to configure the size of Resizable BARs
A resizable BAR is different from a normal BAR in a few ways: - The minimum size of a resizable BAR is 1 MB. - Each BAR that is resizable has a Capability and Control register in the Resizable BAR Capability structure. These registers contain the supported sizes and the currently selected size of a resizable BAR. The supported sizes is a bitmap of the supported sizes. The selected size is a single value that is equal to one of the supported sizes. A resizable BAR thus has to be configured differently than a BAR_PROGRAMMABLE BAR, which usually sets the BAR size/mask in a vendor specific way. The PCI endpoint framework currently does not support resizable BARs. Add a BAR type BAR_RESIZABLE, so that an EPC driver can support resizable BARs properly. Note that the pci_epc_set_bar() API takes a struct pci_epf_bar which tells the EPC driver how it wants to configure the BAR. struct pci_epf_bar only has a single size struct member. This means that an EPC driver will only be able to set a single supported size. This is perfectly fine, as we do not need the complexity of allowing a host to change the size of the BAR. If someone ever wants to support resizing a resizable BAR, the pci_epc_set_bar() API can be extended in the future. With these changes, we allow an EPF driver to configure the size of Resizable BARs, rather than forcing them to a 1 MB size. Signed-off-by: Niklas Cassel <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Manivannan Sadhasivam <[email protected]> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <[email protected]>
1 parent 3c936e0 commit 52132f3

File tree

3 files changed

+12
-0
lines changed

3 files changed

+12
-0
lines changed

drivers/pci/endpoint/pci-epc-core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
609609
if (!epc_features)
610610
return -EINVAL;
611611

612+
if (epc_features->bar[bar].type == BAR_RESIZABLE &&
613+
(epf_bar->size < SZ_1M || (u64)epf_bar->size > (SZ_128G * 1024)))
614+
return -EINVAL;
615+
612616
if (epc_features->bar[bar].type == BAR_FIXED &&
613617
(epc_features->bar[bar].fixed_size != epf_bar->size))
614618
return -EINVAL;

drivers/pci/endpoint/pci-epf-core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
274274
if (size < 128)
275275
size = 128;
276276

277+
/* According to PCIe base spec, min size for a resizable BAR is 1 MB. */
278+
if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M)
279+
size = SZ_1M;
280+
277281
if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
278282
if (size > bar_fixed_size) {
279283
dev_err(&epf->dev,

include/linux/pci-epc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,15 @@ struct pci_epc {
188188
* enum pci_epc_bar_type - configurability of endpoint BAR
189189
* @BAR_PROGRAMMABLE: The BAR mask can be configured by the EPC.
190190
* @BAR_FIXED: The BAR mask is fixed by the hardware.
191+
* @BAR_RESIZABLE: The BAR implements the PCI-SIG Resizable BAR Capability.
192+
* NOTE: An EPC driver can currently only set a single supported
193+
* size.
191194
* @BAR_RESERVED: The BAR should not be touched by an EPF driver.
192195
*/
193196
enum pci_epc_bar_type {
194197
BAR_PROGRAMMABLE = 0,
195198
BAR_FIXED,
199+
BAR_RESIZABLE,
196200
BAR_RESERVED,
197201
};
198202

0 commit comments

Comments
 (0)