@@ -57,7 +57,7 @@ impl DeviceFd {
5757 /// let kvm = Kvm::new().unwrap();
5858 /// let vm = kvm.create_vm().unwrap();
5959 ///
60- /// # #[cfg(not(target_arch = "riscv64"))]
60+ /// # #[cfg(not(any( target_arch = "riscv64", target_arch = "loongarch64") ))]
6161 /// # {
6262 /// # use kvm_bindings::{
6363 /// # kvm_device_type_KVM_DEV_TYPE_VFIO,
@@ -210,6 +210,7 @@ mod tests {
210210 #[ cfg( target_arch = "aarch64" ) ]
211211 use kvm_bindings:: { KVM_DEV_VFIO_GROUP , KVM_DEV_VFIO_GROUP_ADD } ;
212212
213+ #[ cfg( not( target_arch = "loongarch64" ) ) ]
213214 use kvm_bindings:: KVM_CREATE_DEVICE_TEST ;
214215
215216 #[ test]
@@ -409,4 +410,87 @@ mod tests {
409410 // when we initialize the AIA.
410411 assert_eq ! ( data, 128 ) ;
411412 }
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+ }
412496}
0 commit comments