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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-09-24 11:44:40 +02:00 committed by Bo Chen
parent e390775bcb
commit 0fb24ea3ae

View File

@ -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();