@@ -57,7 +57,7 @@ impl DeviceFd {
57
57
/// let kvm = Kvm::new().unwrap();
58
58
/// let vm = kvm.create_vm().unwrap();
59
59
///
60
- /// # #[cfg(not(target_arch = "riscv64"))]
60
+ /// # #[cfg(not(any( target_arch = "riscv64", target_arch = "loongarch64") ))]
61
61
/// # {
62
62
/// # use kvm_bindings::{
63
63
/// # kvm_device_type_KVM_DEV_TYPE_VFIO,
@@ -210,6 +210,7 @@ mod tests {
210
210
#[ cfg( target_arch = "aarch64" ) ]
211
211
use kvm_bindings:: { KVM_DEV_VFIO_GROUP , KVM_DEV_VFIO_GROUP_ADD } ;
212
212
213
+ #[ cfg( not( target_arch = "loongarch64" ) ) ]
213
214
use kvm_bindings:: KVM_CREATE_DEVICE_TEST ;
214
215
215
216
#[ test]
@@ -409,4 +410,87 @@ mod tests {
409
410
// when we initialize the AIA.
410
411
assert_eq ! ( data, 128 ) ;
411
412
}
413
+
414
+ #[ test]
415
+ #[ cfg( target_arch = "loongarch64" ) ]
416
+ fn test_create_device ( ) {
417
+ use crate :: ioctls:: vm:: { create_eiointc_device, create_ipi_device, create_pchpic_device} ;
418
+ use kvm_bindings:: {
419
+ kvm_device_attr, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS , KVM_DEV_LOONGARCH_IPI_GRP_REGS ,
420
+ KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS ,
421
+ } ;
422
+ use vmm_sys_util:: errno:: Error ;
423
+
424
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
425
+ let vm = kvm. create_vm ( ) . unwrap ( ) ;
426
+ let ipi_fd = create_ipi_device ( & vm, 0 ) ;
427
+ let eio_fd = create_eiointc_device ( & vm, 0 ) ;
428
+ let pch_fd = create_pchpic_device ( & vm, 0 ) ;
429
+
430
+ vm. create_vcpu ( 0 ) . unwrap ( ) ;
431
+
432
+ let raw_fd = unsafe { libc:: dup ( ipi_fd. as_raw_fd ( ) ) } ;
433
+ assert ! ( raw_fd >= 0 ) ;
434
+ let ipi_fd = unsafe { DeviceFd :: from_raw_fd ( raw_fd) } ;
435
+
436
+ let mut data: u32 = 0 ;
437
+ let mut ipi_attr = kvm_device_attr {
438
+ group : KVM_DEV_LOONGARCH_IPI_GRP_REGS ,
439
+ attr : 4 ,
440
+ addr : data as u64 ,
441
+ ..Default :: default ( )
442
+ } ;
443
+
444
+ // Without properly providing the address to where the
445
+ // value will be stored, the ioctl fails with EFAULT.
446
+ let res = unsafe { ipi_fd. get_device_attr ( & mut ipi_attr) } ;
447
+ assert_eq ! ( res, Err ( Error :: new( libc:: EFAULT ) ) ) ;
448
+
449
+ ipi_attr. addr = & mut data as * mut u32 as u64 ;
450
+ unsafe { ipi_fd. get_device_attr ( & mut ipi_attr) } . unwrap ( ) ;
451
+ // The IPI enable state should be false.
452
+ assert_eq ! ( data, 0 ) ;
453
+
454
+ let raw_fd = unsafe { libc:: dup ( eio_fd. as_raw_fd ( ) ) } ;
455
+ assert ! ( raw_fd >= 0 ) ;
456
+ let eio_fd = unsafe { DeviceFd :: from_raw_fd ( raw_fd) } ;
457
+
458
+ let mut eio_attr = kvm_device_attr {
459
+ group : KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS ,
460
+ attr : 0x200 ,
461
+ addr : data as u64 ,
462
+ ..Default :: default ( )
463
+ } ;
464
+
465
+ // Without properly providing the address to where the
466
+ // value will be stored, the ioctl fails with EFAULT.
467
+ let res = unsafe { eio_fd. get_device_attr ( & mut eio_attr) } ;
468
+ assert_eq ! ( res, Err ( Error :: new( libc:: EFAULT ) ) ) ;
469
+
470
+ eio_attr. addr = & mut data as * mut u32 as u64 ;
471
+ unsafe { eio_fd. get_device_attr ( & mut eio_attr) } . unwrap ( ) ;
472
+ // The EIOINTC enable state should be false.
473
+ assert_eq ! ( data, 0 ) ;
474
+
475
+ let raw_fd = unsafe { libc:: dup ( pch_fd. as_raw_fd ( ) ) } ;
476
+ assert ! ( raw_fd >= 0 ) ;
477
+ let pch_fd = unsafe { DeviceFd :: from_raw_fd ( raw_fd) } ;
478
+
479
+ let mut pch_attr = kvm_device_attr {
480
+ group : KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS ,
481
+ attr : 0x3a0 ,
482
+ addr : data as u64 ,
483
+ ..Default :: default ( )
484
+ } ;
485
+
486
+ // Without properly providing the address to where the
487
+ // value will be stored, the ioctl fails with EFAULT.
488
+ let res = unsafe { pch_fd. get_device_attr ( & mut pch_attr) } ;
489
+ assert_eq ! ( res, Err ( Error :: new( libc:: EFAULT ) ) ) ;
490
+
491
+ pch_attr. addr = & mut data as * mut u32 as u64 ;
492
+ unsafe { pch_fd. get_device_attr ( & mut pch_attr) } . unwrap ( ) ;
493
+ // The PCH-PIC ISR enable state should be false.
494
+ assert_eq ! ( data, 0 ) ;
495
+ }
412
496
}
0 commit comments