@@ -59,41 +59,84 @@ impl FromRawFd for DeviceFd {
59
59
mod tests {
60
60
use super :: * ;
61
61
use ioctls:: system:: Kvm ;
62
+ #[ cfg( target_arch = "aarch64" ) ]
63
+ use kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2;
64
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
65
+ use kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_VFIO;
62
66
use kvm_bindings:: {
63
- kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3, kvm_device_type_KVM_DEV_TYPE_VFIO ,
64
- KVM_CREATE_DEVICE_TEST , KVM_DEV_VFIO_GROUP , KVM_DEV_VFIO_GROUP_ADD ,
67
+ kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3, KVM_CREATE_DEVICE_TEST , KVM_DEV_VFIO_GROUP ,
68
+ KVM_DEV_VFIO_GROUP_ADD ,
65
69
} ;
66
70
67
71
#[ test]
72
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
68
73
fn test_create_device ( ) {
69
- #[ cfg( any( target_arch = "arm" , target_arch = "aarch64" ) ) ]
70
- use kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20;
71
-
72
74
let kvm = Kvm :: new ( ) . unwrap ( ) ;
73
75
let vm = kvm. create_vm ( ) . unwrap ( ) ;
74
76
75
77
let mut gic_device = kvm_bindings:: kvm_create_device {
76
- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
77
78
type_ : kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3,
78
- #[ cfg( any( target_arch = "arm" , target_arch = "aarch64" ) ) ]
79
- type_ : kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20,
80
79
fd : 0 ,
81
80
flags : KVM_CREATE_DEVICE_TEST ,
82
81
} ;
83
82
// This fails on x86_64 because there is no VGIC there.
84
- // This fails on aarch64 as it does not use MPIC (MultiProcessor Interrupt Controller), it uses
85
- // the VGIC.
86
83
assert ! ( vm. create_device( & mut gic_device) . is_err( ) ) ;
87
84
88
- if cfg ! ( any( target_arch = "x86" , target_arch = "x86_64" ) ) {
89
- gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_VFIO;
90
- } else if cfg ! ( any( target_arch = "arm" , target_arch = "aarch64" ) ) {
91
- gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3;
92
- }
85
+ gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_VFIO;
86
+
93
87
let device_fd = vm
94
88
. create_device ( & mut gic_device)
95
89
. expect ( "Cannot create KVM device" ) ;
96
90
91
+ // Following lines to re-construct device_fd are used to test
92
+ // DeviceFd::from_raw_fd() and DeviceFd::as_raw_fd().
93
+ let raw_fd = unsafe { libc:: dup ( device_fd. as_raw_fd ( ) ) } ;
94
+ assert ! ( raw_fd >= 0 ) ;
95
+ let device_fd = unsafe { DeviceFd :: from_raw_fd ( raw_fd) } ;
96
+
97
+ let dist_attr = kvm_bindings:: kvm_device_attr {
98
+ group : KVM_DEV_VFIO_GROUP ,
99
+ attr : u64:: from ( KVM_DEV_VFIO_GROUP_ADD ) ,
100
+ addr : 0x0 ,
101
+ flags : 0 ,
102
+ } ;
103
+
104
+ // We are just creating a test device. Creating a real device would make the CI dependent
105
+ // on host configuration (like having /dev/vfio). We expect this to fail.
106
+ assert ! ( device_fd. set_device_attr( & dist_attr) . is_err( ) ) ;
107
+ assert_eq ! ( errno:: Error :: last( ) . errno( ) , 25 ) ;
108
+ }
109
+
110
+ #[ test]
111
+ #[ cfg( target_arch = "aarch64" ) ]
112
+ fn test_create_device ( ) {
113
+ use kvm_bindings:: kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20;
114
+
115
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
116
+ let vm = kvm. create_vm ( ) . unwrap ( ) ;
117
+
118
+ let mut gic_device = kvm_bindings:: kvm_create_device {
119
+ type_ : kvm_device_type_KVM_DEV_TYPE_FSL_MPIC_20,
120
+ fd : 0 ,
121
+ flags : KVM_CREATE_DEVICE_TEST ,
122
+ } ;
123
+ // This fails on aarch64 as it does not use MPIC (MultiProcessor Interrupt Controller), it uses
124
+ // the VGIC.
125
+ assert ! ( vm. create_device( & mut gic_device) . is_err( ) ) ;
126
+
127
+ gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3;
128
+
129
+ let device_fd = match vm. create_device ( & mut gic_device) {
130
+ Ok ( fd) => fd,
131
+ Err ( _) => {
132
+ gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2;
133
+ vm. create_device ( & mut gic_device)
134
+ . expect ( "Cannot create KVM device" )
135
+ }
136
+ } ;
137
+
138
+ // Following lines to re-construct device_fd are used to test
139
+ // DeviceFd::from_raw_fd() and DeviceFd::as_raw_fd().
97
140
let raw_fd = unsafe { libc:: dup ( device_fd. as_raw_fd ( ) ) } ;
98
141
assert ! ( raw_fd >= 0 ) ;
99
142
let device_fd = unsafe { DeviceFd :: from_raw_fd ( raw_fd) } ;
0 commit comments