Skip to content

Commit bb6f105

Browse files
committed
refactor: clean up region collection related errors
Turn the error type defined in region.rs into one specifically to GuestRegionCollections, and move the non-collection related errors into a new error type that is specific to the `from_ranges*` family of functions (these are the only functions that can return both a region construction error, as well as a collection error). The `from_ranges*` family of functions is publicly exported, but in reality only used in tests, so breakage of this should be limited. Since we're breaking things anyway, remove the reexport of GuestRegionCollectionError as `vm_memory::Error`. It made no sense for this one to have this special designation. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent d8754ab commit bb6f105

File tree

3 files changed

+47
-43
lines changed

3 files changed

+47
-43
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub use guest_memory::{
5151
};
5252

5353
pub mod region;
54-
pub use region::{GuestMemoryRegion, GuestRegionCollection, GuestRegionError as Error};
54+
pub use region::{GuestMemoryRegion, GuestRegionCollection, GuestRegionCollectionError};
5555

5656
pub mod io;
5757
pub use io::{ReadVolatile, WriteVolatile};

src/mmap/mod.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,15 @@ impl<B: NewBitmap> GuestRegionMmap<B> {
8282
addr: GuestAddress,
8383
size: usize,
8484
file: Option<FileOffset>,
85-
) -> result::Result<Self, Error> {
85+
) -> result::Result<Self, FromRangesError> {
8686
let region = if let Some(ref f_off) = file {
87-
MmapRegion::from_file(f_off.clone(), size)
87+
MmapRegion::from_file(f_off.clone(), size)?
8888
} else {
89-
MmapRegion::new(size)
90-
}
91-
.map_err(Error::MmapRegion)?;
89+
MmapRegion::new(size)?
90+
};
9291

9392
Self::new(region, addr)
94-
.ok_or(Error::InvalidGuestRegion)
93+
.ok_or(FromRangesError::InvalidGuestRegion)
9594
}
9695
}
9796

@@ -103,12 +102,12 @@ impl<B: NewBitmap> GuestRegionMmap<B> {
103102
addr: GuestAddress,
104103
size: usize,
105104
file: Option<FileOffset>,
106-
) -> result::Result<Self, Error> {
105+
) -> result::Result<Self, FromRangesError> {
107106
let range = MmapRange::new_unix(size, file, addr);
108107

109-
let region = MmapRegion::from_range(range).map_err(Error::MmapRegion)?;
108+
let region = MmapRegion::from_range(range)?;
110109
Self::new(region, addr)
111-
.ok_or(Error::InvalidGuestRegion)
110+
.ok_or(FromRangesError::InvalidGuestRegion)
112111
}
113112
}
114113

@@ -168,19 +167,33 @@ impl<B: Bitmap> GuestMemoryRegionBytes for GuestRegionMmap<B> {}
168167
/// virtual address space of the calling process.
169168
pub type GuestMemoryMmap<B = ()> = GuestRegionCollection<GuestRegionMmap<B>>;
170169

170+
/// Errors that can happen during [`GuestMemoryMap::from_ranges`] and related functions.
171+
#[derive(Debug, thiserror::Error)]
172+
pub enum FromRangesError {
173+
/// Error during construction of [`GuestMemoryMmap`]
174+
#[error("Error constructing guest region collection: {0}")]
175+
Collection(#[from] Error),
176+
/// Error while allocating raw mmap region
177+
#[error("Error setting up raw memory for guest region: {0}")]
178+
MmapRegion(#[from] MmapRegionError),
179+
/// A combination of region length and guest address would overflow.
180+
#[error("Combination of guest address and region length invalid (would overflow)")]
181+
InvalidGuestRegion,
182+
}
183+
171184
impl<B: NewBitmap> GuestMemoryMmap<B> {
172185
/// Creates a container and allocates anonymous memory for guest memory regions.
173186
///
174187
/// Valid memory regions are specified as a slice of (Address, Size) tuples sorted by Address.
175-
pub fn from_ranges(ranges: &[(GuestAddress, usize)]) -> result::Result<Self, Error> {
188+
pub fn from_ranges(ranges: &[(GuestAddress, usize)]) -> result::Result<Self, FromRangesError> {
176189
Self::from_ranges_with_files(ranges.iter().map(|r| (r.0, r.1, None)))
177190
}
178191

179192
/// Creates a container and allocates anonymous memory for guest memory regions.
180193
///
181194
/// Valid memory regions are specified as a sequence of (Address, Size, [`Option<FileOffset>`])
182195
/// tuples sorted by Address.
183-
pub fn from_ranges_with_files<A, T>(ranges: T) -> result::Result<Self, Error>
196+
pub fn from_ranges_with_files<A, T>(ranges: T) -> result::Result<Self, FromRangesError>
184197
where
185198
A: Borrow<(GuestAddress, usize, Option<FileOffset>)>,
186199
T: IntoIterator<Item = A>,
@@ -191,8 +204,8 @@ impl<B: NewBitmap> GuestMemoryMmap<B> {
191204
.map(|x| {
192205
GuestRegionMmap::from_range(x.borrow().0, x.borrow().1, x.borrow().2.clone())
193206
})
194-
.collect::<result::Result<Vec<_>, Error>>()?,
195-
)
207+
.collect::<Result<Vec<_>, _>>()?,
208+
).map_err(Into::into)
196209
}
197210
}
198211

src/region.rs

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,9 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = GuestMemoryError> {
142142
}
143143
}
144144

