From c274ce4d4922a19cd64a9fba63987707d5c5a23a Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 21 Apr 2022 10:12:56 +0100 Subject: [PATCH] virtio-devices: mem: Reject resize if device not activated by guest If the guest has not activated the virtio-mem device then reject an attempt to resize using it. Fixes: #4001 Signed-off-by: Rob Bradford --- virtio-devices/src/mem.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index cf7167651..3f5e6d7db 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -137,6 +137,8 @@ pub enum Error { DmaUnmap(std::io::Error), // Invalid DMA mapping handler InvalidDmaMappingHandler, + // Not activated by the guest + NotActivatedByGuest, } #[repr(C)] @@ -327,6 +329,7 @@ impl Request { pub struct ResizeSender { hotplugged_size: Arc, + activated: Arc, tx: mpsc::Sender>, evt: EventFd, } @@ -345,6 +348,7 @@ impl Clone for ResizeSender { fn clone(&self) -> Self { ResizeSender { hotplugged_size: self.hotplugged_size.clone(), + activated: self.activated.clone(), tx: self.tx.clone(), evt: self .evt @@ -356,6 +360,7 @@ impl Clone for ResizeSender { pub struct Resize { hotplugged_size: Arc, + activated: Arc, tx: mpsc::Sender>, rx: mpsc::Receiver>, evt: EventFd, @@ -367,6 +372,7 @@ impl Resize { Ok(Resize { hotplugged_size: Arc::new(AtomicU64::new(hotplugged_size)), + activated: Arc::new(AtomicBool::default()), tx, rx, evt: EventFd::new(EFD_NONBLOCK)?, @@ -376,12 +382,17 @@ impl Resize { pub fn new_resize_sender(&self) -> Result { Ok(ResizeSender { hotplugged_size: self.hotplugged_size.clone(), + activated: self.activated.clone(), tx: self.tx.clone(), evt: self.evt.try_clone().map_err(Error::EventFdTryCloneFail)?, }) } pub fn work(&self, desired_size: u64) -> Result<(), Error> { + if !self.activated.load(Ordering::Acquire) { + return Err(Error::NotActivatedByGuest); + } + self.hotplugged_size.store(desired_size, Ordering::Release); self.evt.write(1).map_err(Error::EventFdWriteFail)?; self.rx.recv().map_err(Error::MpscRecvFail)? @@ -1046,11 +1057,14 @@ impl VirtioDevice for Mem { )?; self.common.epoll_threads = Some(epoll_threads); + self.resize.activated.store(true, Ordering::Release); + event!("virtio-device", "activated", "id", &self.id); Ok(()) } fn reset(&mut self) -> Option> { + self.resize.activated.store(false, Ordering::Release); let result = self.common.reset(); event!("virtio-device", "reset", "id", &self.id); result