77 * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
88 */
99
10+ #include <linux/bitfield.h>
11+ #include <linux/bits.h>
12+ #include <linux/log2.h>
1013#include <linux/pci.h>
14+ #include <linux/sizes.h>
1115#include <linux/slab.h>
1216#include <linux/export.h>
1317#include <linux/string.h>
1418#include <linux/delay.h>
19+ #include <asm/div64.h>
1520#include "pci.h"
1621
1722#define VIRTFN_ID_LEN 17 /* "virtfn%u\0" for 2^32 - 1 */
@@ -150,7 +155,28 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
150155 if (!dev -> is_physfn )
151156 return 0 ;
152157
153- return dev -> sriov -> barsz [resno - PCI_IOV_RESOURCES ];
158+ return dev -> sriov -> barsz [pci_resource_num_to_vf_bar (resno )];
159+ }
160+
161+ void pci_iov_resource_set_size (struct pci_dev * dev , int resno ,
162+ resource_size_t size )
163+ {
164+ if (!pci_resource_is_iov (resno )) {
165+ pci_warn (dev , "%s is not an IOV resource\n" ,
166+ pci_resource_name (dev , resno ));
167+ return ;
168+ }
169+
170+ dev -> sriov -> barsz [pci_resource_num_to_vf_bar (resno )] = size ;
171+ }
172+
173+ bool pci_iov_is_memory_decoding_enabled (struct pci_dev * dev )
174+ {
175+ u16 cmd ;
176+
177+ pci_read_config_word (dev , dev -> sriov -> pos + PCI_SRIOV_CTRL , & cmd );
178+
179+ return cmd & PCI_SRIOV_CTRL_MSE ;
154180}
155181
156182static void pci_read_vf_config_common (struct pci_dev * virtfn )
@@ -341,12 +367,14 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id)
341367 virtfn -> multifunction = 0 ;
342368
343369 for (i = 0 ; i < PCI_SRIOV_NUM_BARS ; i ++ ) {
344- res = & dev -> resource [i + PCI_IOV_RESOURCES ];
370+ int idx = pci_resource_num_from_vf_bar (i );
371+
372+ res = & dev -> resource [idx ];
345373 if (!res -> parent )
346374 continue ;
347375 virtfn -> resource [i ].name = pci_name (virtfn );
348376 virtfn -> resource [i ].flags = res -> flags ;
349- size = pci_iov_resource_size (dev , i + PCI_IOV_RESOURCES );
377+ size = pci_iov_resource_size (dev , idx );
350378 resource_set_range (& virtfn -> resource [i ],
351379 res -> start + size * id , size );
352380 rc = request_resource (res , & virtfn -> resource [i ]);
@@ -643,8 +671,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
643671
644672 nres = 0 ;
645673 for (i = 0 ; i < PCI_SRIOV_NUM_BARS ; i ++ ) {
646- bars |= (1 << (i + PCI_IOV_RESOURCES ));
647- res = & dev -> resource [i + PCI_IOV_RESOURCES ];
674+ int idx = pci_resource_num_from_vf_bar (i );
675+ resource_size_t vf_bar_sz = pci_iov_resource_size (dev , idx );
676+
677+ bars |= (1 << idx );
678+ res = & dev -> resource [idx ];
679+ if (vf_bar_sz * nr_virtfn > resource_size (res ))
680+ continue ;
648681 if (res -> parent )
649682 nres ++ ;
650683 }
@@ -810,8 +843,10 @@ static int sriov_init(struct pci_dev *dev, int pos)
810843
811844 nres = 0 ;
812845 for (i = 0 ; i < PCI_SRIOV_NUM_BARS ; i ++ ) {
813- res = & dev -> resource [i + PCI_IOV_RESOURCES ];
814- res_name = pci_resource_name (dev , i + PCI_IOV_RESOURCES );
846+ int idx = pci_resource_num_from_vf_bar (i );
847+
848+ res = & dev -> resource [idx ];
849+ res_name = pci_resource_name (dev , idx );
815850
816851 /*
817852 * If it is already FIXED, don't change it, something
@@ -850,6 +885,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
850885 pci_read_config_byte (dev , pos + PCI_SRIOV_FUNC_LINK , & iov -> link );
851886 if (pci_pcie_type (dev ) == PCI_EXP_TYPE_RC_END )
852887 iov -> link = PCI_DEVFN (PCI_SLOT (dev -> devfn ), iov -> link );
888+ iov -> vf_rebar_cap = pci_find_ext_capability (dev , PCI_EXT_CAP_ID_VF_REBAR );
853889
854890 if (pdev )
855891 iov -> dev = pci_dev_get (pdev );
@@ -869,7 +905,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
869905 dev -> is_physfn = 0 ;
870906failed :
871907 for (i = 0 ; i < PCI_SRIOV_NUM_BARS ; i ++ ) {
872- res = & dev -> resource [i + PCI_IOV_RESOURCES ];
908+ res = & dev -> resource [pci_resource_num_from_vf_bar ( i ) ];
873909 res -> flags = 0 ;
874910 }
875911
@@ -888,6 +924,30 @@ static void sriov_release(struct pci_dev *dev)
888924 dev -> sriov = NULL ;
889925}
890926
927+ static void sriov_restore_vf_rebar_state (struct pci_dev * dev )
928+ {
929+ unsigned int pos , nbars , i ;
930+ u32 ctrl ;
931+
932+ pos = pci_iov_vf_rebar_cap (dev );
933+ if (!pos )
934+ return ;
935+
936+ pci_read_config_dword (dev , pos + PCI_VF_REBAR_CTRL , & ctrl );
937+ nbars = FIELD_GET (PCI_VF_REBAR_CTRL_NBAR_MASK , ctrl );
938+
939+ for (i = 0 ; i < nbars ; i ++ , pos += 8 ) {
940+ int bar_idx , size ;
941+
942+ pci_read_config_dword (dev , pos + PCI_VF_REBAR_CTRL , & ctrl );
943+ bar_idx = FIELD_GET (PCI_VF_REBAR_CTRL_BAR_IDX , ctrl );
944+ size = pci_rebar_bytes_to_size (dev -> sriov -> barsz [bar_idx ]);
945+ ctrl &= ~PCI_VF_REBAR_CTRL_BAR_SIZE ;
946+ ctrl |= FIELD_PREP (PCI_VF_REBAR_CTRL_BAR_SIZE , size );
947+ pci_write_config_dword (dev , pos + PCI_VF_REBAR_CTRL , ctrl );
948+ }
949+ }
950+
891951static void sriov_restore_state (struct pci_dev * dev )
892952{
893953 int i ;
@@ -907,7 +967,7 @@ static void sriov_restore_state(struct pci_dev *dev)
907967 pci_write_config_word (dev , iov -> pos + PCI_SRIOV_CTRL , ctrl );
908968
909969 for (i = 0 ; i < PCI_SRIOV_NUM_BARS ; i ++ )
910- pci_update_resource (dev , i + PCI_IOV_RESOURCES );
970+ pci_update_resource (dev , pci_resource_num_from_vf_bar ( i ) );
911971
912972 pci_write_config_dword (dev , iov -> pos + PCI_SRIOV_SYS_PGSIZE , iov -> pgsz );
913973 pci_iov_set_numvfs (dev , iov -> num_VFs );
@@ -973,7 +1033,7 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno)
9731033{
9741034 struct pci_sriov * iov = dev -> is_physfn ? dev -> sriov : NULL ;
9751035 struct resource * res = pci_resource_n (dev , resno );
976- int vf_bar = resno - PCI_IOV_RESOURCES ;
1036+ int vf_bar = pci_resource_num_to_vf_bar ( resno ) ;
9771037 struct pci_bus_region region ;
9781038 u16 cmd ;
9791039 u32 new ;
@@ -1047,8 +1107,10 @@ resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
10471107 */
10481108void pci_restore_iov_state (struct pci_dev * dev )
10491109{
1050- if (dev -> is_physfn )
1110+ if (dev -> is_physfn ) {
1111+ sriov_restore_vf_rebar_state (dev );
10511112 sriov_restore_state (dev );
1113+ }
10521114}
10531115
10541116/**
@@ -1255,3 +1317,72 @@ int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn)
12551317 return nr_virtfn ;
12561318}
12571319EXPORT_SYMBOL_GPL (pci_sriov_configure_simple );
1320+
1321+ /**
1322+ * pci_iov_vf_bar_set_size - set a new size for a VF BAR
1323+ * @dev: the PCI device
1324+ * @resno: the resource number
1325+ * @size: new size as defined in the spec (0=1MB, 31=128TB)
1326+ *
1327+ * Set the new size of a VF BAR that supports VF resizable BAR capability.
1328+ * Unlike pci_resize_resource(), this does not cause the resource that
1329+ * reserves the MMIO space (originally up to total_VFs) to be resized, which
1330+ * means that following calls to pci_enable_sriov() can fail if the resources
1331+ * no longer fit.
1332+ *
1333+ * Return: 0 on success, or negative on failure.
1334+ */
1335+ int pci_iov_vf_bar_set_size (struct pci_dev * dev , int resno , int size )
1336+ {
1337+ u32 sizes ;
1338+ int ret ;
1339+
1340+ if (!pci_resource_is_iov (resno ))
1341+ return - EINVAL ;
1342+
1343+ if (pci_iov_is_memory_decoding_enabled (dev ))
1344+ return - EBUSY ;
1345+
1346+ sizes = pci_rebar_get_possible_sizes (dev , resno );
1347+ if (!sizes )
1348+ return - ENOTSUPP ;
1349+
1350+ if (!(sizes & BIT (size )))
1351+ return - EINVAL ;
1352+
1353+ ret = pci_rebar_set_size (dev , resno , size );
1354+ if (ret )
1355+ return ret ;
1356+
1357+ pci_iov_resource_set_size (dev , resno , pci_rebar_size_to_bytes (size ));
1358+
1359+ return 0 ;
1360+ }
1361+ EXPORT_SYMBOL_GPL (pci_iov_vf_bar_set_size );
1362+
1363+ /**
1364+ * pci_iov_vf_bar_get_sizes - get VF BAR sizes allowing to create up to num_vfs
1365+ * @dev: the PCI device
1366+ * @resno: the resource number
1367+ * @num_vfs: number of VFs
1368+ *
1369+ * Get the sizes of a VF resizable BAR that can accommodate @num_vfs within
1370+ * the currently assigned size of the resource @resno.
1371+ *
1372+ * Return: A bitmask of sizes in format defined in the spec (bit 0=1MB,
1373+ * bit 31=128TB).
1374+ */
1375+ u32 pci_iov_vf_bar_get_sizes (struct pci_dev * dev , int resno , int num_vfs )
1376+ {
1377+ u64 vf_len = pci_resource_len (dev , resno );
1378+ u32 sizes ;
1379+
1380+ if (!num_vfs )
1381+ return 0 ;
1382+
1383+ do_div (vf_len , num_vfs );
1384+ sizes = (roundup_pow_of_two (vf_len + 1 ) - 1 ) >> ilog2 (SZ_1M );
1385+
1386+ return sizes & pci_rebar_get_possible_sizes (dev , resno );
1387+ }
1388+ EXPORT_SYMBOL_GPL (pci_iov_vf_bar_get_sizes );
0 commit comments