On Tue, May 20, 2025 at 07:48:11PM +0200, Paolo Bonzini wrote:
> Date: Tue, 20 May 2025 19:48:11 +0200
> From: Paolo Bonzini <bonz...@gnu.org>
> Subject: Re: Rust in QEMU update, April 2025
> 
> 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>;

This is indeed exactly what I meet now. GuestMemory and QEMU's design don't
macth well! I've learned from the lessons of failure that MemoryRegion is
different from GuestMemoryRegion. Thank you for pointing the direction and
helping me decide to switch to FlatView.

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

I also realize that once FlatRange/FlatView is associated with 
GuestMemoryRegion/
GuestMemory, it changes the usual practice in QEMU, where most memory operations
are built around MemoryRegion/AddressSpace.

But that's okay because what users aware is the vm-memory interface.

> 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!

Yes, there will be many gaps.

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

Yes, the bitmap is also a problem for me, and I also haven't figured out
how to align it with rust-vmm. In fact, in the code (that currently doesn't
run), I indeed used `()`. :-(

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

Is it possible or necessary for vm-memory to support overlap? Because I
feel that if it is possible, the problem might be simplified. (As a
beginner, I have yet to understand exactly how difficult it is.)

Thanks,
Zhao


Reply via email to