@@ -164,41 +164,67 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
164164
165165#define PCI_COMMAND_DECODE_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
166166
167+ /**
168+ * __pci_size_bars - Read the raw BAR mask for a range of PCI BARs
169+ * @dev: the PCI device
170+ * @count: number of BARs to size
171+ * @pos: starting config space position
172+ * @sizes: array to store mask values
173+ * @rom: indicate whether to use ROM mask, which avoids enabling ROM BARs
174+ *
175+ * Provided @sizes array must be sufficiently sized to store results for
176+ * @count u32 BARs. Caller is responsible for disabling decode to specified
177+ * BAR range around calling this function. This function is intended to avoid
178+ * disabling decode around sizing each BAR individually, which can result in
179+ * non-trivial overhead in virtualized environments with very large PCI BARs.
180+ */
181+ static void __pci_size_bars (struct pci_dev * dev , int count ,
182+ unsigned int pos , u32 * sizes , bool rom )
183+ {
184+ u32 orig , mask = rom ? PCI_ROM_ADDRESS_MASK : ~0 ;
185+ int i ;
186+
187+ for (i = 0 ; i < count ; i ++ , pos += 4 , sizes ++ ) {
188+ pci_read_config_dword (dev , pos , & orig );
189+ pci_write_config_dword (dev , pos , mask );
190+ pci_read_config_dword (dev , pos , sizes );
191+ pci_write_config_dword (dev , pos , orig );
192+ }
193+ }
194+
195+ void __pci_size_stdbars (struct pci_dev * dev , int count ,
196+ unsigned int pos , u32 * sizes )
197+ {
198+ __pci_size_bars (dev , count , pos , sizes , false);
199+ }
200+
201+ static void __pci_size_rom (struct pci_dev * dev , unsigned int pos , u32 * sizes )
202+ {
203+ __pci_size_bars (dev , 1 , pos , sizes , true);
204+ }
205+
167206/**
168207 * __pci_read_base - Read a PCI BAR
169208 * @dev: the PCI device
170209 * @type: type of the BAR
171210 * @res: resource buffer to be filled in
172211 * @pos: BAR position in the config space
212+ * @sizes: array of one or more pre-read BAR masks
173213 *
174214 * Returns 1 if the BAR is 64-bit, or 0 if 32-bit.
175215 */
176216int __pci_read_base (struct pci_dev * dev , enum pci_bar_type type ,
177- struct resource * res , unsigned int pos )
217+ struct resource * res , unsigned int pos , u32 * sizes )
178218{
179- u32 l = 0 , sz = 0 , mask ;
219+ u32 l = 0 , sz ;
180220 u64 l64 , sz64 , mask64 ;
181- u16 orig_cmd ;
182221 struct pci_bus_region region , inverted_region ;
183222 const char * res_name = pci_resource_name (dev , res - dev -> resource );
184223
185- mask = type ? PCI_ROM_ADDRESS_MASK : ~0 ;
186-
187- /* No printks while decoding is disabled! */
188- if (!dev -> mmio_always_on ) {
189- pci_read_config_word (dev , PCI_COMMAND , & orig_cmd );
190- if (orig_cmd & PCI_COMMAND_DECODE_ENABLE ) {
191- pci_write_config_word (dev , PCI_COMMAND ,
192- orig_cmd & ~PCI_COMMAND_DECODE_ENABLE );
193- }
194- }
195-
196224 res -> name = pci_name (dev );
197225
198226 pci_read_config_dword (dev , pos , & l );
199- pci_write_config_dword (dev , pos , l | mask );
200- pci_read_config_dword (dev , pos , & sz );
201- pci_write_config_dword (dev , pos , l );
227+ sz = sizes [0 ];
202228
203229 /*
204230 * All bits set in sz means the device isn't working properly.
@@ -238,18 +264,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
238264
239265 if (res -> flags & IORESOURCE_MEM_64 ) {
240266 pci_read_config_dword (dev , pos + 4 , & l );
241- pci_write_config_dword (dev , pos + 4 , ~0 );
242- pci_read_config_dword (dev , pos + 4 , & sz );
243- pci_write_config_dword (dev , pos + 4 , l );
267+ sz = sizes [1 ];
244268
245269 l64 |= ((u64 )l << 32 );
246270 sz64 |= ((u64 )sz << 32 );
247271 mask64 |= ((u64 )~0 << 32 );
248272 }
249273
250- if (!dev -> mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE ))
251- pci_write_config_word (dev , PCI_COMMAND , orig_cmd );
252-
253274 if (!sz64 )
254275 goto fail ;
255276
@@ -320,7 +341,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
320341
321342static void pci_read_bases (struct pci_dev * dev , unsigned int howmany , int rom )
322343{
344+ u32 rombar , stdbars [PCI_STD_NUM_BARS ];
323345 unsigned int pos , reg ;
346+ u16 orig_cmd ;
347+
348+ BUILD_BUG_ON (howmany > PCI_STD_NUM_BARS );
324349
325350 if (dev -> non_compliant_bars )
326351 return ;
@@ -329,18 +354,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
329354 if (dev -> is_virtfn )
330355 return ;
331356
357+ /* No printks while decoding is disabled! */
358+ if (!dev -> mmio_always_on ) {
359+ pci_read_config_word (dev , PCI_COMMAND , & orig_cmd );
360+ if (orig_cmd & PCI_COMMAND_DECODE_ENABLE ) {
361+ pci_write_config_word (dev , PCI_COMMAND ,
362+ orig_cmd & ~PCI_COMMAND_DECODE_ENABLE );
363+ }
364+ }
365+
366+ __pci_size_stdbars (dev , howmany , PCI_BASE_ADDRESS_0 , stdbars );
367+ if (rom )
368+ __pci_size_rom (dev , rom , & rombar );
369+
370+ if (!dev -> mmio_always_on &&
371+ (orig_cmd & PCI_COMMAND_DECODE_ENABLE ))
372+ pci_write_config_word (dev , PCI_COMMAND , orig_cmd );
373+
332374 for (pos = 0 ; pos < howmany ; pos ++ ) {
333375 struct resource * res = & dev -> resource [pos ];
334376 reg = PCI_BASE_ADDRESS_0 + (pos << 2 );
335- pos += __pci_read_base (dev , pci_bar_unknown , res , reg );
377+ pos += __pci_read_base (dev , pci_bar_unknown ,
378+ res , reg , & stdbars [pos ]);
336379 }
337380
338381 if (rom ) {
339382 struct resource * res = & dev -> resource [PCI_ROM_RESOURCE ];
340383 dev -> rom_base_reg = rom ;
341384 res -> flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
342385 IORESOURCE_READONLY | IORESOURCE_SIZEALIGN ;
343- __pci_read_base (dev , pci_bar_mem32 , res , rom );
386+ __pci_read_base (dev , pci_bar_mem32 , res , rom , & rombar );
344387 }
345388}
346389
0 commit comments