1
+ // Copyright © 2024 Institute of Software, CAS. All rights reserved.
2
+ //
1
3
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
4
// SPDX-License-Identifier: Apache-2.0 OR MIT
3
5
//
@@ -22,7 +24,14 @@ use vmm_sys_util::errno;
22
24
use vmm_sys_util:: eventfd:: EventFd ;
23
25
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
24
26
use vmm_sys_util:: ioctl:: ioctl_with_mut_ptr;
25
- use vmm_sys_util:: ioctl:: { ioctl, ioctl_with_mut_ref, ioctl_with_ref, ioctl_with_val} ;
27
+ #[ cfg( any(
28
+ target_arch = "x86" ,
29
+ target_arch = "x86_64" ,
30
+ target_arch = "arm" ,
31
+ target_arch = "aarch64"
32
+ ) ) ]
33
+ use vmm_sys_util:: ioctl:: { ioctl, ioctl_with_mut_ref} ;
34
+ use vmm_sys_util:: ioctl:: { ioctl_with_ref, ioctl_with_val} ;
26
35
27
36
/// An address either in programmable I/O space or in memory mapped I/O space.
28
37
///
@@ -2348,6 +2357,64 @@ mod tests {
2348
2357
}
2349
2358
}
2350
2359
2360
+ #[ test]
2361
+ #[ cfg( target_arch = "riscv64" ) ]
2362
+ fn test_register_unregister_irqfd ( ) {
2363
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
2364
+ let vm_fd = kvm. create_vm ( ) . unwrap ( ) ;
2365
+ let evtfd1 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
2366
+ let evtfd2 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
2367
+ let evtfd3 = EventFd :: new ( EFD_NONBLOCK ) . unwrap ( ) ;
2368
+
2369
+ // Create the vAIA device.
2370
+ let vaia_fd = create_aia_device ( & vm_fd, 0 ) ;
2371
+
2372
+ // AIA on riscv64 requires at least one online vCPU prior to setting
2373
+ // device attributes. Otherwise it would fail when trying ot set address
2374
+ // of IMSIC.
2375
+ vm_fd. create_vcpu ( 0 ) . unwrap ( ) ;
2376
+
2377
+ // Set maximum supported number of IRQs of the vAIA device to 128.
2378
+ set_supported_nr_irqs ( & vaia_fd, 128 ) ;
2379
+
2380
+ // Before request vAIA device to initialize, APLIC and IMSIC must be set
2381
+ let aplic_addr: u64 = 0x4000 ;
2382
+ vaia_fd
2383
+ . set_device_attr ( & kvm_device_attr {
2384
+ group : KVM_DEV_RISCV_AIA_GRP_ADDR ,
2385
+ attr : u64:: from ( KVM_DEV_RISCV_AIA_ADDR_APLIC ) ,
2386
+ addr : & aplic_addr as * const u64 as u64 ,
2387
+ flags : 0 ,
2388
+ } )
2389
+ . unwrap ( ) ;
2390
+ let imsic_addr: u64 = 0x8000 ;
2391
+ vaia_fd
2392
+ . set_device_attr ( & kvm_device_attr {
2393
+ group : KVM_DEV_RISCV_AIA_GRP_ADDR ,
2394
+ attr : 1u64 ,
2395
+ addr : & imsic_addr as * const u64 as u64 ,
2396
+ flags : 0 ,
2397
+ } )
2398
+ . unwrap ( ) ;
2399
+
2400
+ // Initialize valid vAIA device.
2401
+ request_aia_init ( & vaia_fd) ;
2402
+
2403
+ vm_fd. register_irqfd ( & evtfd1, 4 ) . unwrap ( ) ;
2404
+ vm_fd. register_irqfd ( & evtfd2, 8 ) . unwrap ( ) ;
2405
+ vm_fd. register_irqfd ( & evtfd3, 4 ) . unwrap ( ) ;
2406
+ vm_fd. unregister_irqfd ( & evtfd2, 8 ) . unwrap ( ) ;
2407
+ // KVM irqfd doesn't report failure on this case:(
2408
+ vm_fd. unregister_irqfd ( & evtfd2, 8 ) . unwrap ( ) ;
2409
+
2410
+ // Duplicated eventfd registration.
2411
+ // On riscv64 this fails as the event fd was already matched with a GSI.
2412
+ vm_fd. register_irqfd ( & evtfd3, 4 ) . unwrap_err ( ) ;
2413
+ vm_fd. register_irqfd ( & evtfd3, 5 ) . unwrap_err ( ) ;
2414
+ // KVM irqfd doesn't report failure on this case:(
2415
+ vm_fd. unregister_irqfd ( & evtfd3, 5 ) . unwrap ( ) ;
2416
+ }
2417
+
2351
2418
#[ test]
2352
2419
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
2353
2420
fn test_set_irq_line ( ) {
@@ -2395,6 +2462,46 @@ mod tests {
2395
2462
vm_fd. set_irq_line ( 0x02_00_0010 , true ) . unwrap ( ) ;
2396
2463
}
2397
2464
2465
+ #[ test]
2466
+ #[ cfg( target_arch = "riscv64" ) ]
2467
+ fn test_set_irq_line ( ) {
2468
+ let kvm = Kvm :: new ( ) . unwrap ( ) ;
2469
+ let vm_fd = kvm. create_vm ( ) . unwrap ( ) ;
2470
+ vm_fd. create_vcpu ( 0 ) . unwrap ( ) ;
2471
+
2472
+ // Create the vAIA device.
2473
+ let vaia_fd = create_aia_device ( & vm_fd, 0 ) ;
2474
+ // Set maximum supported number of IRQs of the vAIA device to 128.
2475
+ set_supported_nr_irqs ( & vaia_fd, 128 ) ;
2476
+
2477
+ // Before request vAIA device to initialize, APLIC and IMSIC must be set
2478
+ let aplic_addr: u64 = 0x4000 ;
2479
+ vaia_fd
2480
+ . set_device_attr ( & kvm_device_attr {
2481
+ group : KVM_DEV_RISCV_AIA_GRP_ADDR ,
2482
+ attr : u64:: from ( KVM_DEV_RISCV_AIA_ADDR_APLIC ) ,
2483
+ addr : & aplic_addr as * const u64 as u64 ,
2484
+ flags : 0 ,
2485
+ } )
2486
+ . unwrap ( ) ;
2487
+ let imsic_addr: u64 = 0x8000 ;
2488
+ vaia_fd
2489
+ . set_device_attr ( & kvm_device_attr {
2490
+ group : KVM_DEV_RISCV_AIA_GRP_ADDR ,
2491
+ attr : 1u64 ,
2492
+ addr : & imsic_addr as * const u64 as u64 ,
2493
+ flags : 0 ,
2494
+ } )
2495
+ . unwrap ( ) ;
2496
+
2497
+ // Initialize valid vAIA device.
2498
+ request_aia_init ( & vaia_fd) ;
2499
+
2500
+ vm_fd. set_irq_line ( 7 , true ) . unwrap ( ) ;
2501
+ vm_fd. set_irq_line ( 7 , false ) . unwrap ( ) ;
2502
+ vm_fd. set_irq_line ( 7 , true ) . unwrap ( ) ;
2503
+ }
2504
+
2398
2505
#[ test]
2399
2506
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
2400
2507
fn test_faulty_vm_fd ( ) {
@@ -2515,7 +2622,8 @@ mod tests {
2515
2622
target_arch = "x86" ,
2516
2623
target_arch = "x86_64" ,
2517
2624
target_arch = "arm" ,
2518
- target_arch = "aarch64"
2625
+ target_arch = "aarch64" ,
2626
+ target_arch = "riscv64"
2519
2627
) ) ]
2520
2628
fn test_signal_msi_failure ( ) {
2521
2629
let kvm = Kvm :: new ( ) . unwrap ( ) ;
@@ -2564,7 +2672,8 @@ mod tests {
2564
2672
target_arch = "x86" ,
2565
2673
target_arch = "x86_64" ,
2566
2674
target_arch = "arm" ,
2567
- target_arch = "aarch64"
2675
+ target_arch = "aarch64" ,
2676
+ target_arch = "riscv64"
2568
2677
) ) ]
2569
2678
fn test_set_gsi_routing ( ) {
2570
2679
let kvm = Kvm :: new ( ) . unwrap ( ) ;
@@ -2575,6 +2684,9 @@ mod tests {
2575
2684
vm. set_gsi_routing ( & irq_routing) . unwrap_err ( ) ;
2576
2685
vm. create_irq_chip ( ) . unwrap ( ) ;
2577
2686
}
2687
+ // RISC-V 64-bit expect an AIA device to be created in advance of committing irq_routing table.
2688
+ #[ cfg( target_arch = "riscv64" ) ]
2689
+ create_aia_device ( & vm, 0 ) ;
2578
2690
let irq_routing = kvm_irq_routing:: default ( ) ;
2579
2691
vm. set_gsi_routing ( & irq_routing) . unwrap ( ) ;
2580
2692
}
0 commit comments