Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mm): 修复vma映射标志错误 #801

Merged
merged 1 commit into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions kernel/src/mm/fault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ impl PageFaultMessage {
}
}

impl Clone for PageFaultMessage {
fn clone(&self) -> Self {
Self {
vma: self.vma.clone(),
address: self.address,
flags: self.flags,
}
}
}

/// 缺页中断处理结构体
pub struct PageFaultHandler;

Expand Down Expand Up @@ -167,27 +177,30 @@ impl PageFaultHandler {
let address = pfm.address_aligned_down();
let flags = pfm.flags;
let vma = pfm.vma.clone();
let mut ret = VmFaultReason::VM_FAULT_COMPLETED;
if let Some(mut entry) = mapper.get_entry(address, 0) {
if !entry.present() {
return Self::do_swap_page(pfm, mapper);
ret = Self::do_swap_page(pfm.clone(), mapper);
}
if entry.protnone() && vma.is_accessible() {
return Self::do_numa_page(pfm, mapper);
ret = Self::do_numa_page(pfm.clone(), mapper);
}
if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) {
if !entry.write() {
return Self::do_wp_page(pfm, mapper);
ret = Self::do_wp_page(pfm.clone(), mapper);
} else {
entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
}
}
} else if vma.is_anonymous() {
return Self::do_anonymous_page(pfm, mapper);
ret = Self::do_anonymous_page(pfm.clone(), mapper);
} else {
return Self::do_fault(pfm, mapper);
ret = Self::do_fault(pfm.clone(), mapper);
}

VmFaultReason::VM_FAULT_COMPLETED
vma.lock().set_mapped(true);

return ret;
}

/// 处理匿名映射页缺页异常
Expand Down
28 changes: 8 additions & 20 deletions kernel/src/mm/ucontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,18 +299,12 @@ impl InnerAddressSpace {
prot_flags,
map_flags,
move |page, count, flags, _mapper, _flusher| {
Ok(LockedVMA::new(VMA {
region: VirtRegion::new(
page.virt_address(),
count.data() * MMArch::PAGE_SIZE,
),
Ok(LockedVMA::new(VMA::new(
VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE),
vm_flags,
flags,
mapped: true,
user_address_space: None,
self_ref: Weak::default(),
provider: Provider::Allocated,
}))
false,
)))
},
)?
};
Expand Down Expand Up @@ -1033,7 +1027,6 @@ impl LockedVMA {
mut flusher: impl Flusher<MMArch>,
) -> Result<(), SystemError> {
let mut guard = self.lock();
assert!(guard.mapped);
for page in guard.region.pages() {
// 暂时要求所有的页帧都已经映射到页表
// TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
Expand All @@ -1052,7 +1045,6 @@ impl LockedVMA {
// todo: 如果当前vma与文件相关,完善文件相关的逻辑

let mut guard = self.lock();
assert!(guard.mapped);

// 获取物理页的anon_vma的守卫
let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
Expand Down Expand Up @@ -1347,7 +1339,6 @@ impl VMA {
mapper: &mut PageMapper,
mut flusher: impl Flusher<MMArch>,
) -> Result<(), SystemError> {
assert!(self.mapped);
for page in self.region.pages() {
// kdebug!("remap page {:?}", page.virt_address());
if mapper.translate(page.virt_address()).is_some() {
Expand Down Expand Up @@ -1477,18 +1468,15 @@ impl VMA {
flusher.consume(r);
cur_dest = cur_dest.next();
}
let r = LockedVMA::new(VMA {
region: VirtRegion::new(
let r = LockedVMA::new(VMA::new(
VirtRegion::new(
destination.virt_address(),
page_count.data() * MMArch::PAGE_SIZE,
),
vm_flags,
flags,
mapped: true,
user_address_space: None,
self_ref: Weak::default(),
provider: Provider::Allocated,
});
true,
));
drop(flusher);
// kdebug!("VMA::zeroed: flusher dropped");

Expand Down
Loading