From 0fb24ea3ae50344382c7330dcfa0c0bb4d51ff32 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Fri, 24 Sep 2021 11:44:40 +0200 Subject: [PATCH] virtio-devices: mem: Discard unplugged ranges only on activate() In order to support correctly the snapshot/restore and migration use cases, we must be careful with the ranges that we discard by punching holes. On restore, there might be some ranges already plugged in, meaning they should not be discarded. That's why we loop over the list of blocks to discard only the ranges that are marked as unplugged. Signed-off-by: Sebastien Boeuf --- virtio-devices/src/mem.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index 7ef5f6885..f59b67a3a 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -997,7 +997,6 @@ impl VirtioDevice for Mem { ) -> ActivateResult { self.common.activate(&queues, &queue_evts, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); - let config = self.config.lock().unwrap(); let mut handler = MemEpollHandler { host_addr: self.host_addr, host_fd: self.host_fd, @@ -1014,12 +1013,20 @@ impl VirtioDevice for Mem { dma_mapping_handlers: Arc::clone(&self.dma_mapping_handlers), }; - handler - .discard_memory_range(0, config.region_size) - .map_err(|e| { - error!("failed discarding memory range: {:?}", e); - ActivateError::BadActivate - })?; + let unplugged_memory_ranges = self.blocks_state.lock().unwrap().memory_ranges(0, false); + for range in unplugged_memory_ranges.regions() { + handler + .discard_memory_range(range.gpa, range.length) + .map_err(|e| { + error!( + "failed discarding memory range [0x{:x}-0x{:x}]: {:?}", + range.gpa, + range.gpa + range.length - 1, + e + ); + ActivateError::BadActivate + })?; + } let paused = self.common.paused.clone(); let paused_sync = self.common.paused_sync.clone();