[Rust-VMM] RFC v2: propose to host memory-model crate under the rust-vm project

Florescu, Andreea fandree at amazon.com
Mon Feb 11 12:38:57 UTC 2019

Let's move this discussion to GitHub for easy tracking: https://github.com/rust-vmm/community/issues/16

Paolo, can you paste what you said on the issue?

From: Paolo Bonzini <pbonzini at redhat.com>
Sent: Monday, February 11, 2019 1:05 PM
To: Liu, Jiang; rust-vmm ML; Florescu, Andreea; Samuel Ortiz; Boeuf, Sebastien; Iordache, Alexandra; Dylan Reid; Dr. David Alan Gilbert; zachr at google.com
Subject: Re: [Rust-VMM] RFC v2: propose to host memory-model crate under the rust-vm project

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>
        F: FnOnce(&MemoryMapping, usize) -> Result<T>;

      fn do_in_region_partial<F>(&self, guest_addr: GuestAddress,
                                     cb: F) -> Result<usize>
        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

  // 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.


Amazon Development Center (Romania) S.R.L. registered office: 27A Sf. Lazar Street, UBC5, floor 2, Iasi, Iasi County, 700045, Romania. Registered in Romania. Registration number J22/2621/2005.

More information about the Rust-vmm mailing list