diff --git a/src/context/memory.rs b/src/context/memory.rs index 7dc985b433..e3bb7dd34c 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -1602,6 +1602,12 @@ impl Grant { } // Cannot be shared and CoW simultaneously. Err(AddRefError::SharedToCow) => { + // The call to cow() later implicitly removes one ref, so add it here + // first, even if Shared. + if src_page_info.add_ref(RefKind::Shared) == Err(AddRefError::RcOverflow) { + return Err(Enomem); + } + // TODO: Copy in place, or use a zeroed page? let CowResult { new_frame, old_frame } = cow(src_frame, src_page_info, rk).map_err(|_| Enomem)?; if let Some(old_frame) = old_frame { diff --git a/src/memory/mod.rs b/src/memory/mod.rs index b791e50f24..145aa40cf4 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -643,7 +643,7 @@ pub fn init_mm(allocator: BumpAllocator) { THE_ZEROED_FRAME.get().write(Some((the_frame, the_info))); } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum AddRefError { CowToShared, SharedToCow, diff --git a/syscall b/syscall index 5b07568677..1583e94276 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 5b075686774ef88374d93834c54e339d456a8ec2 +Subproject commit 1583e94276dbd84f4e23f044accadef5bb28ad6b