feat(mm): 实现缺页中断处理,支持页面延迟分配和写时拷贝,以及用户栈自动拓展 (#715)

* 实现缺页中断处理

* 完善页表拷贝逻辑

* 优化代码结构

* 完善缺页异常信息

* 修改大页映射逻辑

* 修正大页映射错误

* 添加缺页中断支持标志

* 实现用户栈自动拓展功能
This commit is contained in:
MemoryShore
2024-04-22 15:10:47 +08:00
committed by GitHub
parent cb02d0bbc2
commit a17651b14b
16 changed files with 1657 additions and 135 deletions

84
kernel/src/mm/madvise.rs Normal file
View File

@ -0,0 +1,84 @@
use system_error::SystemError;
use crate::arch::{mm::PageMapper, MMArch};
use super::{page::Flusher, syscall::MadvFlags, ucontext::LockedVMA, VmFlags};
impl LockedVMA {
pub fn do_madvise(
&self,
behavior: MadvFlags,
_mapper: &mut PageMapper,
_flusher: impl Flusher<MMArch>,
) -> Result<(), SystemError> {
//TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/madvise.c?fi=madvise#do_madvise
let mut vma = self.lock();
let mut new_flags = *vma.vm_flags();
match behavior {
MadvFlags::MADV_REMOVE => {
// TODO
}
MadvFlags::MADV_WILLNEED => {
// TODO
}
MadvFlags::MADV_COLD => {
// TODO
}
MadvFlags::MADV_PAGEOUT => {
// TODO
}
MadvFlags::MADV_FREE => {
// TODO
}
MadvFlags::MADV_POPULATE_READ | MadvFlags::MADV_POPULATE_WRITE => {
// TODO
}
MadvFlags::MADV_NORMAL => {
new_flags = new_flags & !VmFlags::VM_RAND_READ & !VmFlags::VM_SEQ_READ
}
MadvFlags::MADV_SEQUENTIAL => {
new_flags = (new_flags & !VmFlags::VM_RAND_READ) | VmFlags::VM_SEQ_READ
}
MadvFlags::MADV_RANDOM => {
new_flags = (new_flags & !VmFlags::VM_SEQ_READ) | VmFlags::VM_RAND_READ
}
MadvFlags::MADV_DONTFORK => new_flags |= VmFlags::VM_DONTCOPY,
MadvFlags::MADV_DOFORK => {
if vma.vm_flags().contains(VmFlags::VM_IO) {
return Err(SystemError::EINVAL);
}
new_flags &= !VmFlags::VM_DONTCOPY;
}
MadvFlags::MADV_WIPEONFORK => {
//MADV_WIPEONFORK仅支持匿名映射后续实现其他映射方式后要在此处添加判断条件
new_flags |= VmFlags::VM_WIPEONFORK;
}
MadvFlags::MADV_KEEPONFORK => new_flags &= !VmFlags::VM_WIPEONFORK,
MadvFlags::MADV_DONTDUMP => new_flags |= VmFlags::VM_DONTDUMP,
//MADV_DODUMP不支持巨页映射后续需要添加判断条件
MadvFlags::MADV_DODUMP => new_flags &= !VmFlags::VM_DONTDUMP,
MadvFlags::MADV_MERGEABLE | MadvFlags::MADV_UNMERGEABLE => {}
MadvFlags::MADV_HUGEPAGE | MadvFlags::MADV_NOHUGEPAGE => {}
MadvFlags::MADV_COLLAPSE => {}
_ => {}
}
vma.set_vm_flags(new_flags);
Ok(())
}
}