From 84e07a6d83f70abffe0476331414210849031188 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 8 Mar 2019 00:03:06 +0800 Subject: [PATCH] Implement sys_mprotect and move attr setting from page_fault_handler to map in Delay --- crate/memory/src/memory_set/handler/delay.rs | 3 +- crate/memory/src/memory_set/handler/mod.rs | 6 ++++ kernel/src/syscall/mem.rs | 30 +++++++++++++++++++- kernel/src/syscall/mod.rs | 1 + 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/crate/memory/src/memory_set/handler/delay.rs b/crate/memory/src/memory_set/handler/delay.rs index e158f54..a908834 100644 --- a/crate/memory/src/memory_set/handler/delay.rs +++ b/crate/memory/src/memory_set/handler/delay.rs @@ -13,6 +13,7 @@ impl MemoryHandler for Delay { fn map(&self, pt: &mut PageTable, addr: VirtAddr) { let entry = pt.map(addr, 0); + self.flags.apply(entry); entry.set_present(false); entry.update(); } @@ -38,7 +39,7 @@ impl MemoryHandler for Delay { } let frame = self.allocator.alloc().expect("failed to alloc frame"); entry.set_target(frame); - self.flags.apply(entry); + entry.set_present(true); true } } diff --git a/crate/memory/src/memory_set/handler/mod.rs b/crate/memory/src/memory_set/handler/mod.rs index ff6951e..81922db 100644 --- a/crate/memory/src/memory_set/handler/mod.rs +++ b/crate/memory/src/memory_set/handler/mod.rs @@ -3,7 +3,13 @@ use super::*; // here may be a interesting part for lab pub trait MemoryHandler: Debug + 'static { fn box_clone(&self) -> Box; + + /// Map addr in the page table + /// Should set page flags here instead of in page_fault_handler fn map(&self, pt: &mut PageTable, addr: VirtAddr); + + /// Map addr in the page table eagerly (i.e. no delay allocation) + /// Should set page flags here instead of in page_fault_handler fn map_eager(&self, pt: &mut PageTable, addr: VirtAddr) { // override this when pages are allocated lazily self.map(pt, addr); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index a77cbc9..7ed32f4 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,5 +1,7 @@ use rcore_memory::memory_set::handler::Delay; use rcore_memory::memory_set::MemoryAttr; +use rcore_memory::paging::PageTable; +use rcore_memory::Page; use rcore_memory::PAGE_SIZE; use crate::memory::GlobalFrameAlloc; @@ -9,7 +11,7 @@ use super::*; pub fn sys_mmap(mut addr: usize, len: usize, prot: usize, flags: usize, fd: i32, offset: usize) -> SysResult { let prot = MmapProt::from_bits_truncate(prot); let flags = MmapFlags::from_bits_truncate(flags); - info!("mmap addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}", addr, len, prot, flags, fd, offset); + info!("mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}", addr, len, prot, flags, fd, offset); let mut proc = process(); if addr == 0 { @@ -31,6 +33,32 @@ pub fn sys_mmap(mut addr: usize, len: usize, prot: usize, flags: usize, fd: i32, unimplemented!() } +pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { + let prot = MmapProt::from_bits_truncate(prot); + info!("mprotect: addr={:#x}, size={:#x}, prot={:?}", addr, len, prot); + + let mut proc = process(); + let attr = prot_to_attr(prot); + + let memory_area = proc.memory_set.iter().find(|area| area.contains(addr)); + if memory_area.is_some() { + proc.memory_set.edit(|pt| { + for page in Page::range_of(addr, addr + len) { + let entry = pt.get_entry(page.start_address()).expect("failed to get entry"); + + // keep original presence + let orig_present = entry.present(); + attr.apply(entry); + entry.set_present(orig_present); + entry.update(); + } + }); + Ok(0) + } else { + Err(SysError::ENOMEM) + } +} + pub fn sys_munmap(addr: usize, len: usize) -> SysResult { info!("munmap addr={:#x}, size={:#x}", addr, len); let mut proc = process(); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 66afeba..0eb4e3a 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -46,6 +46,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 007 => sys_poll(args[0] as *mut PollFd, args[1], args[2]), 008 => sys_lseek(args[0], args[1] as i64, args[2] as u8), 009 => sys_mmap(args[0], args[1], args[2], args[3], args[4] as i32, args[5]), + 010 => sys_mprotect(args[0], args[1], args[2]), 011 => sys_munmap(args[0], args[1]), 019 => sys_readv(args[0], args[1] as *const IoVec, args[2]), 020 => sys_writev(args[0], args[1] as *const IoVec, args[2]),