WIP: Ensure that Grant::borrow does not borrow nonpresent grants.
This commit is contained in:
+21
-5
@@ -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)?
|
||||
|
||||
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user