@@ -24,6 +24,7 @@ impl GICv3 {
2424 const SZ_64K : u64 = 0x0001_0000 ;
2525 const KVM_VGIC_V3_DIST_SIZE : u64 = GICv3 :: SZ_64K ;
2626 const KVM_VGIC_V3_REDIST_SIZE : u64 = ( 2 * GICv3 :: SZ_64K ) ;
27+ const GIC_V3_ITS_SIZE : u64 = 0x2_0000 ;
2728
2829 // Device trees specific constants
2930 const ARCH_GIC_V3_MAINT_IRQ : u32 = 9 ;
@@ -48,6 +49,16 @@ impl GICv3 {
4849 vcpu_count * GICv3 :: KVM_VGIC_V3_REDIST_SIZE
4950 }
5051
52+ /// Get the MSI address
53+ fn get_msi_address ( vcpu_count : u64 ) -> u64 {
54+ Self :: get_redists_addr ( vcpu_count) - GICv3 :: GIC_V3_ITS_SIZE
55+ }
56+
57+ /// Get the MSI size
58+ const fn get_msi_size ( ) -> u64 {
59+ GICv3 :: GIC_V3_ITS_SIZE
60+ }
61+
5162 pub const VERSION : u32 = kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3;
5263
5364 pub fn fdt_compatibility ( & self ) -> & str {
@@ -59,17 +70,41 @@ impl GICv3 {
5970 }
6071
6172 /// Create the GIC device object
62- pub fn create_device ( fd : DeviceFd , vcpu_count : u64 ) -> Self {
63- GICv3 ( super :: GIC {
64- fd,
73+ pub fn create_device ( vm : & VmFd , vcpu_count : u64 ) -> Result < Self , GicError > {
74+ // Create the GIC device
75+ let mut gic_device = kvm_bindings:: kvm_create_device {
76+ type_ : Self :: VERSION ,
77+ fd : 0 ,
78+ flags : 0 ,
79+ } ;
80+
81+ let gic_fd = vm
82+ . create_device ( & mut gic_device)
83+ . map_err ( GicError :: CreateGIC ) ?;
84+
85+ // ITS part attributes
86+ let mut its_device = kvm_bindings:: kvm_create_device {
87+ type_ : kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_ITS,
88+ fd : 0 ,
89+ flags : 0 ,
90+ } ;
91+
92+ let its_fd = vm
93+ . create_device ( & mut its_device)
94+ . map_err ( GicError :: CreateGIC ) ?;
95+
96+ Ok ( GICv3 ( super :: GIC {
97+ fd : gic_fd,
6598 properties : [
6699 GICv3 :: get_dist_addr ( ) ,
67100 GICv3 :: get_dist_size ( ) ,
68101 GICv3 :: get_redists_addr ( vcpu_count) ,
69102 GICv3 :: get_redists_size ( vcpu_count) ,
70103 ] ,
104+ msi_properties : Some ( [ GICv3 :: get_msi_address ( vcpu_count) , GICv3 :: get_msi_size ( ) ] ) ,
71105 vcpu_count,
72- } )
106+ its_device : Some ( its_fd) ,
107+ } ) )
73108 }
74109
75110 pub fn save_device ( & self , mpidrs : & [ u64 ] ) -> Result < GicState , GicError > {
@@ -82,7 +117,7 @@ impl GICv3 {
82117
83118 pub fn init_device_attributes ( gic_device : & Self ) -> Result < ( ) , GicError > {
84119 // Setting up the distributor attribute.
85- // We are placing the GIC below 1GB so we need to substract the size of the distributor.
120+ // We are placing the GIC below 1GB so we need to subtract the size of the distributor.
86121 Self :: set_device_attribute (
87122 gic_device. device_fd ( ) ,
88123 kvm_bindings:: KVM_DEV_ARM_VGIC_GRP_ADDR ,
@@ -101,26 +136,29 @@ impl GICv3 {
101136 0 ,
102137 ) ?;
103138
104- Ok ( ( ) )
105- }
139+ // Setting up the ITS attributes
140+ Self :: set_device_attribute (
141+ gic_device. its_device . as_ref ( ) . unwrap ( ) ,
142+ kvm_bindings:: KVM_DEV_ARM_VGIC_GRP_ADDR ,
143+ u64:: from ( kvm_bindings:: KVM_VGIC_ITS_ADDR_TYPE ) ,
144+ Self :: get_msi_address ( gic_device. vcpu_count ( ) ) as * const u64 as u64 ,
145+ 0 ,
146+ ) ?;
106147
107- /// Initialize a GIC device
108- pub fn init_device ( vm : & VmFd ) -> Result < DeviceFd , GicError > {
109- let mut gic_device = kvm_bindings:: kvm_create_device {
110- type_ : Self :: VERSION ,
111- fd : 0 ,
112- flags : 0 ,
113- } ;
148+ Self :: set_device_attribute (
149+ gic_device . its_device . as_ref ( ) . unwrap ( ) ,
150+ kvm_bindings:: KVM_DEV_ARM_VGIC_GRP_CTRL ,
151+ u64 :: from ( kvm_bindings :: KVM_DEV_ARM_VGIC_CTRL_INIT ) ,
152+ 0 ,
153+ 0 ,
154+ ) ? ;
114155
115- vm. create_device ( & mut gic_device)
116- . map_err ( GicError :: CreateGIC )
156+ Ok ( ( ) )
117157 }
118158
119159 /// Method to initialize the GIC device
120160 pub fn create ( vm : & VmFd , vcpu_count : u64 ) -> Result < Self , GicError > {
121- let vgic_fd = Self :: init_device ( vm) ?;
122-
123- let device = Self :: create_device ( vgic_fd, vcpu_count) ;
161+ let device = Self :: create_device ( vm, vcpu_count) ?;
124162
125163 Self :: init_device_attributes ( & device) ?;
126164
0 commit comments