[RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend

Zhao Liu posted 26 patches 4 months, 1 week ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Peter Xu <peterx@redhat.com>, David Hildenbrand <david@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Manos Pitsidianakis <manos.pitsidianakis@linaro.org>, "Alex Bennée" <alex.bennee@linaro.org>, Thomas Huth <thuth@redhat.com>
[RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend
Posted by Zhao Liu 4 months, 1 week ago
Add 2 patches to support QEMU memory backend implementation.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 .../packagefiles/vm-memory-0.16-rs/0001.diff  |  81 +++++++++++++
 .../packagefiles/vm-memory-0.16-rs/0002.diff  | 111 ++++++++++++++++++
 subprojects/vm-memory-0.16-rs.wrap            |   2 +
 3 files changed, 194 insertions(+)
 create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
 create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0002.diff

diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
new file mode 100644
index 000000000000..037193108d45
--- /dev/null
+++ b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
@@ -0,0 +1,81 @@
+From 298f8ba019b2fe159fa943e0ae4dfd3c83ee64e0 Mon Sep 17 00:00:00 2001
+From: Zhao Liu <zhao1.liu@intel.com>
+Date: Wed, 6 Aug 2025 11:31:11 +0800
+Subject: [PATCH 1/2] guest_memory: Add a marker tarit to implement
+ Bytes<GuestAddress> for GuestMemory
+
+At present, Bytes<GuestAddress> is implemented as the blanet trait for
+all types which implemented GuestMemory.
+
+QEMU needs to customize its own Bytes<GuestAddress> implementation.
+
+So add a marker trait to still provide the default implementation for
+GuestRegionCollection and GuestMemoryMmap, and QEMU could have its own
+implementation.
+
+Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
+---
+ src/guest_memory.rs | 8 +++++++-
+ src/lib.rs          | 2 +-
+ src/region.rs       | 6 ++++--
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/guest_memory.rs b/src/guest_memory.rs
+index 39e4f10a89d6..5b78038c3c92 100644
+--- a/src/guest_memory.rs
++++ b/src/guest_memory.rs
+@@ -457,7 +457,13 @@ pub trait GuestMemory {
+     }
+ }
+ 
+-impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
++/// A marker trait that if implemented on a type `M` makes available a default
++/// implementation of `Bytes<GuestAddress>` for `M`, based on the assumption
++/// that the entire `GuestMemory` is just traditional Guest memory abstraction
++/// without any special access requirements.
++pub trait GuestMemoryBytes: GuestMemory {}
++
++impl<M: GuestMemoryBytes + ?Sized> Bytes<GuestAddress> for M {
+     type E = Error;
+ 
+     fn write(&self, buf: &[u8], addr: GuestAddress) -> Result<usize> {
+diff --git a/src/lib.rs b/src/lib.rs
+index 2f87f4c8482f..64ed3ec27a36 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -47,7 +47,7 @@ pub use endian::{Be16, Be32, Be64, BeSize, Le16, Le32, Le64, LeSize};
+ pub mod guest_memory;
+ pub use guest_memory::{
+     Error as GuestMemoryError, FileOffset, GuestAddress, GuestAddressSpace, GuestMemory,
+-    GuestUsize, MemoryRegionAddress, Result as GuestMemoryResult,
++    GuestMemoryBytes, GuestUsize, MemoryRegionAddress, Result as GuestMemoryResult,
+ };
+ 
+ pub mod region;
+diff --git a/src/region.rs b/src/region.rs
+index e716a6290e75..7114dfbe15a7 100644
+--- a/src/region.rs
++++ b/src/region.rs
+@@ -3,8 +3,8 @@
+ use crate::bitmap::{Bitmap, BS};
+ use crate::guest_memory::Result;
+ use crate::{
+-    Address, AtomicAccess, Bytes, FileOffset, GuestAddress, GuestMemory, GuestMemoryError,
+-    GuestUsize, MemoryRegionAddress, ReadVolatile, VolatileSlice, WriteVolatile,
++    Address, AtomicAccess, Bytes, FileOffset, GuestAddress, GuestMemory, GuestMemoryBytes,
++    GuestMemoryError, GuestUsize, MemoryRegionAddress, ReadVolatile, VolatileSlice, WriteVolatile,
+ };
+ use std::sync::atomic::Ordering;
+ use std::sync::Arc;
+@@ -322,6 +322,8 @@ impl<R: GuestMemoryRegion> GuestMemory for GuestRegionCollection<R> {
+     }
+ }
+ 
++impl<R: GuestMemoryRegion> GuestMemoryBytes for GuestRegionCollection<R> {}
++
+ /// A marker trait that if implemented on a type `R` makes available a default
+ /// implementation of `Bytes<MemoryRegionAddress>` for `R`, based on the assumption
+ /// that the entire `GuestMemoryRegion` is just traditional memory without any
+-- 
+2.34.1
+
diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0002.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
new file mode 100644
index 000000000000..bfef1bf1fee3
--- /dev/null
+++ b/subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
@@ -0,0 +1,111 @@
+From 2af7ea12a589fde619690e5060c01710cb6f2e0e Mon Sep 17 00:00:00 2001
+From: Zhao Liu <zhao1.liu@intel.com>
+Date: Wed, 6 Aug 2025 14:27:14 +0800
+Subject: [PATCH 2/2] guest_memory: Add is_write argument for
+ GuestMemory::try_access()
+
+QEMU needs to know whether the memory access is for write or not, e.g.,
+memory region may be read-only, or iommu needs to distinguish write
+access.
+
+The alternative option is to move try_access() into Bytes trait, and
+implement Bytes<(GuestAddress, is_write)> for QEMU's GuestMemory
+abstraction. However, try_access() seems to lack generality in the
+abstraction of Bytes, as only GuestMemory needs it.
+
+Therefore, just add another argument in try_access() to help handle
+more complex memory backend.
+
+Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
+---
+ src/bitmap/mod.rs   | 17 +++++++++++------
+ src/guest_memory.rs | 10 ++++++----
+ 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/src/bitmap/mod.rs b/src/bitmap/mod.rs
+index cf1555b29350..de4203166304 100644
+--- a/src/bitmap/mod.rs
++++ b/src/bitmap/mod.rs
+@@ -287,12 +287,17 @@ pub(crate) mod tests {
+         // Finally, let's invoke the generic tests for `Bytes`.
+         let check_range_closure = |m: &M, start: usize, len: usize, clean: bool| -> bool {
+             let mut check_result = true;
+-            m.try_access(len, GuestAddress(start as u64), |_, size, reg_addr, reg| {
+-                if !check_range(&reg.bitmap(), reg_addr.0 as usize, size, clean) {
+-                    check_result = false;
+-                }
+-                Ok(size)
+-            })
++            m.try_access(
++                len,
++                GuestAddress(start as u64),
++                false,
++                |_, size, reg_addr, reg| {
++                    if !check_range(&reg.bitmap(), reg_addr.0 as usize, size, clean) {
++                        check_result = false;
++                    }
++                    Ok(size)
++                },
++            )
+             .unwrap();
+ 
+             check_result
+diff --git a/src/guest_memory.rs b/src/guest_memory.rs
+index 5b78038c3c92..53981c4e8e94 100644
+--- a/src/guest_memory.rs
++++ b/src/guest_memory.rs
+@@ -353,7 +353,7 @@ pub trait GuestMemory {
+ 
+     /// Check whether the range [base, base + len) is valid.
+     fn check_range(&self, base: GuestAddress, len: usize) -> bool {
+-        match self.try_access(len, base, |_, count, _, _| -> Result<usize> { Ok(count) }) {
++        match self.try_access(len, base, false, |_, count, _, _| -> Result<usize> { Ok(count) }) {
+             Ok(count) => count == len,
+             _ => false,
+         }
+@@ -374,7 +374,7 @@ pub trait GuestMemory {
+     /// - the error code returned by the callback 'f'
+     /// - the size of the already handled data when encountering the first hole
+     /// - the size of the already handled data when the whole range has been handled
+-    fn try_access<F>(&self, count: usize, addr: GuestAddress, mut f: F) -> Result<usize>
++    fn try_access<F>(&self, count: usize, addr: GuestAddress, _is_write: bool, mut f: F) -> Result<usize>
+     where
+         F: FnMut(usize, usize, MemoryRegionAddress, &Self::R) -> Result<usize>,
+     {
+@@ -470,6 +470,7 @@ impl<M: GuestMemoryBytes + ?Sized> Bytes<GuestAddress> for M {
+         self.try_access(
+             buf.len(),
+             addr,
++            true,
+             |offset, _count, caddr, region| -> Result<usize> {
+                 region.write(&buf[offset..], caddr)
+             },
+@@ -480,6 +481,7 @@ impl<M: GuestMemoryBytes + ?Sized> Bytes<GuestAddress> for M {
+         self.try_access(
+             buf.len(),
+             addr,
++            false,
+             |offset, _count, caddr, region| -> Result<usize> {
+                 region.read(&mut buf[offset..], caddr)
+             },
+@@ -547,7 +549,7 @@ impl<M: GuestMemoryBytes + ?Sized> Bytes<GuestAddress> for M {
+     where
+         F: ReadVolatile,
+     {
+-        self.try_access(count, addr, |_, len, caddr, region| -> Result<usize> {
++        self.try_access(count, addr, false, |_, len, caddr, region| -> Result<usize> {
+             region.read_volatile_from(caddr, src, len)
+         })
+     }
+@@ -575,7 +577,7 @@ impl<M: GuestMemoryBytes + ?Sized> Bytes<GuestAddress> for M {
+     where
+         F: WriteVolatile,
+     {
+-        self.try_access(count, addr, |_, len, caddr, region| -> Result<usize> {
++        self.try_access(count, addr, true, |_, len, caddr, region| -> Result<usize> {
+             // For a non-RAM region, reading could have side effects, so we
+             // must use write_all().
+             region.write_all_volatile_to(caddr, dst, len).map(|()| len)
+-- 
+2.34.1
+
diff --git a/subprojects/vm-memory-0.16-rs.wrap b/subprojects/vm-memory-0.16-rs.wrap
index a057c8c9efc1..592271300294 100644
--- a/subprojects/vm-memory-0.16-rs.wrap
+++ b/subprojects/vm-memory-0.16-rs.wrap
@@ -8,5 +8,7 @@ revision = 5eb996a060d7ca3844cbd2f10b1d048c0c91942f
 patch_directory = vm-memory-0.16-rs
 depth = 1
 
+diff_files = vm-memory-0.16-rs/0001.diff, vm-memory-0.16-rs/0002.diff
+
 # bump this version number on every change to meson.build or the patches:
 # v2
-- 
2.34.1
Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend
Posted by Paolo Bonzini 4 months, 1 week ago
On 8/7/25 14:30, Zhao Liu wrote:
> Add 2 patches to support QEMU memory backend implementation.
> 
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>   .../packagefiles/vm-memory-0.16-rs/0001.diff  |  81 +++++++++++++
>   .../packagefiles/vm-memory-0.16-rs/0002.diff  | 111 ++++++++++++++++++
>   subprojects/vm-memory-0.16-rs.wrap            |   2 +
>   3 files changed, 194 insertions(+)
>   create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
>   create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
> 
> diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> new file mode 100644
> index 000000000000..037193108d45
> --- /dev/null
> +++ b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> @@ -0,0 +1,81 @@
> +From 298f8ba019b2fe159fa943e0ae4dfd3c83ee64e0 Mon Sep 17 00:00:00 2001
> +From: Zhao Liu <zhao1.liu@intel.com>
> +Date: Wed, 6 Aug 2025 11:31:11 +0800
> +Subject: [PATCH 1/2] guest_memory: Add a marker tarit to implement
> + Bytes<GuestAddress> for GuestMemory

This was a bit surprising.  Maybe this is something where GuestMemory 
needs some extra flexibility.

> @@ -0,0 +1,111 @@
> +From 2af7ea12a589fde619690e5060c01710cb6f2e0e Mon Sep 17 00:00:00 2001
> +From: Zhao Liu <zhao1.liu@intel.com>
> +Date: Wed, 6 Aug 2025 14:27:14 +0800
> +Subject: [PATCH 2/2] guest_memory: Add is_write argument for
> + GuestMemory::try_access()

This should be fine.  But Hanna is also working on IOMMU so maybe this 
won't be needed!

Paolo
Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend
Posted by Zhao Liu 4 months, 1 week ago
(+Hanna: I would like to align with Hanna on 0002.diff patch :-))

On Thu, Aug 07, 2025 at 03:59:26PM +0200, Paolo Bonzini wrote:
> Date: Thu, 7 Aug 2025 15:59:26 +0200
> From: Paolo Bonzini <pbonzini@redhat.com>
> Subject: Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU
>  memory backend
> 
> On 8/7/25 14:30, Zhao Liu wrote:
> > Add 2 patches to support QEMU memory backend implementation.
> > 
> > Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> > ---
> >   .../packagefiles/vm-memory-0.16-rs/0001.diff  |  81 +++++++++++++
> >   .../packagefiles/vm-memory-0.16-rs/0002.diff  | 111 ++++++++++++++++++
> >   subprojects/vm-memory-0.16-rs.wrap            |   2 +
> >   3 files changed, 194 insertions(+)
> >   create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> >   create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
> > 
> > diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> > new file mode 100644
> > index 000000000000..037193108d45
> > --- /dev/null
> > +++ b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> > @@ -0,0 +1,81 @@
> > +From 298f8ba019b2fe159fa943e0ae4dfd3c83ee64e0 Mon Sep 17 00:00:00 2001
> > +From: Zhao Liu <zhao1.liu@intel.com>
> > +Date: Wed, 6 Aug 2025 11:31:11 +0800
> > +Subject: [PATCH 1/2] guest_memory: Add a marker tarit to implement
> > + Bytes<GuestAddress> for GuestMemory
> 
> This was a bit surprising.  Maybe this is something where GuestMemory needs
> some extra flexibility.

At least, the default GuestMemory::try_access() need to re-implement in
QEMU, and this is because GuestMemory::iter() doesn't fit for QEMU's
case, and GuestMemory::to_region_addr() also needs adjustment to support
complete translation.

For details,

1) iter() - QEMU has implemented the two-level "page" walk in
   `phys_page_find`, which is more efficient than linear iteration.

2) to_region_addr() - it's function signature is:

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

but QEMU currentlt wants:

    fn translate(
        &self,
        addr: GuestAddress,
        len: GuestUsize,
        is_write: bool,
    ) -> Option<(&MemoryRegionSection, MemoryRegionAddress, GuestUsize)>

`is_write` is mainly about IOMMU (and read-only case, but that could be
workaround I think).

And the 3rd member `GuestUsize` of (&MemoryRegionSection,
MemoryRegionAddress, GuestUsize) indicates the remianing size, which is
used to detect cross-region case. Maybe this `GuestUsize` is not
necessary in its return, since we can check the size of `MemoryRegionSection`
later. But this would be a bit repetitive.

But at least, this marker trait is acceptable, right? :-)

The marker trait for GuestMemoryRegion is introduced at commit 66ff347
("refactor: use matches! instead of to_string() for tests").

> > @@ -0,0 +1,111 @@
> > +From 2af7ea12a589fde619690e5060c01710cb6f2e0e Mon Sep 17 00:00:00 2001
> > +From: Zhao Liu <zhao1.liu@intel.com>
> > +Date: Wed, 6 Aug 2025 14:27:14 +0800
> > +Subject: [PATCH 2/2] guest_memory: Add is_write argument for
> > + GuestMemory::try_access()
> 
> This should be fine.  But Hanna is also working on IOMMU so maybe this won't
> be needed!

I'm not sure what method could align with Hanna's design. If there's
another interface/method, I can have a try.

Or, should I just ignore all IOMMU code path directly? This may need
to decouple some C codes. For example, I can split flatview_do_translate
into a non-iommu case and an iommu case.

Thanks,
Zhao
Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend
Posted by Paolo Bonzini 4 months, 1 week ago
On 8/8/25 10:17, Zhao Liu wrote:
> (+Hanna: I would like to align with Hanna on 0002.diff patch :-))
> 
> On Thu, Aug 07, 2025 at 03:59:26PM +0200, Paolo Bonzini wrote:
>> Date: Thu, 7 Aug 2025 15:59:26 +0200
>> From: Paolo Bonzini <pbonzini@redhat.com>
>> Subject: Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU
>>   memory backend
>>
>> On 8/7/25 14:30, Zhao Liu wrote:
>>> Add 2 patches to support QEMU memory backend implementation.
>>>
>>> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
>>> ---
>>>    .../packagefiles/vm-memory-0.16-rs/0001.diff  |  81 +++++++++++++
>>>    .../packagefiles/vm-memory-0.16-rs/0002.diff  | 111 ++++++++++++++++++
>>>    subprojects/vm-memory-0.16-rs.wrap            |   2 +
>>>    3 files changed, 194 insertions(+)
>>>    create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
>>>    create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
>>>
>>> diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
>>> new file mode 100644
>>> index 000000000000..037193108d45
>>> --- /dev/null
>>> +++ b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
>>> @@ -0,0 +1,81 @@
>>> +From 298f8ba019b2fe159fa943e0ae4dfd3c83ee64e0 Mon Sep 17 00:00:00 2001
>>> +From: Zhao Liu <zhao1.liu@intel.com>
>>> +Date: Wed, 6 Aug 2025 11:31:11 +0800
>>> +Subject: [PATCH 1/2] guest_memory: Add a marker tarit to implement
>>> + Bytes<GuestAddress> for GuestMemory
>>
>> This was a bit surprising.  Maybe this is something where GuestMemory needs
>> some extra flexibility.
> 
> At least, the default GuestMemory::try_access() need to re-implement in
> QEMU, and this is because GuestMemory::iter() doesn't fit for QEMU's
> case, and GuestMemory::to_region_addr() also needs adjustment to support
> complete translation.
> 
> For details,
> 
> 1) iter() - QEMU has implemented the two-level "page" walk in
>     `phys_page_find`, which is more efficient than linear iteration.
> 
> 2) to_region_addr() - it's function signature is:
> 
>      fn to_region_addr(
>          &self,
> 	addr: GuestAddress
>      ) -> Option<(&Self::R, MemoryRegionAddress)>;
> 
> but QEMU currentlt wants:
> 
>      fn translate(
>          &self,
>          addr: GuestAddress,
>          len: GuestUsize,
>          is_write: bool,
>      ) -> Option<(&MemoryRegionSection, MemoryRegionAddress, GuestUsize)>
> 
> `is_write` is mainly about IOMMU (and read-only case, but that could be
> workaround I think).
> 
> And the 3rd member `GuestUsize` of (&MemoryRegionSection,
> MemoryRegionAddress, GuestUsize) indicates the remianing size, which is
> used to detect cross-region case. Maybe this `GuestUsize` is not
> necessary in its return, since we can check the size of `MemoryRegionSection`
> later. But this would be a bit repetitive.
> 
> But at least, this marker trait is acceptable, right? :-)
> 
> The marker trait for GuestMemoryRegion is introduced at commit 66ff347
> ("refactor: use matches! instead of to_string() for tests").
> 
>>> @@ -0,0 +1,111 @@
>>> +From 2af7ea12a589fde619690e5060c01710cb6f2e0e Mon Sep 17 00:00:00 2001
>>> +From: Zhao Liu <zhao1.liu@intel.com>
>>> +Date: Wed, 6 Aug 2025 14:27:14 +0800
>>> +Subject: [PATCH 2/2] guest_memory: Add is_write argument for
>>> + GuestMemory::try_access()
>>
>> This should be fine.  But Hanna is also working on IOMMU so maybe this won't
>> be needed!
> 
> I'm not sure what method could align with Hanna's design. If there's
> another interface/method, I can have a try.

For example she already has similar fixes in 
https://github.com/rust-vmm/vm-memory/pull/327:

https://github.com/rust-vmm/vm-memory/pull/327/commits/9bcd5ac9b9ae37d1fb421f86f0aff310411933af
    Bytes: Fix read() and write()

    read() and write() must not ignore the `count` parameter: The
    mappings passed into the `try_access()` closure are only valid for up
    to `count` bytes, not more.

https://github.com/rust-vmm/vm-memory/pull/327/commits/2b83c72be656e5d46b83cb3a66d580e56cf33d5b
     Bytes: Do not use to_region_addr()

     When we switch to a (potentially) virtual memory model [...]
     the one memory-region-referencing part we are going to keep is
     `try_access()` [...] switch `Bytes::load()` and `store()` from using
     `to_region_addr()` to `try_access()`.

With some luck, your custom implementation of Bytes<GuestAddress> is not 
needed once vm-memory supports iommu.

Paolo
Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU memory backend
Posted by Zhao Liu 4 months, 1 week ago
On Fri, Aug 08, 2025 at 10:17:51AM +0200, Paolo Bonzini wrote:
> Date: Fri, 8 Aug 2025 10:17:51 +0200
> From: Paolo Bonzini <pbonzini@redhat.com>
> Subject: Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU
>  memory backend
> 
> On 8/8/25 10:17, Zhao Liu wrote:
> > (+Hanna: I would like to align with Hanna on 0002.diff patch :-))
> > 
> > On Thu, Aug 07, 2025 at 03:59:26PM +0200, Paolo Bonzini wrote:
> > > Date: Thu, 7 Aug 2025 15:59:26 +0200
> > > From: Paolo Bonzini <pbonzini@redhat.com>
> > > Subject: Re: [RFC 10/26] subprojects/vm-memory: Patch vm-memory for QEMU
> > >   memory backend
> > > 
> > > On 8/7/25 14:30, Zhao Liu wrote:
> > > > Add 2 patches to support QEMU memory backend implementation.
> > > > 
> > > > Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> > > > ---
> > > >    .../packagefiles/vm-memory-0.16-rs/0001.diff  |  81 +++++++++++++
> > > >    .../packagefiles/vm-memory-0.16-rs/0002.diff  | 111 ++++++++++++++++++
> > > >    subprojects/vm-memory-0.16-rs.wrap            |   2 +
> > > >    3 files changed, 194 insertions(+)
> > > >    create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> > > >    create mode 100644 subprojects/packagefiles/vm-memory-0.16-rs/0002.diff
> > > > 
> > > > diff --git a/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> > > > new file mode 100644
> > > > index 000000000000..037193108d45
> > > > --- /dev/null
> > > > +++ b/subprojects/packagefiles/vm-memory-0.16-rs/0001.diff
> > > > @@ -0,0 +1,81 @@
> > > > +From 298f8ba019b2fe159fa943e0ae4dfd3c83ee64e0 Mon Sep 17 00:00:00 2001
> > > > +From: Zhao Liu <zhao1.liu@intel.com>
> > > > +Date: Wed, 6 Aug 2025 11:31:11 +0800
> > > > +Subject: [PATCH 1/2] guest_memory: Add a marker tarit to implement
> > > > + Bytes<GuestAddress> for GuestMemory
> > > 
> > > This was a bit surprising.  Maybe this is something where GuestMemory needs
> > > some extra flexibility.
> > 
> > At least, the default GuestMemory::try_access() need to re-implement in
> > QEMU, and this is because GuestMemory::iter() doesn't fit for QEMU's
> > case, and GuestMemory::to_region_addr() also needs adjustment to support
> > complete translation.
> > 
> > For details,
> > 
> > 1) iter() - QEMU has implemented the two-level "page" walk in
> >     `phys_page_find`, which is more efficient than linear iteration.
> > 
> > 2) to_region_addr() - it's function signature is:
> > 
> >      fn to_region_addr(
> >          &self,
> > 	addr: GuestAddress
> >      ) -> Option<(&Self::R, MemoryRegionAddress)>;
> > 
> > but QEMU currentlt wants:
> > 
> >      fn translate(
> >          &self,
> >          addr: GuestAddress,
> >          len: GuestUsize,
> >          is_write: bool,
> >      ) -> Option<(&MemoryRegionSection, MemoryRegionAddress, GuestUsize)>
> > 
> > `is_write` is mainly about IOMMU (and read-only case, but that could be
> > workaround I think).
> > 
> > And the 3rd member `GuestUsize` of (&MemoryRegionSection,
> > MemoryRegionAddress, GuestUsize) indicates the remianing size, which is
> > used to detect cross-region case. Maybe this `GuestUsize` is not
> > necessary in its return, since we can check the size of `MemoryRegionSection`
> > later. But this would be a bit repetitive.
> > 
> > But at least, this marker trait is acceptable, right? :-)
> > 
> > The marker trait for GuestMemoryRegion is introduced at commit 66ff347
> > ("refactor: use matches! instead of to_string() for tests").
> > 
> > > > @@ -0,0 +1,111 @@
> > > > +From 2af7ea12a589fde619690e5060c01710cb6f2e0e Mon Sep 17 00:00:00 2001
> > > > +From: Zhao Liu <zhao1.liu@intel.com>
> > > > +Date: Wed, 6 Aug 2025 14:27:14 +0800
> > > > +Subject: [PATCH 2/2] guest_memory: Add is_write argument for
> > > > + GuestMemory::try_access()
> > > 
> > > This should be fine.  But Hanna is also working on IOMMU so maybe this won't
> > > be needed!
> > 
> > I'm not sure what method could align with Hanna's design. If there's
> > another interface/method, I can have a try.
> 
> For example she already has similar fixes in
> https://github.com/rust-vmm/vm-memory/pull/327:
> 
> https://github.com/rust-vmm/vm-memory/pull/327/commits/9bcd5ac9b9ae37d1fb421f86f0aff310411933af
>    Bytes: Fix read() and write()
> 
>    read() and write() must not ignore the `count` parameter: The
>    mappings passed into the `try_access()` closure are only valid for up
>    to `count` bytes, not more.
> 
> https://github.com/rust-vmm/vm-memory/pull/327/commits/2b83c72be656e5d46b83cb3a66d580e56cf33d5b
>     Bytes: Do not use to_region_addr()
> 
>     When we switch to a (potentially) virtual memory model [...]
>     the one memory-region-referencing part we are going to keep is
>     `try_access()` [...] switch `Bytes::load()` and `store()` from using
>     `to_region_addr()` to `try_access()`.
> 
> With some luck, your custom implementation of Bytes<GuestAddress> is not
> needed once vm-memory supports iommu.

Nice! I took a quick look, and these patches seem to be shaped as what
this RFC wants. I'll give them a try.

Thanks,
Zhao