diff --git a/pci/src/vfio_user.rs b/pci/src/vfio_user.rs index 104691030..56b48ac2f 100644 --- a/pci/src/vfio_user.rs +++ b/pci/src/vfio_user.rs @@ -326,17 +326,33 @@ impl Vfio for VfioUserClientWrapper { ); let fds: Vec = event_fds.iter().map(|e| e.as_raw_fd()).collect(); - self.client - .lock() - .unwrap() - .set_irqs( - irq_index, - VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, - 0, - event_fds.len() as u32, - &fds, - ) - .map_err(VfioError::VfioUser) + // Batch into blocks of 16 fds as sendmsg() has a size limit + let mut sent_fds = 0; + let num_fds = event_fds.len() as u32; + while sent_fds < num_fds { + let remaining_fds = num_fds - sent_fds; + let count = if remaining_fds > 16 { + 16 + } else { + remaining_fds + }; + + self.client + .lock() + .unwrap() + .set_irqs( + irq_index, + VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, + sent_fds, + count, + &fds[sent_fds as usize..(sent_fds + count) as usize], + ) + .map_err(VfioError::VfioUser)?; + + sent_fds += count; + } + + Ok(()) } fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> {