virtio-devices: Custom EpollHelper::run/VirtioCommon:reset for fuzz

It provides fuzzer a reliable way to wait for a sequence of events
to complete for virtio-devices while not using a fixed timeout to
maintain the full speed of fuzzing.

Take virtio-block as an example, the 'queue event' with a valid
available queue setup can trigger a 'completion event'. This is a
meaningful virtio-block code path of processing guest inputs which is
our target for fuzzing virtio devices.

Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
Bo Chen
2022-08-22 12:47:09 -07:00
committed by Bo Chen
parent 616ec530a8
commit a9924df2b8
2 changed files with 86 additions and 0 deletions

View File

@@ -280,6 +280,7 @@ impl VirtioCommon {
Ok(())
}
#[cfg(not(fuzzing))]
pub fn reset(&mut self) -> Option<Arc<dyn VirtioInterrupt>> {
// We first must resume the virtio thread if it was paused.
if self.pause_evt.take().is_some() {
@@ -303,6 +304,20 @@ impl VirtioCommon {
Some(self.interrupt_cb.take().unwrap())
}
#[cfg(fuzzing)]
// Wait for the worker thread to finish and return
pub fn reset(&mut self) -> Option<Arc<dyn VirtioInterrupt>> {
if let Some(mut threads) = self.epoll_threads.take() {
for t in threads.drain(..) {
if let Err(e) = t.join() {
error!("Error joining thread: {:?}", e);
}
}
}
None
}
pub fn dup_eventfds(&self) -> (EventFd, EventFd) {
(
self.kill_evt.as_ref().unwrap().try_clone().unwrap(),