rename functions. ignore readonly in mmap to avoid page fault.

master
WangRunji 6 years ago
parent ab63c933c2
commit 84c12ae6e1

@ -23,7 +23,7 @@ impl<T: FrameAllocator> MemoryHandler for ByFrame<T> {
pt.unmap(addr);
}
fn page_fault_handler(&self, _pt: &mut PageTable, _addr: VirtAddr) -> bool {
fn handle_page_fault(&self, _pt: &mut PageTable, _addr: VirtAddr) -> bool {
false
}
}

@ -34,7 +34,7 @@ impl<T: FrameAllocator> MemoryHandler for Delay<T> {
pt.unmap(addr);
}
fn page_fault_handler(&self, pt: &mut PageTable, addr: VirtAddr) -> bool {
fn handle_page_fault(&self, pt: &mut PageTable, addr: VirtAddr) -> bool {
let entry = pt.get_entry(addr).expect("failed to get entry");
if entry.present() {
// not a delay case

@ -21,7 +21,7 @@ impl MemoryHandler for Linear {
pt.unmap(addr);
}
fn page_fault_handler(&self, _pt: &mut PageTable, _addr: VirtAddr) -> bool {
fn handle_page_fault(&self, _pt: &mut PageTable, _addr: VirtAddr) -> bool {
false
}
}

@ -20,7 +20,7 @@ pub trait MemoryHandler: Debug + 'static {
/// Handle page fault on `addr`
/// Return true if success, false if error
fn page_fault_handler(&self, pt: &mut PageTable, addr: VirtAddr) -> bool;
fn handle_page_fault(&self, pt: &mut PageTable, addr: VirtAddr) -> bool;
}
impl Clone for Box<MemoryHandler> {

@ -375,10 +375,10 @@ impl<T: InactivePageTable> MemorySet<T> {
&mut self.page_table
}
pub fn page_fault_handler(&mut self, addr: VirtAddr) -> bool {
pub fn handle_page_fault(&mut self, addr: VirtAddr) -> bool {
let area = self.areas.iter().find(|area| area.contains(addr));
match area {
Some(area) => self.page_table.edit(|pt| area.handler.page_fault_handler(pt, addr)),
Some(area) => self.page_table.edit(|pt| area.handler.handle_page_fault(pt, addr)),
None => false,
}
}

@ -94,7 +94,7 @@ fn handle_syscall(num: u16, tf: &mut TrapFrame) {
fn handle_page_fault(tf: &mut TrapFrame) {
let addr = FAR_EL1.get() as usize;
if !crate::memory::page_fault_handler(addr) {
if !crate::memory::handle_page_fault(addr) {
error!("\nEXCEPTION: Page Fault @ {:#x}", addr);
crate::trap::error(tf);
}

@ -194,7 +194,7 @@ fn page_fault(tf: &mut TrapFrame) {
let addr = tf.stval;
trace!("\nEXCEPTION: Page Fault @ {:#x}", addr);
if !crate::memory::page_fault_handler(addr) {
if !crate::memory::handle_page_fault(addr) {
crate::trap::error(tf);
}
}

@ -67,6 +67,7 @@
use super::consts::*;
use super::TrapFrame;
use log::*;
use bitflags::*;
use crate::drivers::DRIVERS;
global_asm!(include_str!("trap.asm"));
@ -124,10 +125,21 @@ fn page_fault(tf: &mut TrapFrame) {
let addr: usize;
unsafe { asm!("mov %cr2, $0" : "=r" (addr)); }
if crate::memory::page_fault_handler(addr) {
bitflags! {
struct PageError: u8 {
const PRESENT = 1 << 0;
const WRITE = 1 << 1;
const USER = 1 << 2;
const RESERVED_WRITE = 1 << 3;
const INST = 1 << 4;
}
}
let code = PageError::from_bits(tf.error_code as u8).unwrap();
if crate::memory::handle_page_fault(addr) {
return;
}
error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:#x}", addr, tf.error_code);
error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:?}", addr, code);
error(tf);
}

@ -101,9 +101,9 @@ impl Drop for KernelStack {
/// Handle page fault at `addr`.
/// Return true to continue, false to halt.
#[cfg(not(feature = "no_mmu"))]
pub fn page_fault_handler(addr: usize) -> bool {
info!("start handling swap in/out page fault, badva={:x}", addr);
process().memory_set.page_fault_handler(addr)
pub fn handle_page_fault(addr: usize) -> bool {
debug!("page fault @ {:#x}", addr);
process().memory_set.handle_page_fault(addr)
}
pub fn init_heap() {
@ -127,6 +127,6 @@ impl rcore_memory::no_mmu::NoMMUSupport for NoMMUSupportImpl {
}
#[cfg(feature = "no_mmu")]
pub fn page_fault_handler(_addr: usize) -> bool {
pub fn handle_page_fault(_addr: usize) -> bool {
unreachable!()
}

@ -194,12 +194,11 @@ impl Thread {
/// Fork a new process from current one
pub fn fork(&self, tf: &TrapFrame) -> Box<Thread> {
info!("COME into fork!");
// Clone memory set, make a new page table
let memory_set = self.proc.lock().memory_set.clone();
let files = self.proc.lock().files.clone();
let cwd = self.proc.lock().cwd.clone();
info!("finish mmset clone in fork!");
debug!("fork: finish clone MemorySet");
// MMU: copy data to the new space
// NoMMU: coping data has been done in `memory_set.clone()`
@ -211,7 +210,7 @@ impl Thread {
}) }
}
info!("temporary copy data!");
debug!("fork: temporary copy data!");
let kstack = KernelStack::new();
let iface = &*(NET_DRIVERS.read()[0]);
@ -250,7 +249,7 @@ impl Thread {
}
impl Process {
pub fn get_free_inode(&self) -> usize {
pub fn get_free_fd(&self) -> usize {
(0..).find(|i| !self.files.contains_key(i)).unwrap()
}
pub fn get_futex(&mut self, uaddr: usize) -> Arc<Condvar> {
@ -265,7 +264,7 @@ impl Process {
/// Generate a MemorySet according to the ELF file.
/// Also return the real entry point address.
fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) {
debug!("come in to memory_set_from");
debug!("creating MemorySet from ELF");
let mut ms = MemorySet::new();
let mut entry = elf.header.pt2.entry_point() as usize;
@ -300,7 +299,7 @@ fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) {
#[cfg(feature = "no_mmu")]
let target = &mut target[virt_addr - va_begin..virt_addr - va_begin + mem_size];
#[cfg(feature = "no_mmu")]
info!("area @ {:?}, size = {:#x}", target.as_ptr(), mem_size);
debug!("area @ {:?}, size = {:#x}", target.as_ptr(), mem_size);
#[cfg(not(feature = "no_mmu"))]
let target = {
ms.push(virt_addr, virt_addr + mem_size, ph.flags().to_attr(), ByFrame::new(GlobalFrameAlloc), "");

@ -316,7 +316,7 @@ pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult {
}
};
let fd = proc.get_free_inode();
let fd = proc.get_free_fd();
let file = FileHandle::new(inode, flags.to_options());
proc.files.insert(fd, FileLike::File(file));
@ -545,12 +545,12 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
let mut proc = process();
proc.memory_set.check_mut_array(fds, 2)?;
let (read, write) = Pipe::create_pair();
let read_fd = proc.get_free_inode();
let read_fd = proc.get_free_fd();
let read_fd = proc.get_free_inode();
let read_fd = proc.get_free_fd();
proc.files.insert(read_fd, FileLike::File(FileHandle::new(Arc::new(read), OpenOptions { read: true, write: false, append: false })));
let write_fd = proc.get_free_inode();
let write_fd = proc.get_free_fd();
proc.files.insert(write_fd, FileLike::File(FileHandle::new(Arc::new(write), OpenOptions { read: false, write: true, append: false })));
Ok(0)

@ -97,7 +97,8 @@ impl MmapProt {
fn to_attr(self) -> MemoryAttr {
let mut attr = MemoryAttr::default().user();
if self.contains(MmapProt::EXEC) { attr = attr.execute(); }
if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); }
// FIXME: see sys_mprotect
// if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); }
attr
}
}

@ -73,8 +73,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
if uaddr % size_of::<u32>() != 0 {
return Err(SysError::EINVAL);
}
// FIXME: check uaddr, see sys_mprotect
// process().memory_set.check_mut_ptr(uaddr)?;
process().memory_set.check_mut_ptr(uaddr as *mut AtomicI32)?;
let atomic = unsafe { &mut *(uaddr as *mut AtomicI32) };
let timeout = if timeout.is_null() {
None

@ -40,7 +40,7 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu
match domain {
AF_INET | AF_UNIX => match socket_type & SOCK_TYPE_MASK {
SOCK_STREAM => {
let fd = proc.get_free_inode();
let fd = proc.get_free_fd();
let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; 2048]);
let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; 2048]);
@ -58,7 +58,7 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu
Ok(fd)
}
SOCK_DGRAM => {
let fd = proc.get_free_inode();
let fd = proc.get_free_fd();
let udp_rx_buffer =
UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 2048]);
@ -78,7 +78,7 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu
Ok(fd)
}
SOCK_RAW => {
let fd = proc.get_free_inode();
let fd = proc.get_free_fd();
let raw_rx_buffer =
RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; 2], vec![0; 2048]);
@ -599,7 +599,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
// move the current one to new_fd
// create a new one in fd
let new_fd = proc.get_free_inode();
let new_fd = proc.get_free_fd();
let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; 2048]);
let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; 2048]);

@ -11,7 +11,8 @@ pub fn sys_fork(tf: &TrapFrame) -> SysResult {
}
/// Create a new thread in the current process.
/// The new thread's stack pointer will be set to `newsp`.
/// The new thread's stack pointer will be set to `newsp`,
/// and thread pointer will be set to `newtls`.
/// The child tid will be stored at both `parent_tid` and `child_tid`.
/// This is partially implemented for musl only.
pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut u32, child_tid: *mut u32, newtls: usize, tf: &TrapFrame) -> SysResult {
@ -22,10 +23,9 @@ pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut u32, child_tid: *m
return Err(SysError::ENOSYS);
}
{
// FIXME: see sys_mprotect
// let proc = process();
// proc.memory_set.check_mut_ptr(parent_tid)?;
// proc.memory_set.check_mut_ptr(child_tid)?;
let proc = process();
proc.memory_set.check_mut_ptr(parent_tid)?;
proc.memory_set.check_mut_ptr(child_tid)?;
}
let new_thread = current_thread().clone(tf, newsp, newtls, child_tid as usize);
// FIXME: parent pid

Loading…
Cancel
Save