Add `is_forced` into `PageFaultInfo`

This commit is contained in:
Wang Siyuan 2026-01-07 12:50:04 +00:00
parent 6d2ff13a63
commit 35b9841cee
6 changed files with 33 additions and 24 deletions

View File

@ -152,10 +152,7 @@ impl TryFrom<&CpuExceptionInfo> for PageFaultInfo {
_ => return Err(()),
};
Ok(PageFaultInfo {
address: value.page_fault_addr,
required_perms,
})
Ok(PageFaultInfo::new(value.page_fault_addr, required_perms))
}
}

View File

@ -150,10 +150,7 @@ impl TryFrom<&CpuException> for PageFaultInfo {
_ => return Err(()),
};
Ok(PageFaultInfo {
address: *fault_addr,
required_perms,
})
Ok(PageFaultInfo::new(*fault_addr, required_perms))
}
}

View File

@ -145,10 +145,7 @@ impl From<&RawPageFaultInfo> for PageFaultInfo {
VmPerms::READ
};
PageFaultInfo {
address: raw_info.addr,
required_perms,
}
PageFaultInfo::new(raw_info.addr, required_perms)
}
}

View File

@ -72,10 +72,7 @@ pub fn futex_wait_bitset(
// The futex word is aligned on a 4-byte boundary, so it cannot cross the page boundary.
user_space
.vmar()
.handle_page_fault(&PageFaultInfo {
address: futex_addr,
required_perms: VmPerms::READ,
})
.handle_page_fault(&PageFaultInfo::new(futex_addr, VmPerms::READ))
.map_err(|_| {
Error::with_message(
Errno::EFAULT,
@ -288,10 +285,10 @@ pub fn futex_wake_op(
// The futex word is aligned on a 4-byte boundary, so it cannot cross the page boundary.
user_space
.vmar()
.handle_page_fault(&PageFaultInfo {
address: futex_addr_2,
required_perms: VmPerms::READ | VmPerms::WRITE,
})
.handle_page_fault(&PageFaultInfo::new(
futex_addr_2,
VmPerms::READ | VmPerms::WRITE,
))
.map_err(|_| {
Error::with_message(
Errno::EFAULT,

View File

@ -28,6 +28,30 @@ pub struct PageFaultInfo {
/// The [`VmPerms`] required by the memory operation that causes page fault.
/// For example, a "store" operation may require `VmPerms::WRITE`.
pub required_perms: VmPerms,
/// Whether this page fault is forced (e.g., manually triggered by `ptrace`).
/// A forced page fault may bypass some permission checks.
pub is_forced: bool,
_private: (),
}
impl PageFaultInfo {
/// Creates a new `PageFaultInfo`.
pub fn new(address: Vaddr, required_perms: VmPerms) -> Self {
Self {
address,
required_perms,
is_forced: false,
_private: (),
}
}
/// Marks this page fault as forced.
pub fn force(mut self) -> Self {
self.is_forced = true;
self
}
}
/// We can't handle most exceptions, just send self a fault signal before return to user space.

View File

@ -150,10 +150,7 @@ impl Vmar {
Some(_) | None => (),
}
let page_fault_info = PageFaultInfo {
address: vaddr,
required_perms: required_page_flags.into(),
};
let page_fault_info = PageFaultInfo::new(vaddr, required_page_flags.into()).force();
self.handle_page_fault(&page_fault_info)?;
item = self.query_page(vaddr)?;