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(®.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(®.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
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
(+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
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
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
© 2016 - 2025 Red Hat, Inc.