On 5/20/25 18:23, Zhao Liu wrote:
HPET does some very simple memory accesses; a good safe solution
for this may be the ``vm-memory`` crate.  While I have not looked into
using it, ``vm-memory`` and ``vm-virtio`` were written with QEMU's
use cases in mind.
I'm working on this and trying to wrap simple memory access by
vm-memory.

Ok. Note that while the GuestAddressSpace corresponds QEMU's AddressSpace (so far so good :)), QEMU's MemoryRegion is completely unrelated to vm-memory's GuestMemoryRegion. That's because vm-memory only operates on an array of non-overlapping regions, like QEMU's FlatRange or MemoryRegionSection structs.


The GuestMemory (GuestAddressSpace::M) corresponds to QEMU's FlatView. Indeed the functions in the trait match with what you expect of a FlatView:

    fn num_regions(&self) -> usize;
    fn find_region(&self, addr: GuestAddress) -> Option<&Self::R>;
    fn iter(&self) -> impl Iterator<Item = &Self::R>;

If the GuestMemory is a FlatView, the GuestAddressSpace::T, implements Clone + Deref<Target = FlatView>. It's not too hard to see that GuestAddressSpace's memory() method must call address_space_get_flatview() and the GuestAddressSpace::T's drop method must call flatview_unref(). Let's call this (Rust-specific) struct FlatViewRefGuard, or something like that.


Going back to the GuestMemoryRegion (<FlatView as GuestMemory>::R), it could be either a QEMU FlatRange or a MemoryRegionSection. Neither are good options. Without a MemoryRegionSection you can't support IOMMU regions; but flatview_do_translate() returns the MemoryRegionSection by value, and GuestMemory's

    fn find_region(&self, addr: GuestAddress) -> Option<&Self::R>;

wants a reference instead!

Anyhow, all three types (AddressSpace, FlatView, FlatRange) are better wrapped with Opaque.

Looking more at FlatRange, these are easy:

    // Required methods
    fn len(&self) -> GuestUsize;
    fn start_addr(&self) -> GuestAddress;

But this one is another problem:

    fn bitmap(&self) -> &Self::B;

because it returns the "Bitmap" by reference. QEMU's bitmap is a global variable indexed by ram_addr_t. It would be better if this was declared like this:

   fn bitmap(&'a self) ->
      <Self::B as WithBitmapSlice<'a>>::S

I have no idea if this can be changed in upstream vm-virtio. For now maybe you can leave it as (). That's buggy but it's ok for a proof of concept.

So... not sure what to do there. It seems like vm-memory is very close to being usable by QEMU, but maybe not completely. :(

Paolo

Reply via email to