@@ -1106,6 +1106,32 @@ impl AsRawFd for VmFd {
1106
1106
}
1107
1107
}
1108
1108
1109
+ /// Creates a dummy GIC device.
1110
+ ///
1111
+ /// # Arguments
1112
+ ///
1113
+ /// * `vm` - The vm file descriptor.
1114
+ /// * `flags` - Flags to be passed to `KVM_CREATE_DEVICE`.
1115
+ ///
1116
+ #[ cfg( test) ]
1117
+ #[ cfg( any( target_arch = "arm" , target_arch = "aarch64" ) ) ]
1118
+ pub ( crate ) fn create_gic_device ( vm : & VmFd , flags : u32 ) -> DeviceFd {
1119
+ let mut gic_device = kvm_bindings:: kvm_create_device {
1120
+ type_ : kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3,
1121
+ fd : 0 ,
1122
+ flags,
1123
+ } ;
1124
+ let device_fd = match vm. create_device ( & mut gic_device) {
1125
+ Ok ( fd) => fd,
1126
+ Err ( _) => {
1127
+ gic_device. type_ = kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2;
1128
+ vm. create_device ( & mut gic_device)
1129
+ . expect ( "Cannot create KVM vGIC device" )
1130
+ }
1131
+ } ;
1132
+ device_fd
1133
+ }
1134
+
1109
1135
#[ cfg( test) ]
1110
1136
mod tests {
1111
1137
use super :: * ;
@@ -1258,62 +1284,76 @@ mod tests {
1258
1284
}
1259
1285
1260
1286
#[ test]
1261
- #[ cfg( any(
1262
- target_arch = "x86" ,
1263
- target_arch = "x86_64" ,
1264
- target_arch = "arm" ,
1265
- target_arch = "aarch64"
1266
- ) ) ]
1267
- fn test_register_irqfd ( ) {
1287
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1288
+ fn test_register_unregister_irqfd ( ) {
1268
1289
let kvm = Kvm :: new ( ) . unwrap ( ) ;
1269
1290
let vm_fd = kvm. create_vm ( ) . unwrap ( ) ;
1270
1291
let evtfd1 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1271
1292
let evtfd2 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1272
1293
let evtfd3 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1273
- if cfg ! ( any( target_arch = "x86" , target_arch = "x86_64" ) ) {
1274
- assert ! ( vm_fd. create_irq_chip( ) . is_ok( ) ) ;
1275
- assert ! ( vm_fd. register_irqfd( & evtfd1, 4 ) . is_ok( ) ) ;
1276
- assert ! ( vm_fd. register_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1277
- assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_ok( ) ) ;
1278
- }
1279
1294
1280
- // On aarch64, this fails because setting up the interrupt controller is mandatory before
1281
- // registering any IRQ.
1295
+ assert ! ( vm_fd. create_irq_chip( ) . is_ok( ) ) ;
1296
+
1297
+ assert ! ( vm_fd. register_irqfd( & evtfd1, 4 ) . is_ok( ) ) ;
1298
+ assert ! ( vm_fd. register_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1299
+ assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_ok( ) ) ;
1300
+ assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1301
+ // KVM irqfd doesn't report failure on this case:(
1302
+ assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1303
+
1304
+ // Duplicated eventfd registration.
1282
1305
// On x86_64 this fails as the event fd was already matched with a GSI.
1283
1306
assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_err( ) ) ;
1284
1307
assert ! ( vm_fd. register_irqfd( & evtfd3, 5 ) . is_err( ) ) ;
1308
+ // KVM irqfd doesn't report failure on this case:(
1309
+ assert ! ( vm_fd. unregister_irqfd( & evtfd3, 5 ) . is_ok( ) ) ;
1285
1310
}
1286
1311
1287
1312
#[ test]
1288
- #[ cfg( any(
1289
- target_arch = "x86" ,
1290
- target_arch = "x86_64" ,
1291
- target_arch = "arm" ,
1292
- target_arch = "aarch64"
1293
- ) ) ]
1294
- fn test_unregister_irqfd ( ) {
1313
+ #[ cfg( target_arch = "aarch64" ) ]
1314
+ fn test_register_unregister_irqfd ( ) {
1295
1315
let kvm = Kvm :: new ( ) . unwrap ( ) ;
1296
1316
let vm_fd = kvm. create_vm ( ) . unwrap ( ) ;
1297
1317
let evtfd1 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1298
1318
let evtfd2 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1299
1319
let evtfd3 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
1300
- if cfg ! ( any( target_arch = "x86" , target_arch = "x86_64" ) ) {
1301
- assert ! ( vm_fd. create_irq_chip( ) . is_ok( ) ) ;
1302
- assert ! ( vm_fd. register_irqfd( & evtfd1, 4 ) . is_ok( ) ) ;
1303
- assert ! ( vm_fd. register_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1304
- assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_ok( ) ) ;
1305
- assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1306
- // KVM irqfd doesn't report failure on this case:(
1307
- assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1308
- }
1320
+
1321
+ // Create the vGIC device.
1322
+ let vgic_fd = create_gic_device ( & vm_fd, 0 ) ;
1323
+
1324
+ // Dummy interrupt for testing on aarch64.
1325
+ let nr_irqs: u32 = 128 ;
1326
+
1327
+ // We need to tell the kernel how many irqs to support with this vgic.
1328
+ let vgic_attr = kvm_bindings:: kvm_device_attr {
1329
+ group : kvm_bindings:: KVM_DEV_ARM_VGIC_GRP_NR_IRQS ,
1330
+ attr : 0 ,
1331
+ addr : & nr_irqs as * const u32 as u64 ,
1332
+ flags : 0 ,
1333
+ } ;
1334
+ assert ! ( vgic_fd. set_device_attr( & vgic_attr) . is_ok( ) ) ;
1335
+
1336
+ // Finalize the GIC.
1337
+ let vgic_attr = kvm_bindings:: kvm_device_attr {
1338
+ group : kvm_bindings:: KVM_DEV_ARM_VGIC_GRP_CTRL ,
1339
+ attr : u64:: from ( kvm_bindings:: KVM_DEV_ARM_VGIC_CTRL_INIT ) ,
1340
+ addr : 0 ,
1341
+ flags : 0 ,
1342
+ } ;
1343
+ assert ! ( vgic_fd. set_device_attr( & vgic_attr) . is_ok( ) ) ;
1344
+
1345
+ assert ! ( vm_fd. register_irqfd( & evtfd1, 4 ) . is_ok( ) ) ;
1346
+ assert ! ( vm_fd. register_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1347
+ assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_ok( ) ) ;
1348
+ assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1349
+ // KVM irqfd doesn't report failure on this case:(
1350
+ assert ! ( vm_fd. unregister_irqfd( & evtfd2, 8 ) . is_ok( ) ) ;
1309
1351
1310
1352
// Duplicated eventfd registration.
1311
1353
// On aarch64, this fails because setting up the interrupt controller is mandatory before
1312
1354
// registering any IRQ.
1313
- // On x86_64 this fails as the event fd was already matched with a GSI.
1314
1355
assert ! ( vm_fd. register_irqfd( & evtfd3, 4 ) . is_err( ) ) ;
1315
1356
assert ! ( vm_fd. register_irqfd( & evtfd3, 5 ) . is_err( ) ) ;
1316
-
1317
1357
// KVM irqfd doesn't report failure on this case:(
1318
1358
assert ! ( vm_fd. unregister_irqfd( & evtfd3, 5 ) . is_ok( ) ) ;
1319
1359
}
0 commit comments