mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-22 04:25:21 +00:00
virtio-devices: mem: Allow for an initial size
This commit gives the possibility to create a virtio-mem device with some memory already plugged into it. This is preliminary work to be able to reboot a VM with the virtio-mem region being already resized. Signed-off-by: Hui Zhu <teawater@antfin.com> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
8b5202aa5a
commit
33a1e37c35
@ -185,6 +185,36 @@ struct VirtioMemConfig {
|
||||
// Safe because it only has data and has no implicit padding.
|
||||
unsafe impl ByteValued for VirtioMemConfig {}
|
||||
|
||||
fn virtio_mem_config_resize(config: &mut VirtioMemConfig, size: u64) -> result::Result<(), Error> {
|
||||
if config.requested_size == size {
|
||||
return Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is same with current config.requested_size",
|
||||
size
|
||||
)));
|
||||
} else if size > config.region_size {
|
||||
let region_size = config.region_size;
|
||||
return Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is bigger than config.region_size {}",
|
||||
size, region_size
|
||||
)));
|
||||
} else if size % (config.block_size as u64) != 0 {
|
||||
let block_size = config.block_size;
|
||||
return Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is not aligned with config.block_size {}",
|
||||
size, block_size
|
||||
)));
|
||||
}
|
||||
|
||||
config.requested_size = size;
|
||||
let tmp_size = cmp::min(
|
||||
config.region_size,
|
||||
config.requested_size + VIRTIO_MEM_USABLE_EXTENT,
|
||||
);
|
||||
config.usable_region_size = cmp::max(config.usable_region_size, tmp_size);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct Request {
|
||||
req: VirtioMemReq,
|
||||
status_addr: GuestAddress,
|
||||
@ -622,37 +652,16 @@ impl EpollHelperHandler for MemEpollHandler {
|
||||
let size = self.resize.get_size();
|
||||
let mut config = self.config.lock().unwrap();
|
||||
let mut signal_error = false;
|
||||
let r = if config.requested_size == size {
|
||||
Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is same with current config.requested_size",
|
||||
size
|
||||
)))
|
||||
} else if size > config.region_size {
|
||||
let region_size = config.region_size;
|
||||
Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is bigger than config.region_size {}",
|
||||
size, region_size
|
||||
)))
|
||||
} else if size % (config.block_size as u64) != 0 {
|
||||
let block_size = config.block_size;
|
||||
Err(Error::ResizeInval(format!(
|
||||
"Virtio-mem resize {} is not aligned with config.block_size {}",
|
||||
size, block_size
|
||||
)))
|
||||
} else {
|
||||
config.requested_size = size;
|
||||
let tmp_size = cmp::min(
|
||||
config.region_size,
|
||||
config.requested_size + VIRTIO_MEM_USABLE_EXTENT,
|
||||
);
|
||||
config.usable_region_size = cmp::max(config.usable_region_size, tmp_size);
|
||||
if let Err(e) = self.signal(&VirtioInterruptType::Config) {
|
||||
signal_error = true;
|
||||
error!("Error signalling config: {:?}", e);
|
||||
Err(Error::ResizeTriggerFail(e))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
let mut r = virtio_mem_config_resize(&mut config, size);
|
||||
r = match r {
|
||||
Err(e) => Err(e),
|
||||
_ => match self.signal(&VirtioInterruptType::Config) {
|
||||
Err(e) => {
|
||||
signal_error = true;
|
||||
Err(Error::ResizeTriggerFail(e))
|
||||
}
|
||||
_ => Ok(()),
|
||||
},
|
||||
};
|
||||
if let Err(e) = self.resize.send(r) {
|
||||
error!("Sending \"resize\" reponse: {:?}", e);
|
||||
@ -702,6 +711,7 @@ impl Mem {
|
||||
resize: Resize,
|
||||
seccomp_action: SeccompAction,
|
||||
numa_node_id: Option<u16>,
|
||||
initial_size: u64,
|
||||
) -> io::Result<Mem> {
|
||||
let region_len = region.len();
|
||||
|
||||
@ -726,6 +736,15 @@ impl Mem {
|
||||
config.requested_size + VIRTIO_MEM_USABLE_EXTENT,
|
||||
);
|
||||
|
||||
if initial_size != 0 {
|
||||
virtio_mem_config_resize(&mut config, initial_size).map_err(|e| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Virtio-mem resize {} got {:?}", initial_size, e),
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
if let Some(node_id) = numa_node_id {
|
||||
avail_features |= 1u64 << VIRTIO_MEM_F_ACPI_PXM;
|
||||
config.node_id = node_id;
|
||||
|
@ -2451,6 +2451,7 @@ impl DeviceManager {
|
||||
.map_err(DeviceManagerError::TryCloneVirtioMemResize)?,
|
||||
self.seccomp_action.clone(),
|
||||
node_id,
|
||||
0,
|
||||
)
|
||||
.map_err(DeviceManagerError::CreateVirtioMem)?,
|
||||
));
|
||||
|
Loading…
x
Reference in New Issue
Block a user