@@ -67,6 +67,9 @@ const VIRTIO_F_NOTIFICATION_DATA: u32 = 38;
6767/// Vector value used to disable MSI for a queue.
6868const VIRTQ_MSI_NO_VECTOR : u16 = 0xffff ;
6969
70+ /// BAR index we are using for VirtIO configuration
71+ const VIRTIO_BAR_INDEX : u8 = 0 ;
72+
7073enum PciCapabilityType {
7174 Common = 1 ,
7275 Notify = 2 ,
@@ -110,12 +113,12 @@ impl PciCapability for VirtioPciCap {
110113const VIRTIO_PCI_CAP_LEN_OFFSET : u8 = 2 ;
111114
112115impl VirtioPciCap {
113- pub fn new ( cfg_type : PciCapabilityType , pci_bar : u8 , offset : u32 , length : u32 ) -> Self {
116+ pub fn new ( cfg_type : PciCapabilityType , offset : u32 , length : u32 ) -> Self {
114117 VirtioPciCap {
115118 cap_len : u8:: try_from ( std:: mem:: size_of :: < VirtioPciCap > ( ) ) . unwrap ( )
116119 + VIRTIO_PCI_CAP_LEN_OFFSET ,
117120 cfg_type : cfg_type as u8 ,
118- pci_bar,
121+ pci_bar : VIRTIO_BAR_INDEX ,
119122 id : 0 ,
120123 padding : [ 0 ; 2 ] ,
121124 offset : Le32 :: from ( offset) ,
@@ -145,19 +148,13 @@ impl PciCapability for VirtioPciNotifyCap {
145148}
146149
147150impl VirtioPciNotifyCap {
148- pub fn new (
149- cfg_type : PciCapabilityType ,
150- pci_bar : u8 ,
151- offset : u32 ,
152- length : u32 ,
153- multiplier : Le32 ,
154- ) -> Self {
151+ pub fn new ( cfg_type : PciCapabilityType , offset : u32 , length : u32 , multiplier : Le32 ) -> Self {
155152 VirtioPciNotifyCap {
156153 cap : VirtioPciCap {
157154 cap_len : u8:: try_from ( std:: mem:: size_of :: < VirtioPciNotifyCap > ( ) ) . unwrap ( )
158155 + VIRTIO_PCI_CAP_LEN_OFFSET ,
159156 cfg_type : cfg_type as u8 ,
160- pci_bar,
157+ pci_bar : VIRTIO_BAR_INDEX ,
161158 id : 0 ,
162159 padding : [ 0 ; 2 ] ,
163160 offset : Le32 :: from ( offset) ,
@@ -231,7 +228,7 @@ impl PciCapability for VirtioPciCfgCap {
231228impl VirtioPciCfgCap {
232229 fn new ( ) -> Self {
233230 VirtioPciCfgCap {
234- cap : VirtioPciCap :: new ( PciCapabilityType :: Pci , 0 , 0 , 0 ) ,
231+ cap : VirtioPciCap :: new ( PciCapabilityType :: Pci , 0 , 0 ) ,
235232 ..Default :: default ( )
236233 }
237234 }
@@ -306,7 +303,7 @@ pub struct VirtioPciDeviceState {
306303 pub pci_dev_state : VirtioPciCommonConfigState ,
307304 pub msix_state : MsixConfigState ,
308305 pub msi_vector_group : Vec < u32 > ,
309- pub bar_configuration : Vec < PciBarConfiguration > ,
306+ pub bar_configuration : PciBarConfiguration ,
310307}
311308
312309#[ derive( Debug , thiserror:: Error , displaydoc:: Display ) ]
@@ -348,12 +345,6 @@ pub struct VirtioPciDevice {
348345 // Guest memory
349346 memory : GuestMemoryMmap ,
350347
351- // Settings PCI BAR
352- settings_bar : u8 ,
353-
354- // Whether to use 64-bit bar location or 32-bit
355- use_64bit_bar : bool ,
356-
357348 // Add a dedicated structure to hold information about the very specific
358349 // virtio-pci capability VIRTIO_PCI_CAP_PCI_CFG. This is needed to support
359350 // the legacy/backward compatible mechanism of letting the guest access the
@@ -362,8 +353,8 @@ pub struct VirtioPciDevice {
362353 // a device.
363354 cap_pci_cfg_info : VirtioPciCfgCapInfo ,
364355
365- // Details of bar regions to free
366- pub bar_regions : Vec < PciBarConfiguration > ,
356+ // Details of BAR region
357+ pub bar_region : PciBarConfiguration ,
367358}
368359
369360impl Debug for VirtioPciDevice {
@@ -471,11 +462,9 @@ impl VirtioPciDevice {
471462 interrupt_status : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
472463 virtio_interrupt : Some ( interrupt) ,
473464 memory,
474- settings_bar : 0 ,
475- use_64bit_bar : true ,
476465 interrupt_source_group : msi_vectors,
477466 cap_pci_cfg_info : VirtioPciCfgCapInfo :: default ( ) ,
478- bar_regions : vec ! [ ] ,
467+ bar_region : PciBarConfiguration :: default ( ) ,
479468 } ;
480469
481470 Ok ( virtio_pci_device)
@@ -524,11 +513,9 @@ impl VirtioPciDevice {
524513 interrupt_status : Arc :: new ( AtomicUsize :: new ( state. interrupt_status ) ) ,
525514 virtio_interrupt : Some ( interrupt) ,
526515 memory : memory. clone ( ) ,
527- settings_bar : 0 ,
528- use_64bit_bar : true ,
529516 interrupt_source_group : msi_vectors,
530517 cap_pci_cfg_info,
531- bar_regions : state. bar_configuration ,
518+ bar_region : state. bar_configuration ,
532519 } ;
533520
534521 if state. device_activated {
@@ -558,17 +545,13 @@ impl VirtioPciDevice {
558545 }
559546
560547 pub fn config_bar_addr ( & self ) -> u64 {
561- self . configuration . get_bar_addr ( self . settings_bar as usize )
548+ self . configuration . get_bar_addr ( VIRTIO_BAR_INDEX as usize )
562549 }
563550
564- fn add_pci_capabilities (
565- & mut self ,
566- settings_bar : u8 ,
567- ) -> std:: result:: Result < ( ) , PciDeviceError > {
551+ fn add_pci_capabilities ( & mut self ) -> std:: result:: Result < ( ) , PciDeviceError > {
568552 // Add pointers to the different configuration structures from the PCI capabilities.
569553 let common_cap = VirtioPciCap :: new (
570554 PciCapabilityType :: Common ,
571- settings_bar,
572555 COMMON_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
573556 COMMON_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
574557 ) ;
@@ -578,7 +561,6 @@ impl VirtioPciDevice {
578561
579562 let isr_cap = VirtioPciCap :: new (
580563 PciCapabilityType :: Isr ,
581- settings_bar,
582564 ISR_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
583565 ISR_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
584566 ) ;
@@ -589,7 +571,6 @@ impl VirtioPciDevice {
589571 // TODO(dgreid) - set based on device's configuration size?
590572 let device_cap = VirtioPciCap :: new (
591573 PciCapabilityType :: Device ,
592- settings_bar,
593574 DEVICE_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
594575 DEVICE_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
595576 ) ;
@@ -599,7 +580,6 @@ impl VirtioPciDevice {
599580
600581 let notify_cap = VirtioPciNotifyCap :: new (
601582 PciCapabilityType :: Notify ,
602- settings_bar,
603583 NOTIFICATION_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
604584 NOTIFICATION_SIZE . try_into ( ) . unwrap ( ) ,
605585 Le32 :: from ( NOTIFY_OFF_MULTIPLIER ) ,
@@ -618,18 +598,17 @@ impl VirtioPciDevice {
618598
619599 if self . msix_config . is_some ( ) {
620600 let msix_cap = MsixCap :: new (
621- settings_bar ,
601+ VIRTIO_BAR_INDEX ,
622602 self . msix_num ,
623603 MSIX_TABLE_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
624- settings_bar ,
604+ VIRTIO_BAR_INDEX ,
625605 MSIX_PBA_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
626606 ) ;
627607 self . configuration
628608 . add_capability ( & msix_cap)
629609 . map_err ( PciDeviceError :: CapabilitiesSetup ) ?;
630610 }
631611
632- self . settings_bar = settings_bar;
633612 Ok ( ( ) )
634613 }
635614
@@ -744,7 +723,7 @@ impl VirtioPciDevice {
744723 . expect ( "Poisoned lock" )
745724 . state ( ) ,
746725 msi_vector_group : self . interrupt_source_group . save ( ) ,
747- bar_configuration : self . bar_regions . clone ( ) ,
726+ bar_configuration : self . bar_region ,
748727 }
749728 }
750729}
@@ -887,41 +866,25 @@ impl PciDevice for VirtioPciDevice {
887866 mmio32_allocator : & mut AddressAllocator ,
888867 mmio64_allocator : & mut AddressAllocator ,
889868 ) -> std:: result:: Result < Vec < PciBarConfiguration > , PciDeviceError > {
890- let mut bars = Vec :: new ( ) ;
891869 let device_clone = self . device . clone ( ) ;
892870 let device = device_clone. lock ( ) . unwrap ( ) ;
893871
894872 // Allocate the virtio-pci capability BAR.
895873 // See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
896- let ( virtio_pci_bar_addr, region_type) = if self . use_64bit_bar {
897- let region_type = PciBarRegionType :: Memory64BitRegion ;
898- let addr = mmio64_allocator
899- . allocate (
900- CAPABILITY_BAR_SIZE ,
901- CAPABILITY_BAR_SIZE ,
902- AllocPolicy :: FirstMatch ,
903- )
904- . unwrap ( )
905- . start ( ) ;
906- ( addr, region_type)
907- } else {
908- let region_type = PciBarRegionType :: Memory32BitRegion ;
909- let addr = mmio32_allocator
910- . allocate (
911- CAPABILITY_BAR_SIZE ,
912- CAPABILITY_BAR_SIZE ,
913- AllocPolicy :: FirstMatch ,
914- )
915- . unwrap ( )
916- . start ( ) ;
917- ( addr, region_type)
918- } ;
874+ let virtio_pci_bar_addr = mmio64_allocator
875+ . allocate (
876+ CAPABILITY_BAR_SIZE ,
877+ CAPABILITY_BAR_SIZE ,
878+ AllocPolicy :: FirstMatch ,
879+ )
880+ . unwrap ( )
881+ . start ( ) ;
919882
920883 let bar = PciBarConfiguration {
921884 addr : virtio_pci_bar_addr,
922885 size : CAPABILITY_BAR_SIZE ,
923886 idx : VIRTIO_COMMON_BAR_INDEX ,
924- region_type,
887+ region_type : PciBarRegionType :: Memory64BitRegion ,
925888 prefetchable : pci:: PciBarPrefetchable :: NotPrefetchable ,
926889 } ;
927890
@@ -934,32 +897,28 @@ impl PciDevice for VirtioPciDevice {
934897 . map_err ( |e| PciDeviceError :: IoRegistrationFailed ( virtio_pci_bar_addr, e) ) ?;
935898
936899 // Once the BARs are allocated, the capabilities can be added to the PCI configuration.
937- self . add_pci_capabilities ( VIRTIO_COMMON_BAR_INDEX . try_into ( ) . unwrap ( ) ) ?;
938-
939- bars. push ( bar) ;
940-
941- self . bar_regions . clone_from ( & bars) ;
900+ self . add_pci_capabilities ( ) ?;
901+ self . bar_region = bar;
942902
943- Ok ( bars )
903+ Ok ( vec ! [ bar ] )
944904 }
945905
946906 fn free_bars (
947907 & mut self ,
948908 mmio32_allocator : & mut AddressAllocator ,
949909 mmio64_allocator : & mut AddressAllocator ,
950910 ) -> std:: result:: Result < ( ) , PciDeviceError > {
951- for bar in self . bar_regions . drain ( ..) {
952- let range = RangeInclusive :: new ( bar. addr , bar. addr + bar. size ) . unwrap ( ) ;
953- match bar. region_type {
954- PciBarRegionType :: Memory32BitRegion => {
955- mmio32_allocator. free ( & range) ;
956- }
957- PciBarRegionType :: Memory64BitRegion => {
958- mmio64_allocator. free ( & range) ;
959- }
960- _ => error ! ( "Unexpected PCI bar type" ) ,
961- }
962- }
911+ assert_eq ! (
912+ self . bar_region. region_type,
913+ PciBarRegionType :: Memory64BitRegion
914+ ) ;
915+
916+ let range = RangeInclusive :: new (
917+ self . bar_region . addr ,
918+ self . bar_region . addr + self . bar_region . size ,
919+ )
920+ . unwrap ( ) ;
921+ mmio64_allocator. free ( & range) ;
963922 Ok ( ( ) )
964923 }
965924
@@ -970,10 +929,8 @@ impl PciDevice for VirtioPciDevice {
970929 ) -> std:: result:: Result < ( ) , std:: io:: Error > {
971930 // We only update our idea of the bar in order to support free_bars() above.
972931 // The majority of the reallocation is done inside DeviceManager.
973- for bar in self . bar_regions . iter_mut ( ) {
974- if bar. addr == old_base {
975- bar. addr = new_base;
976- }
932+ if self . bar_region . addr == old_base {
933+ self . bar_region . addr = new_base;
977934 }
978935
979936 Ok ( ( ) )
0 commit comments