mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 02:46:47 +00:00
修复vma映射标志错误 (#801)
This commit is contained in:
parent
7db6e06354
commit
17dc558977
@ -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;
|
pub struct PageFaultHandler;
|
||||||
|
|
||||||
@ -167,27 +177,30 @@ impl PageFaultHandler {
|
|||||||
let address = pfm.address_aligned_down();
|
let address = pfm.address_aligned_down();
|
||||||
let flags = pfm.flags;
|
let flags = pfm.flags;
|
||||||
let vma = pfm.vma.clone();
|
let vma = pfm.vma.clone();
|
||||||
|
let mut ret = VmFaultReason::VM_FAULT_COMPLETED;
|
||||||
if let Some(mut entry) = mapper.get_entry(address, 0) {
|
if let Some(mut entry) = mapper.get_entry(address, 0) {
|
||||||
if !entry.present() {
|
if !entry.present() {
|
||||||
return Self::do_swap_page(pfm, mapper);
|
ret = Self::do_swap_page(pfm.clone(), mapper);
|
||||||
}
|
}
|
||||||
if entry.protnone() && vma.is_accessible() {
|
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 flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) {
|
||||||
if !entry.write() {
|
if !entry.write() {
|
||||||
return Self::do_wp_page(pfm, mapper);
|
ret = Self::do_wp_page(pfm.clone(), mapper);
|
||||||
} else {
|
} else {
|
||||||
entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
|
entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if vma.is_anonymous() {
|
} else if vma.is_anonymous() {
|
||||||
return Self::do_anonymous_page(pfm, mapper);
|
ret = Self::do_anonymous_page(pfm.clone(), mapper);
|
||||||
} else {
|
} 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理匿名映射页缺页异常
|
/// 处理匿名映射页缺页异常
|
||||||
|
@ -299,18 +299,12 @@ impl InnerAddressSpace {
|
|||||||
prot_flags,
|
prot_flags,
|
||||||
map_flags,
|
map_flags,
|
||||||
move |page, count, flags, _mapper, _flusher| {
|
move |page, count, flags, _mapper, _flusher| {
|
||||||
Ok(LockedVMA::new(VMA {
|
Ok(LockedVMA::new(VMA::new(
|
||||||
region: VirtRegion::new(
|
VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE),
|
||||||
page.virt_address(),
|
|
||||||
count.data() * MMArch::PAGE_SIZE,
|
|
||||||
),
|
|
||||||
vm_flags,
|
vm_flags,
|
||||||
flags,
|
flags,
|
||||||
mapped: true,
|
false,
|
||||||
user_address_space: None,
|
)))
|
||||||
self_ref: Weak::default(),
|
|
||||||
provider: Provider::Allocated,
|
|
||||||
}))
|
|
||||||
},
|
},
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
@ -1033,7 +1027,6 @@ impl LockedVMA {
|
|||||||
mut flusher: impl Flusher<MMArch>,
|
mut flusher: impl Flusher<MMArch>,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
let mut guard = self.lock();
|
let mut guard = self.lock();
|
||||||
assert!(guard.mapped);
|
|
||||||
for page in guard.region.pages() {
|
for page in guard.region.pages() {
|
||||||
// 暂时要求所有的页帧都已经映射到页表
|
// 暂时要求所有的页帧都已经映射到页表
|
||||||
// TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
|
// TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
|
||||||
@ -1052,7 +1045,6 @@ impl LockedVMA {
|
|||||||
// todo: 如果当前vma与文件相关,完善文件相关的逻辑
|
// todo: 如果当前vma与文件相关,完善文件相关的逻辑
|
||||||
|
|
||||||
let mut guard = self.lock();
|
let mut guard = self.lock();
|
||||||
assert!(guard.mapped);
|
|
||||||
|
|
||||||
// 获取物理页的anon_vma的守卫
|
// 获取物理页的anon_vma的守卫
|
||||||
let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
|
let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
|
||||||
@ -1347,7 +1339,6 @@ impl VMA {
|
|||||||
mapper: &mut PageMapper,
|
mapper: &mut PageMapper,
|
||||||
mut flusher: impl Flusher<MMArch>,
|
mut flusher: impl Flusher<MMArch>,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
assert!(self.mapped);
|
|
||||||
for page in self.region.pages() {
|
for page in self.region.pages() {
|
||||||
// kdebug!("remap page {:?}", page.virt_address());
|
// kdebug!("remap page {:?}", page.virt_address());
|
||||||
if mapper.translate(page.virt_address()).is_some() {
|
if mapper.translate(page.virt_address()).is_some() {
|
||||||
@ -1477,18 +1468,15 @@ impl VMA {
|
|||||||
flusher.consume(r);
|
flusher.consume(r);
|
||||||
cur_dest = cur_dest.next();
|
cur_dest = cur_dest.next();
|
||||||
}
|
}
|
||||||
let r = LockedVMA::new(VMA {
|
let r = LockedVMA::new(VMA::new(
|
||||||
region: VirtRegion::new(
|
VirtRegion::new(
|
||||||
destination.virt_address(),
|
destination.virt_address(),
|
||||||
page_count.data() * MMArch::PAGE_SIZE,
|
page_count.data() * MMArch::PAGE_SIZE,
|
||||||
),
|
),
|
||||||
vm_flags,
|
vm_flags,
|
||||||
flags,
|
flags,
|
||||||
mapped: true,
|
true,
|
||||||
user_address_space: None,
|
));
|
||||||
self_ref: Weak::default(),
|
|
||||||
provider: Provider::Allocated,
|
|
||||||
});
|
|
||||||
drop(flusher);
|
drop(flusher);
|
||||||
// kdebug!("VMA::zeroed: flusher dropped");
|
// kdebug!("VMA::zeroed: flusher dropped");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user