@@ -67,6 +67,9 @@ const VIRTIO_F_NOTIFICATION_DATA: u32 = 38;
67
67
/// Vector value used to disable MSI for a queue.
68
68
const VIRTQ_MSI_NO_VECTOR : u16 = 0xffff ;
69
69
70
+ /// BAR index we are using for VirtIO configuration
71
+ const VIRTIO_BAR_INDEX : u8 = 0 ;
72
+
70
73
enum PciCapabilityType {
71
74
Common = 1 ,
72
75
Notify = 2 ,
@@ -110,12 +113,12 @@ impl PciCapability for VirtioPciCap {
110
113
const VIRTIO_PCI_CAP_LEN_OFFSET : u8 = 2 ;
111
114
112
115
impl 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 {
114
117
VirtioPciCap {
115
118
cap_len : u8:: try_from ( std:: mem:: size_of :: < VirtioPciCap > ( ) ) . unwrap ( )
116
119
+ VIRTIO_PCI_CAP_LEN_OFFSET ,
117
120
cfg_type : cfg_type as u8 ,
118
- pci_bar,
121
+ pci_bar : VIRTIO_BAR_INDEX ,
119
122
id : 0 ,
120
123
padding : [ 0 ; 2 ] ,
121
124
offset : Le32 :: from ( offset) ,
@@ -145,19 +148,13 @@ impl PciCapability for VirtioPciNotifyCap {
145
148
}
146
149
147
150
impl 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 {
155
152
VirtioPciNotifyCap {
156
153
cap : VirtioPciCap {
157
154
cap_len : u8:: try_from ( std:: mem:: size_of :: < VirtioPciNotifyCap > ( ) ) . unwrap ( )
158
155
+ VIRTIO_PCI_CAP_LEN_OFFSET ,
159
156
cfg_type : cfg_type as u8 ,
160
- pci_bar,
157
+ pci_bar : VIRTIO_BAR_INDEX ,
161
158
id : 0 ,
162
159
padding : [ 0 ; 2 ] ,
163
160
offset : Le32 :: from ( offset) ,
@@ -231,7 +228,7 @@ impl PciCapability for VirtioPciCfgCap {
231
228
impl VirtioPciCfgCap {
232
229
fn new ( ) -> Self {
233
230
VirtioPciCfgCap {
234
- cap : VirtioPciCap :: new ( PciCapabilityType :: Pci , 0 , 0 , 0 ) ,
231
+ cap : VirtioPciCap :: new ( PciCapabilityType :: Pci , 0 , 0 ) ,
235
232
..Default :: default ( )
236
233
}
237
234
}
@@ -306,7 +303,7 @@ pub struct VirtioPciDeviceState {
306
303
pub pci_dev_state : VirtioPciCommonConfigState ,
307
304
pub msix_state : MsixConfigState ,
308
305
pub msi_vector_group : Vec < u32 > ,
309
- pub bar_configuration : Vec < PciBarConfiguration > ,
306
+ pub bar_configuration : PciBarConfiguration ,
310
307
}
311
308
312
309
#[ derive( Debug , thiserror:: Error , displaydoc:: Display ) ]
@@ -348,12 +345,6 @@ pub struct VirtioPciDevice {
348
345
// Guest memory
349
346
memory : GuestMemoryMmap ,
350
347
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
-
357
348
// Add a dedicated structure to hold information about the very specific
358
349
// virtio-pci capability VIRTIO_PCI_CAP_PCI_CFG. This is needed to support
359
350
// the legacy/backward compatible mechanism of letting the guest access the
@@ -362,8 +353,8 @@ pub struct VirtioPciDevice {
362
353
// a device.
363
354
cap_pci_cfg_info : VirtioPciCfgCapInfo ,
364
355
365
- // Details of bar regions to free
366
- pub bar_regions : Vec < PciBarConfiguration > ,
356
+ // Details of BAR region
357
+ pub bar_region : PciBarConfiguration ,
367
358
}
368
359
369
360
impl Debug for VirtioPciDevice {
@@ -471,11 +462,9 @@ impl VirtioPciDevice {
471
462
interrupt_status : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
472
463
virtio_interrupt : Some ( interrupt) ,
473
464
memory,
474
- settings_bar : 0 ,
475
- use_64bit_bar : true ,
476
465
interrupt_source_group : msi_vectors,
477
466
cap_pci_cfg_info : VirtioPciCfgCapInfo :: default ( ) ,
478
- bar_regions : vec ! [ ] ,
467
+ bar_region : PciBarConfiguration :: default ( ) ,
479
468
} ;
480
469
481
470
Ok ( virtio_pci_device)
@@ -524,11 +513,9 @@ impl VirtioPciDevice {
524
513
interrupt_status : Arc :: new ( AtomicUsize :: new ( state. interrupt_status ) ) ,
525
514
virtio_interrupt : Some ( interrupt) ,
526
515
memory : memory. clone ( ) ,
527
- settings_bar : 0 ,
528
- use_64bit_bar : true ,
529
516
interrupt_source_group : msi_vectors,
530
517
cap_pci_cfg_info,
531
- bar_regions : state. bar_configuration ,
518
+ bar_region : state. bar_configuration ,
532
519
} ;
533
520
534
521
if state. device_activated {
@@ -558,17 +545,13 @@ impl VirtioPciDevice {
558
545
}
559
546
560
547
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 )
562
549
}
563
550
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 > {
568
552
// Add pointers to the different configuration structures from the PCI capabilities.
569
553
let common_cap = VirtioPciCap :: new (
570
554
PciCapabilityType :: Common ,
571
- settings_bar,
572
555
COMMON_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
573
556
COMMON_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
574
557
) ;
@@ -578,7 +561,6 @@ impl VirtioPciDevice {
578
561
579
562
let isr_cap = VirtioPciCap :: new (
580
563
PciCapabilityType :: Isr ,
581
- settings_bar,
582
564
ISR_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
583
565
ISR_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
584
566
) ;
@@ -589,7 +571,6 @@ impl VirtioPciDevice {
589
571
// TODO(dgreid) - set based on device's configuration size?
590
572
let device_cap = VirtioPciCap :: new (
591
573
PciCapabilityType :: Device ,
592
- settings_bar,
593
574
DEVICE_CONFIG_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
594
575
DEVICE_CONFIG_SIZE . try_into ( ) . unwrap ( ) ,
595
576
) ;
@@ -599,7 +580,6 @@ impl VirtioPciDevice {
599
580
600
581
let notify_cap = VirtioPciNotifyCap :: new (
601
582
PciCapabilityType :: Notify ,
602
- settings_bar,
603
583
NOTIFICATION_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
604
584
NOTIFICATION_SIZE . try_into ( ) . unwrap ( ) ,
605
585
Le32 :: from ( NOTIFY_OFF_MULTIPLIER ) ,
@@ -618,18 +598,17 @@ impl VirtioPciDevice {
618
598
619
599
if self . msix_config . is_some ( ) {
620
600
let msix_cap = MsixCap :: new (
621
- settings_bar ,
601
+ VIRTIO_BAR_INDEX ,
622
602
self . msix_num ,
623
603
MSIX_TABLE_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
624
- settings_bar ,
604
+ VIRTIO_BAR_INDEX ,
625
605
MSIX_PBA_BAR_OFFSET . try_into ( ) . unwrap ( ) ,
626
606
) ;
627
607
self . configuration
628
608
. add_capability ( & msix_cap)
629
609
. map_err ( PciDeviceError :: CapabilitiesSetup ) ?;
630
610
}
631
611
632
- self . settings_bar = settings_bar;
633
612
Ok ( ( ) )
634
613
}
635
614
@@ -744,7 +723,7 @@ impl VirtioPciDevice {
744
723
. expect ( "Poisoned lock" )
745
724
. state ( ) ,
746
725
msi_vector_group : self . interrupt_source_group . save ( ) ,
747
- bar_configuration : self . bar_regions . clone ( ) ,
726
+ bar_configuration : self . bar_region ,
748
727
}
749
728
}
750
729
}
@@ -887,41 +866,25 @@ impl PciDevice for VirtioPciDevice {
887
866
mmio32_allocator : & mut AddressAllocator ,
888
867
mmio64_allocator : & mut AddressAllocator ,
889
868
) -> std:: result:: Result < Vec < PciBarConfiguration > , PciDeviceError > {
890
- let mut bars = Vec :: new ( ) ;
891
869
let device_clone = self . device . clone ( ) ;
892
870
let device = device_clone. lock ( ) . unwrap ( ) ;
893
871
894
872
// Allocate the virtio-pci capability BAR.
895
873
// 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 ( ) ;
919
882
920
883
let bar = PciBarConfiguration {
921
884
addr : virtio_pci_bar_addr,
922
885
size : CAPABILITY_BAR_SIZE ,
923
886
idx : VIRTIO_COMMON_BAR_INDEX ,
924
- region_type,
887
+ region_type : PciBarRegionType :: Memory64BitRegion ,
925
888
prefetchable : pci:: PciBarPrefetchable :: NotPrefetchable ,
926
889
} ;
927
890
@@ -934,32 +897,28 @@ impl PciDevice for VirtioPciDevice {
934
897
. map_err ( |e| PciDeviceError :: IoRegistrationFailed ( virtio_pci_bar_addr, e) ) ?;
935
898
936
899
// 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;
942
902
943
- Ok ( bars )
903
+ Ok ( vec ! [ bar ] )
944
904
}
945
905
946
906
fn free_bars (
947
907
& mut self ,
948
908
mmio32_allocator : & mut AddressAllocator ,
949
909
mmio64_allocator : & mut AddressAllocator ,
950
910
) -> 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) ;
963
922
Ok ( ( ) )
964
923
}
965
924
@@ -970,10 +929,8 @@ impl PciDevice for VirtioPciDevice {
970
929
) -> std:: result:: Result < ( ) , std:: io:: Error > {
971
930
// We only update our idea of the bar in order to support free_bars() above.
972
931
// 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;
977
934
}
978
935
979
936
Ok ( ( ) )
0 commit comments