@@ -235,3 +235,157 @@ impl KvmIrqRouting {
235235 self . set_routing ( & routes)
236236 }
237237}
238+
239+ #[ cfg( any( target = "x86" , target = "x86_64" ) ) ]
240+ #[ cfg( test) ]
241+ mod test {
242+ use super :: * ;
243+ use kvm_ioctls:: { Kvm , VmFd } ;
244+
245+ //const VFIO_PCI_MSI_IRQ_INDEX: u32 = 1;
246+
247+ fn create_vm_fd ( ) -> VmFd {
248+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
249+ kvm. create_vm ( ) . unwrap ( )
250+ }
251+
252+ fn create_irq_group (
253+ manager : Arc < KvmIrqManager > ,
254+ _vmfd : Arc < VmFd > ,
255+ ) -> Arc < Box < dyn InterruptSourceGroup > > {
256+ let base = 0 ;
257+ let count = 1 ;
258+
259+ manager
260+ . create_group ( InterruptSourceType :: LegacyIrq , base, count)
261+ . unwrap ( )
262+ }
263+
264+ fn create_msi_group (
265+ manager : Arc < KvmIrqManager > ,
266+ _vmfd : Arc < VmFd > ,
267+ ) -> Arc < Box < dyn InterruptSourceGroup > > {
268+ let base = 168 ;
269+ let count = 32 ;
270+
271+ manager
272+ . create_group ( InterruptSourceType :: MsiIrq , base, count)
273+ . unwrap ( )
274+ }
275+
276+ const MASTER_PIC : usize = 7 ;
277+ const SLAVE_PIC : usize = 8 ;
278+ const IOAPIC : usize = 23 ;
279+
280+ #[ test]
281+ fn test_create_kvmirqmanager ( ) {
282+ let vmfd = Arc :: new ( create_vm_fd ( ) ) ;
283+ let manager = KvmIrqManager :: new ( vmfd. clone ( ) ) ;
284+ assert ! ( vmfd. create_irq_chip( ) . is_ok( ) ) ;
285+ assert ! ( manager. initialize( ) . is_ok( ) ) ;
286+ }
287+
288+ #[ test]
289+ fn test_kvmirqmanager_opt ( ) {
290+ let vmfd = Arc :: new ( create_vm_fd ( ) ) ;
291+ assert ! ( vmfd. create_irq_chip( ) . is_ok( ) ) ;
292+ let manager = Arc :: new ( KvmIrqManager :: new ( vmfd. clone ( ) ) ) ;
293+ assert ! ( manager. initialize( ) . is_ok( ) ) ;
294+ //irq
295+ let group = create_irq_group ( manager. clone ( ) , vmfd. clone ( ) ) ;
296+ let _ = group. clone ( ) ;
297+ assert ! ( manager. destroy_group( group) . is_ok( ) ) ;
298+ //msi
299+ let group = create_msi_group ( manager. clone ( ) , vmfd. clone ( ) ) ;
300+ let _ = group. clone ( ) ;
301+ assert ! ( manager. destroy_group( group) . is_ok( ) ) ;
302+ }
303+
304+ #[ test]
305+ fn test_irqrouting_initialize_legacy ( ) {
306+ let vmfd = Arc :: new ( create_vm_fd ( ) ) ;
307+ let routing = KvmIrqRouting :: new ( vmfd. clone ( ) ) ;
308+ assert ! ( routing. initialize( ) . is_err( ) ) ;
309+ assert ! ( vmfd. create_irq_chip( ) . is_ok( ) ) ;
310+ assert ! ( routing. initialize( ) . is_ok( ) ) ;
311+ let routes = & routing. routes . lock ( ) . unwrap ( ) ;
312+ assert_eq ! ( routes. len( ) , MASTER_PIC + SLAVE_PIC + IOAPIC ) ;
313+ }
314+
315+ #[ test]
316+ fn test_routing_opt ( ) {
317+ // pub(super) fn modify(&self, entry: &kvm_irq_routing_entry) -> Result<()> {
318+ let vmfd = Arc :: new ( create_vm_fd ( ) ) ;
319+ let routing = KvmIrqRouting :: new ( vmfd. clone ( ) ) ;
320+ assert ! ( routing. initialize( ) . is_err( ) ) ;
321+ assert ! ( vmfd. create_irq_chip( ) . is_ok( ) ) ;
322+ assert ! ( routing. initialize( ) . is_ok( ) ) ;
323+
324+ let mut entry = kvm_irq_routing_entry {
325+ gsi : 8 ,
326+ type_ : KVM_IRQ_ROUTING_IRQCHIP ,
327+ ..Default :: default ( )
328+ } ;
329+
330+ // Safe because we are initializing all fields of the `irqchip` struct.
331+ unsafe {
332+ entry. u . irqchip . irqchip = 0 ;
333+ entry. u . irqchip . pin = 3 ;
334+ }
335+
336+ let entrys = vec ! [ entry. clone( ) ] ;
337+
338+ assert ! ( routing. modify( & entry) . is_err( ) ) ;
339+ assert ! ( routing. add( & entrys) . is_ok( ) ) ;
340+ unsafe {
341+ entry. u . irqchip . pin = 4 ;
342+ }
343+ assert ! ( routing. modify( & entry) . is_ok( ) ) ;
344+ assert ! ( routing. remove( & entrys) . is_ok( ) ) ;
345+ assert ! ( routing. modify( & entry) . is_err( ) ) ;
346+ }
347+
348+ #[ test]
349+ fn test_routing_commit ( ) {
350+ let vmfd = Arc :: new ( create_vm_fd ( ) ) ;
351+ let routing = KvmIrqRouting :: new ( vmfd. clone ( ) ) ;
352+
353+ assert ! ( routing. initialize( ) . is_err( ) ) ;
354+ assert ! ( vmfd. create_irq_chip( ) . is_ok( ) ) ;
355+ assert ! ( routing. initialize( ) . is_ok( ) ) ;
356+
357+ let mut entry = kvm_irq_routing_entry {
358+ gsi : 8 ,
359+ type_ : KVM_IRQ_ROUTING_IRQCHIP ,
360+ ..Default :: default ( )
361+ } ;
362+ unsafe {
363+ entry. u . irqchip . irqchip = 0 ;
364+ entry. u . irqchip . pin = 3 ;
365+ }
366+
367+ routing
368+ . routes
369+ . lock ( )
370+ . unwrap ( )
371+ . insert ( hash_key ( & entry) , entry) ;
372+ let routes = routing. routes . lock ( ) . unwrap ( ) ;
373+ assert ! ( routing. commit( & routes) . is_ok( ) ) ;
374+ }
375+
376+ #[ test]
377+ fn test_has_key ( ) {
378+ let gsi = 4 ;
379+ let mut entry = kvm_irq_routing_entry {
380+ gsi,
381+ type_ : KVM_IRQ_ROUTING_IRQCHIP ,
382+ ..Default :: default ( )
383+ } ;
384+ // Safe because we are initializing all fields of the `irqchip` struct.
385+ unsafe {
386+ entry. u . irqchip . irqchip = KVM_IRQCHIP_PIC_MASTER ;
387+ entry. u . irqchip . pin = gsi;
388+ }
389+ assert_eq ! ( hash_key( & entry) , 0x0001_0000_0004 ) ;
390+ }
391+ }
0 commit comments