@@ -16,12 +16,14 @@ use vm_device::{DeviceMmio, MutDeviceMmio};
1616use vm_memory:: { GuestAddressSpace , GuestMemoryMmap } ;
1717
1818use crate :: virtio:: block:: { BLOCK_DEVICE_ID , VIRTIO_BLK_F_RO } ;
19- use crate :: virtio:: { CommonConfig , Env , SingleFdSignalQueue , QUEUE_MAX_SIZE } ;
19+ use crate :: virtio:: { CommonConfig , Env , IrqTrigger , SingleFdSignalQueue , QUEUE_MAX_SIZE } ;
2020
2121use super :: inorder_handler:: InOrderQueueHandler ;
2222use super :: queue_handler:: QueueHandler ;
2323use super :: { build_config_space, BlockArgs , Error , Result } ;
2424
25+ use crate :: intc:: APlicTrigger ;
26+
2527// This Block device can only use the MMIO transport for now, but we plan to reuse large parts of
2628// the functionality when we implement virtio PCI as well, for example by having a base generic
2729// type, and then separate concrete instantiations for `MmioConfig` and `PciConfig`.
@@ -33,6 +35,7 @@ pub struct Block<M: GuestAddressSpace + Clone + Send + 'static> {
3335 // the outside.
3436 _root_device : bool ,
3537 mem : Arc < GuestMemoryMmap > ,
38+ aplic_trigger : Option < APlicTrigger > ,
3639}
3740
3841impl < M : GuestAddressSpace + Clone + Send + Sync + ' static > Block < M > {
@@ -41,6 +44,7 @@ impl<M: GuestAddressSpace + Clone + Send + Sync + 'static> Block<M> {
4144 mem : Arc < GuestMemoryMmap > ,
4245 env : & mut Env < M , B > ,
4346 args : & BlockArgs ,
47+ aplic_trigger : Option < APlicTrigger > ,
4448 ) -> Result < Self > {
4549 let device_features = args. device_features ( ) ;
4650
@@ -57,6 +61,7 @@ impl<M: GuestAddressSpace + Clone + Send + Sync + 'static> Block<M> {
5761 file_path : args. file_path . clone ( ) ,
5862 read_only : args. read_only ,
5963 _root_device : args. root_device ,
64+ aplic_trigger,
6065 } )
6166 }
6267
@@ -66,14 +71,20 @@ impl<M: GuestAddressSpace + Clone + Send + Sync + 'static> Block<M> {
6671 mem : Arc < GuestMemoryMmap > ,
6772 env : & mut Env < M , B > ,
6873 args : & BlockArgs ,
74+ aplic_trigger : Option < APlicTrigger > ,
6975 ) -> Result < Arc < Mutex < Self > > >
7076 where
7177 // We're using this (more convoluted) bound so we can pass both references and smart
7278 // pointers such as mutex guards here.
7379 B : DerefMut ,
7480 B :: Target : MmioManager < D = Arc < dyn DeviceMmio + Send + Sync > > ,
7581 {
76- let block = Arc :: new ( Mutex :: new ( Self :: create_block ( mem, env, args) ?) ) ;
82+ let block = Arc :: new ( Mutex :: new ( Self :: create_block (
83+ mem,
84+ env,
85+ args,
86+ aplic_trigger,
87+ ) ?) ) ;
7788
7889 // Register the device on the MMIO bus.
7990 env. register_mmio_device ( block. clone ( ) )
@@ -123,9 +134,14 @@ impl<M: GuestAddressSpace + Clone + Send + 'static> VirtioDeviceActions for Bloc
123134
124135 // TODO: Create the backend earlier (as part of `Block::new`)?
125136 let disk = StdIoBackend :: new ( file, features) . map_err ( Error :: Backend ) ?;
137+ let irq_trigger = if cfg ! ( target_arch = "riscv64" ) {
138+ IrqTrigger :: APlicTrigger ( Some ( self . aplic_trigger . clone ( ) . unwrap ( ) ) )
139+ } else {
140+ IrqTrigger :: IrqFd ( self . cfg . irqfd . clone ( ) )
141+ } ;
126142
127143 let driver_notify = SingleFdSignalQueue {
128- irqfd : self . cfg . irqfd . clone ( ) ,
144+ irq_trigger ,
129145 interrupt_status : self . cfg . virtio . interrupt_status . clone ( ) ,
130146 } ;
131147
@@ -185,7 +201,16 @@ mod tests {
185201 advertise_flush : true ,
186202 } ;
187203
188- let block_mutex = Block :: new ( env. mem . clone ( ) , & mut env, & args) . unwrap ( ) ;
204+ let aplic_trigger = if cfg ! ( target_arch = "riscv64" ) {
205+ Some ( APlicTrigger {
206+ gsi : 5 ,
207+ vm : env. vm_fd . clone ( ) ,
208+ } )
209+ } else {
210+ None
211+ } ;
212+
213+ let block_mutex = Block :: new ( env. mem . clone ( ) , & mut env, & args, aplic_trigger) . unwrap ( ) ;
189214 let block = block_mutex. lock ( ) . unwrap ( ) ;
190215
191216 assert_eq ! ( block. device_type( ) , BLOCK_DEVICE_ID ) ;
0 commit comments