Conversation

Jarkko Sakkinen

So, in case you’ve ever wondered, this is how you map anonymous memory with vm-memory crate:

//! Copyright (c) Jarkko Sakkinen 2024

#![deny(clippy::all)]
#![deny(clippy::pedantic)]

use vm_memory::{GuestAddress, GuestMemoryMmap};

fn main() {
    let mem: GuestMemoryMmap<()> =
        GuestMemoryMmap::from_ranges(&[(GuestAddress(0u64), 8192usize)]).unwrap();
    println!("{:?}", mem);
}

The type parameter is for Bitmap.

I’ll do a small test program for each type of memory that we need in Enarx and after that make the changes to the project itself. Changes are simple but the code base is large so this is fastest way to formalize a decent patch.

So next step is /dev/kvm test.

#rust #rustlang #mmap #kvm

1
1
0

Output:

~/work/local/hello-vm-memory master* 7m 13s
❯ target/debug/hello-vm-memory                    
GuestMemoryMmap { regions: [GuestRegionMmap { mapping: MmapRegion { addr: 0x7f593adbf000, size: 8192, bitmap: (), file_offset: None, prot: 3, flags: 16418, owned: true, hugetlbfs: None }, guest_base: GuestAddress(0) }] }
1
0
0

Turns out that vm-memory is WRONG crate for arbitrary mappings. E.g. it does not allows arbitray permissions for anonymous mappings. Instead mmap-rs is probably better idea:

// SPDX-License-Identifier: MIT
//! Copyright (c) Jarkko Sakkinen 2024

#![deny(clippy::all)]
#![deny(clippy::pedantic)]

use mmap::MemoryMap;

fn main() {
    let mem = MemoryMap::new(0x2000, &[
        mmap::MapOption::MapReadable,
        mmap::MapOption::MapWritable,
        mmap::MapOption::MapExecutable,
    ]).unwrap_or_else(|_| std::process::exit(1));
    println!("{}", mem.len());
}

MapOption contains fields for file and similar stuff too.

2
0
0

@jarkko note that memmap is [unmaintained](https://rustsec.org/advisories/RUSTSEC-2020-0077.html) you almost certainly want memmap2

1
0
1
@Dr_Emann This is exactly why I experiment with these test programs before making any enarx changes ;-) Thanks for the tip.

I still have to play also with vm-memory too...
1
0
0

Jarkko Sakkinen

Edited 4 months ago

@Dr_Emann Not fully yet understanding capabilities of vm-memory but enarx has two kinds of mappings:

  1. Actual mmaps. For these there was trait called Map but cannot recall what was the internal crate called.
  2. “Fake” mmaps inside e.g. SGX enclave just for markup with https://github.com/enarx/mmledger

So I’m looking into if I could extend vm-memory to provide the latter so then host/guest mmaps would have same parameters and two internal crates could be removed.

So lot’s of experimentation to do before it make sense to do anything for the actual project. If this draft of an idea would be possible with vm-memory, it would make doing the task whole a lot more feasible.

@rjzak

0
0
0
@hjvt Any input is welcome most welcome because memory management (in the sense of mapping it) is not the strong point of Rust's stdlib.

I just do bunch of test programs and that will hopefully converge to choice ;-)

Way test these is that I git grep just our call sites in Enarx and then make lowest-common denominator hello world out of it...

Thank you!
1
0
0

Jarkko Sakkinen

Edited 4 months ago
@hjvt I found proper memory mapping primitives from vm-memory, they are just under "xen" feature flag, e.g. https://docs.rs/vm-memory/latest/vm_memory/mmap/struct.MmapRange.html.

I don't get the reason for "xen-only" but the API is reasonable and quick skim to source seems to give same impression.

So I see where that leads me. If possible I'd prefer vm-memory most only because of its volume. I.e. most likely to stay alive and maintained.
1
0
0