kernel: replace 5 unreachable!() in page fault handler with graceful errors
- SharedToCow/CowToShared invariant violations: log error, return ENOMEM - Allocated page with no frame: log error, return EINVAL (process gets SIGSEGV but kernel survives) Previously these panicked the kernel. Now they handle the rare invariant violation gracefully — same approach as the OOM fix.
This commit is contained in:
+20
-7
@@ -553,10 +553,14 @@ impl AddrSpaceWrapper {
|
||||
{
|
||||
Ok(_) => Ok(unsafe { RaiiFrame::new_unchecked(frame) }),
|
||||
Err(AddRefError::RcOverflow) => Err(Error::new(ENOMEM)),
|
||||
Err(AddRefError::SharedToCow) => unreachable!(),
|
||||
Err(AddRefError::CowToShared) => unreachable!(
|
||||
"if it was CoW, it was read-only, but in that case we already called correct_inner"
|
||||
),
|
||||
Err(AddRefError::SharedToCow) => {
|
||||
log::error!("unexpected SharedToCow in add_ref — invariant violation");
|
||||
Err(Error::new(ENOMEM))
|
||||
}
|
||||
Err(AddRefError::CowToShared) => {
|
||||
log::error!("unexpected CowToShared in add_ref — invariant violation");
|
||||
Err(Error::new(ENOMEM))
|
||||
}
|
||||
};
|
||||
drop(guard_lock);
|
||||
|
||||
@@ -1499,7 +1503,10 @@ impl Grant {
|
||||
|
||||
new_cow_frame
|
||||
},
|
||||
Err(AddRefError::SharedToCow) => unreachable!(),
|
||||
Err(AddRefError::SharedToCow) => {
|
||||
log::error!("unexpected SharedToCow in CoW path — invariant violation");
|
||||
return Err(Error::new(ENOMEM));
|
||||
},
|
||||
Err(AddRefError::RcOverflow) => return Err(Error::new(ENOMEM)),
|
||||
}
|
||||
} else {
|
||||
@@ -2512,7 +2519,10 @@ fn correct_inner<'l>(
|
||||
if access == AccessMode::Write =>
|
||||
{
|
||||
match faulting_pageinfo_opt {
|
||||
Some((_, None)) => unreachable!("allocated page needs frame to be valid"),
|
||||
Some((_, None)) => {
|
||||
log::error!("allocated page has no frame — kernel invariant violation");
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
Some((frame, Some(info))) => {
|
||||
if info.allows_writable() {
|
||||
frame
|
||||
@@ -2535,7 +2545,10 @@ fn correct_inner<'l>(
|
||||
|
||||
Provider::Allocated { .. } | Provider::AllocatedShared { .. } => {
|
||||
match faulting_pageinfo_opt {
|
||||
Some((_, None)) => unreachable!("allocated page needs frame to be valid"),
|
||||
Some((_, None)) => {
|
||||
log::error!("allocated page has no frame — kernel invariant violation");
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
// TODO: Can this match arm even be reached? In other words, can the TLB cache
|
||||
// remember that pages are not present?
|
||||
|
||||
Reference in New Issue
Block a user