145-
/// Errors that can occur when dealing with [`GuestRegion`]s, or collections thereof
145+
/// Errors that can occur when dealing with [`GuestRegionCollection`]s
146146
#[derive(Debug, thiserror::Error)]
147-
pub enum GuestRegionError {
148-
/// Adding the guest base address to the length of the underlying mapping resulted
149-
/// in an overflow.
150-
#[error("Adding the guest base address to the length of the underlying mapping resulted in an overflow")]
151-
#[cfg(feature = "backend-mmap")]
152-
InvalidGuestRegion,
153-
/// Error creating a `MmapRegion` object.
154-
#[error("{0}")]
155-
#[cfg(feature = "backend-mmap")]
156-
MmapRegion(crate::mmap::MmapRegionError),
147+
pub enum GuestRegionCollectionError {
157148
/// No memory region found.
158149
#[error("No memory region found")]
159150
NoMemoryRegion,
@@ -203,7 +194,7 @@ impl<R: GuestMemoryRegion> GuestRegionCollection<R> {
203194
/// * `regions` - The vector of regions.
204195
/// The regions shouldn't overlap, and they should be sorted
205196
/// by the starting address.
206-
pub fn from_regions(mut regions: Vec<R>) -> std::result::Result<Self, GuestRegionError> {
197+
pub fn from_regions(mut regions: Vec<R>) -> std::result::Result<Self, GuestRegionCollectionError> {
207198
Self::from_arc_regions(regions.drain(..).map(Arc::new).collect())
208199
}
209200

@@ -219,21 +210,21 @@ impl<R: GuestMemoryRegion> GuestRegionCollection<R> {
219210
/// * `regions` - The vector of `Arc` regions.
220211
/// The regions shouldn't overlap and they should be sorted
221212
/// by the starting address.
222-
pub fn from_arc_regions(regions: Vec<Arc<R>>) -> std::result::Result<Self, GuestRegionError> {
213+
pub fn from_arc_regions(regions: Vec<Arc<R>>) -> std::result::Result<Self, GuestRegionCollectionError> {
223214
if regions.is_empty() {
224-
return Err(GuestRegionError::NoMemoryRegion);
215+
return Err(GuestRegionCollectionError::NoMemoryRegion);
225216
}
226217

227218
for window in regions.windows(2) {
228219
let prev = &window[0];
229220
let next = &window[1];
230221

231222
if prev.start_addr() > next.start_addr() {
232-
return Err(GuestRegionError::UnsortedMemoryRegions);
223+
return Err(GuestRegionCollectionError::UnsortedMemoryRegions);
233224
}
234225

235226
if prev.last_addr() >= next.start_addr() {
236-
return Err(GuestRegionError::MemoryRegionOverlap);
227+
return Err(GuestRegionCollectionError::MemoryRegionOverlap);
237228
}
238229
}
239230

@@ -247,7 +238,7 @@ impl<R: GuestMemoryRegion> GuestRegionCollection<R> {
247238
pub fn insert_region(
248239
&self,
249240
region: Arc<R>,
250-
) -> std::result::Result<GuestRegionCollection<R>, GuestRegionError> {
241+
) -> std::result::Result<GuestRegionCollection<R>, GuestRegionCollectionError> {
251242
let mut regions = self.regions.clone();
252243
regions.push(region);
253244
regions.sort_by_key(|x| x.start_addr());
@@ -265,7 +256,7 @@ impl<R: GuestMemoryRegion> GuestRegionCollection<R> {
265256
&self,
266257
base: GuestAddress,
267258
size: GuestUsize,
268-
) -> std::result::Result<(GuestRegionCollection<R>, Arc<R>), GuestRegionError> {
259+
) -> std::result::Result<(GuestRegionCollection<R>, Arc<R>), GuestRegionCollectionError> {
269260
if let Ok(region_index) = self.regions.binary_search_by_key(&base, |x| x.start_addr()) {
270261
if self.regions.get(region_index).unwrap().len() == size {
271262
let mut regions = self.regions.clone();
@@ -274,7 +265,7 @@ impl<R: GuestMemoryRegion> GuestRegionCollection<R> {
274265
}
275266
}
276267

277-
Err(GuestRegionError::NoMemoryRegion)
268+
Err(GuestRegionCollectionError::NoMemoryRegion)
278269
}
279270
}
280271

@@ -452,7 +443,7 @@ impl<R: GuestMemoryRegionBytes> Bytes<MemoryRegionAddress> for R {
452443

453444
#[cfg(test)]
454445
pub(crate) mod tests {
455-
use crate::region::{GuestMemoryRegionBytes, GuestRegionError};
446+
use crate::region::{GuestMemoryRegionBytes, GuestRegionCollectionError};
456447
use crate::{
457448
Address, GuestAddress, GuestMemory, GuestMemoryRegion, GuestRegionCollection, GuestUsize,
458449
};
@@ -483,7 +474,7 @@ pub(crate) mod tests {
483474
pub(crate) type Collection = GuestRegionCollection<MockRegion>;
484475

485476
fn check_guest_memory_mmap(
486-
maybe_guest_mem: Result<Collection, GuestRegionError>,
477+
maybe_guest_mem: Result<Collection, GuestRegionCollectionError>,
487478
expected_regions_summary: &[(GuestAddress, u64)],
488479
) {
489480
assert!(maybe_guest_mem.is_ok());
@@ -510,7 +501,7 @@ pub(crate) mod tests {
510501

511502
pub(crate) fn new_guest_memory_collection_from_regions(
512503
regions_summary: &[(GuestAddress, u64)],
513-
) -> Result<Collection, GuestRegionError> {
504+
) -> Result<Collection, GuestRegionCollectionError> {
514505
Collection::from_regions(
515506
regions_summary
516507
.iter()
@@ -521,7 +512,7 @@ pub(crate) mod tests {
521512

522513
fn new_guest_memory_collection_from_arc_regions(
523514
regions_summary: &[(GuestAddress, u64)],
524-
) -> Result<Collection, GuestRegionError> {
515+
) -> Result<Collection, GuestRegionCollectionError> {
525516
Collection::from_arc_regions(
526517
regions_summary
527518
.iter()
@@ -536,11 +527,11 @@ pub(crate) mod tests {
536527

537528
assert!(matches!(
538529
new_guest_memory_collection_from_regions(&regions_summary).unwrap_err(),
539-
GuestRegionError::NoMemoryRegion
530+
GuestRegionCollectionError::NoMemoryRegion
540531
));
541532
assert!(matches!(
542533
new_guest_memory_collection_from_arc_regions(&regions_summary).unwrap_err(),
543-
GuestRegionError::NoMemoryRegion
534+
GuestRegionCollectionError::NoMemoryRegion
544535
));
545536
}
546537

@@ -550,11 +541,11 @@ pub(crate) mod tests {
550541

551542
assert!(matches!(
552543
new_guest_memory_collection_from_regions(&regions_summary).unwrap_err(),
553-
GuestRegionError::MemoryRegionOverlap
544+
GuestRegionCollectionError::MemoryRegionOverlap
554545
));
555546
assert!(matches!(
556547
new_guest_memory_collection_from_arc_regions(&regions_summary).unwrap_err(),
557-
GuestRegionError::MemoryRegionOverlap
548+
GuestRegionCollectionError::MemoryRegionOverlap
558549
));
559550
}
560551

@@ -564,11 +555,11 @@ pub(crate) mod tests {
564555

565556
assert!(matches!(
566557
new_guest_memory_collection_from_regions(&regions_summary).unwrap_err(),
567-
GuestRegionError::UnsortedMemoryRegions
558+
GuestRegionCollectionError::UnsortedMemoryRegions
568559
));
569560
assert!(matches!(
570561
new_guest_memory_collection_from_arc_regions(&regions_summary).unwrap_err(),
571-
GuestRegionError::UnsortedMemoryRegions
562+
GuestRegionCollectionError::UnsortedMemoryRegions
572563
));
573564
}
574565

0 commit comments

Comments
 (0)