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