[Rust-VMM] RFC v2: propose to host memory-model crate under the rust-vm project
Paolo Bonzini
pbonzini at redhat.com
Mon Feb 11 11:05:39 UTC 2019
On 10/02/19 07:00, Liu, Jiang wrote:
> Hi all,
> I have posted the first version of memory-model crate under
> rust-vmm/memory-model, which breaks the repository inclusion process of
> the rust-vmm community. So I have created a personal GitHub repository
> (https://github.com/jiangliu/memory-model) for v2 and the
> rust-vmm/memory-model repository will be deleted soon. Sorry for the
> inconvenience!
A memory model crate is certainly a very good starting point for
rust-vmm, but it shouldn't include the implementation of the backend.
Instead, for rust-vmm we should focus on defining common traits that can
be used by any VMM.
In this light, GuestMemory is composed of two parts:
- a way to convert a GuestAddress to a MemoryMapping and an offset,
which can be a very simple MemoryMap trait:
pub trait MemoryMap {
fn do_in_region<F, T>(&self, guest_addr: GuestAddress,
size: usize, cb: F) -> Result<T>
where
F: FnOnce(&MemoryMapping, usize) -> Result<T>;
fn do_in_region_partial<F>(&self, guest_addr: GuestAddress,
cb: F) -> Result<usize>
where
F: FnOnce(&MemoryMapping, usize) -> Result<usize>;
}
This can be implemented with linear lookup as is currently the case in
firecracker, or it could use a binary search or a radix tree. rust-vmm
shouldn't care.
- the convenience API to access memory as slices/streams/objects. This
part of the API is shared by MemoryMapping and GuestMemory:
// From MemoryMapping
pub fn read_to_memory<F>(&self, mem_offset: usize, src: &mut F,
count: usize) -> Result<()>
where F: Read;
// From GuestMemory
pub fn read_to_memory<F>(&self, guest_addr: GuestAddress,
src: &mut F, count: usize) -> Result<()>
where F: Read;
sometimes with different names:
// From MemoryMapping
pub fn write_slice(&self, buf: &[u8], offset: usize) -> Result<usize>;
pub fn read_obj<T: DataInit>(&self, offset: usize) -> Result<T>;
// From GuestMemory
pub fn write_slice_at_addr(&self, buf: &[u8], guest_addr: GuestAddress)
-> Result<usize>;
pub fn read_obj_from_addr<T: DataInit>(&self, guest_addr: GuestAddress)
-> Result<T>;
and should be a separate trait.
For example if we call it Bytes, MemoryMapping would implement
Bytes<usize> for MemoryMapping and GuestMemory would implement
Bytes<GuestAddress>:
// O for offset
pub trait Bytes<O> {
type Error;
fn read_to_memory<F>(&self, offset: O, src: &mut F,
count: usize) -> Result<(), Self::Error>
where F: Read;
fn read_obj<T: DataInit>(&self, offset: O) -> Result<T, Self::Error>;
...
fn read_slice(&self, buf: &[u8], mem_offset: O) ->
Result<usize, Self::Error>;
..
}
endian.rs should be part of this crate too, so that you can write
let x: LE<u32> = mem.read_obj(ofs);
AddressSpace is also too specialized and I would leave it out completely
from the time being, while GuestMemory and MemoryMapping could be
provided in a separate crate ("rust-vmm-examples"?) as a reference
implementation of the traits.
No objections from me of course on other parts of the crate, for example
VolatileMemory or DataInit.
Thanks,
More information about the Rust-vmm
mailing list