diff --git a/src/context/memory.rs b/src/context/memory.rs index ffc61415d82210736b5f5e4e78a2fd79459cb353..2c6492857427f4fecf3b44f53cfe8a942d95744b 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -644,7 +644,7 @@ impl Grant { dst_mapper: &mut PageMapper, dst_flusher: impl Flusher<RmmA>, eager: bool, - ) -> Result<Vec<Grant>, Enomem> { + ) -> Result<Vec<Grant>> { /* if eager { for page in PageSpan::new(src_base, page_count) { @@ -653,16 +653,22 @@ impl Grant { } */ - // TODO: If grants are missing for certain ranges specified, fill with Provider::External - // grants anyway, which will in turn fill the host address space will zeroed grants. This - // is required before schemes can be safe. - let mut dst_grants = Vec::with_capacity(1); let src_span = PageSpan::new(src_base, page_count); + let mut prev_span = None; for (src_grant_base, src_grant) in src_address_space.grants.conflicts(src_span) { let grant_span = PageSpan::new(src_grant_base, src_grant.page_count); + let prev_span = prev_span.replace(grant_span); + + if prev_span.is_none() && src_grant_base > src_base { + log::warn!("Grant too far away, prev_span {:?} src_base {:?} grant base {:?} grant {:#?}", prev_span, src_base, src_grant_base, src_grant); + return Err(Error::new(EINVAL)); + } else if let Some(prev) = prev_span && prev.end() != src_grant_base { + log::warn!("Hole between grants, prev_span {:?} src_base {:?} grant base {:?} grant {:#?}", prev_span, src_base, src_grant_base, src_grant); + return Err(Error::new(EINVAL)); + } let common_span = src_span.intersection(grant_span); let offset_from_src_base = common_span.base.offset_from(src_base); @@ -690,6 +696,16 @@ impl Grant { }); } + let Some(last_span) = prev_span else { + log::warn!("Called Grant::borrow, but no grants were there!"); + return Err(Error::new(EINVAL)); + }; + + if last_span.end() < src_span.end() { + log::warn!("Requested end page too far away from last grant"); + return Err(Error::new(EINVAL)); + } + Ok(dst_grants) } // TODO: This is limited to one grant. Should it be (if some magic new proc: API is introduced)? diff --git a/src/lib.rs b/src/lib.rs index 94be64242ff23d7a9372b993c081e9a3cb3b1aca..b6312060f9b0edaba7f81d333412948701d73ae6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,7 @@ #![feature(const_option)] #![feature(arbitrary_self_types)] #![feature(int_roundings)] +#![feature(let_chains)] #![feature(naked_functions)] #![feature(slice_ptr_get, slice_ptr_len)] #![feature(sync_unsafe_cell)]