diff options
author | Dylan Reid <dgreid@chromium.org> | 2017-12-06 18:20:09 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-01-02 23:36:26 -0800 |
commit | d44320488fd2db344b6b1fd156c22fdf90b82fe2 (patch) | |
tree | 1ee593b0efa66a7f5dff11f47df98bc307598fd6 /vm_control/src | |
parent | 4aa86930edecf6b7842b9403dbea153ba8101e00 (diff) | |
download | crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar.gz crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar.bz2 crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar.lz crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar.xz crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.tar.zst crosvm-d44320488fd2db344b6b1fd156c22fdf90b82fe2.zip |
main: Add inflate/deflate interface for balloon
Change-Id: I0fc63abbed8db303c7d283ce392fd47777b60d19 Reviewed-on: https://chromium-review.googlesource.com/818207 Commit-Ready: Dylan Reid <dgreid@chromium.org> Tested-by: Dylan Reid <dgreid@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'vm_control/src')
-rw-r--r-- | vm_control/src/lib.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/vm_control/src/lib.rs b/vm_control/src/lib.rs index cf40569..d486081 100644 --- a/vm_control/src/lib.rs +++ b/vm_control/src/lib.rs @@ -10,6 +10,7 @@ //! The wire message format is a little-endian C-struct of fixed size, along with a file descriptor //! if the request type expects one. +extern crate byteorder; extern crate data_model; extern crate kvm; extern crate libc; @@ -22,6 +23,7 @@ use std::result; use libc::{ERANGE, EINVAL}; +use byteorder::{LittleEndian, WriteBytesExt}; use data_model::{DataInit, Le32, Le64, VolatileMemory}; use sys_util::{EventFd, Error as SysError, MmapError, MemoryMapping, Scm, GuestAddress}; use kvm::{IoeventAddress, Vm}; @@ -65,6 +67,8 @@ impl AsRawFd for MaybeOwnedFd { /// /// Unless otherwise noted, each request should expect a `VmResponse::Ok` to be received on success. pub enum VmRequest { + /// Try to grow or shrink the VM's balloon. + BalloonAdjust(i32), /// Break the VM's run loop and exit. Exit, /// Register the given ioevent address along with given datamatch to trigger the `EventFd`. @@ -81,7 +85,8 @@ pub enum VmRequest { const VM_REQUEST_TYPE_EXIT: u32 = 1; const VM_REQUEST_TYPE_REGISTER_MEMORY: u32 = 2; const VM_REQUEST_TYPE_UNREGISTER_MEMORY: u32 = 3; -const VM_REQUEST_SIZE: usize = 16; +const VM_REQUEST_TYPE_BALLOON_ADJUST: u32 = 4; +const VM_REQUEST_SIZE: usize = 24; #[repr(C)] #[derive(Clone, Copy, Default)] @@ -89,6 +94,7 @@ struct VmRequestStruct { type_: Le32, slot: Le32, size: Le64, + num_pages: Le32, } // Safe because it only has data and has no implicit padding. @@ -99,6 +105,7 @@ impl VmRequest { /// /// A `VmResponse` should be sent out over the given socket before another request is received. pub fn recv(scm: &mut Scm, s: &UnixDatagram) -> VmControlResult<VmRequest> { + assert_eq!(VM_REQUEST_SIZE, std::mem::size_of::<VmRequestStruct>()); let mut buf = [0; VM_REQUEST_SIZE]; let mut fds = Vec::new(); let read = scm.recv(s, &mut [&mut buf], &mut fds) @@ -118,6 +125,9 @@ impl VmRequest { req.size.to_native() as usize)) } VM_REQUEST_TYPE_UNREGISTER_MEMORY => Ok(VmRequest::UnregisterMemory(req.slot.into())), + VM_REQUEST_TYPE_BALLOON_ADJUST => { + Ok(VmRequest::BalloonAdjust(req.num_pages.to_native() as i32)) + }, _ => Err(VmControlError::InvalidType), } } @@ -127,6 +137,7 @@ impl VmRequest { /// After this request is a sent, a `VmResponse` should be received before sending another /// request. pub fn send(&self, scm: &mut Scm, s: &UnixDatagram) -> VmControlResult<()> { + assert_eq!(VM_REQUEST_SIZE, std::mem::size_of::<VmRequestStruct>()); let mut req = VmRequestStruct::default(); let mut fd_buf = [0; 1]; let mut fd_len = 0; @@ -142,6 +153,10 @@ impl VmRequest { req.type_ = Le32::from(VM_REQUEST_TYPE_UNREGISTER_MEMORY); req.slot = Le32::from(slot); } + &VmRequest::BalloonAdjust(pages) => { + req.type_ = Le32::from(VM_REQUEST_TYPE_BALLOON_ADJUST); + req.num_pages = Le32::from(pages as u32); + }, _ => return Err(VmControlError::InvalidType), } let mut buf = [0; VM_REQUEST_SIZE]; @@ -162,7 +177,8 @@ impl VmRequest { /// This does not return a result, instead encapsulating the success or failure in a /// `VmResponse` with the intended purpose of sending the response back over the socket that /// received this `VmRequest`. - pub fn execute(&self, vm: &mut Vm, next_mem_pfn: &mut u64, running: &mut bool) -> VmResponse { + pub fn execute(&self, vm: &mut Vm, next_mem_pfn: &mut u64, running: &mut bool, + balloon_host_socket: &UnixDatagram) -> VmResponse { *running = true; match self { &VmRequest::Exit => { @@ -209,6 +225,15 @@ impl VmRequest { Err(e) => VmResponse::Err(e), } } + &VmRequest::BalloonAdjust(num_pages) => { + let mut buf = [0u8; 4]; + // write_i32 can't fail as the buffer is 4 bytes long. + (&mut buf[0..]).write_i32::<LittleEndian>(num_pages).unwrap(); + match balloon_host_socket.send(&buf) { + Ok(_) => VmResponse::Ok, + Err(_) => VmResponse::Err(SysError::last()), + } + }, } } } |