WIP: Support clone in userspace

Everything seems to work for the most part, but now there are tons of
daemons which rely on syscall::clone, which is now implemented in relibc
:(
This commit is contained in:
4lDO2
2022-07-05 12:26:30 +02:00
parent 283ada82a0
commit b50495bfa5
6 changed files with 237 additions and 93 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ pub struct Context {
/// Base pointer
rbp: usize,
/// Stack pointer
rsp: usize,
pub(crate) rsp: usize,
/// FSBASE.
///
/// NOTE: Same fsgsbase behavior as with gsbase.
+15 -3
View File
@@ -12,7 +12,7 @@ use core::{
};
use spin::RwLock;
use crate::arch::{interrupt::InterruptStack, paging::PAGE_SIZE};
use crate::arch::{interrupt::InterruptStack, paging::{PAGE_SIZE, RmmA, RmmArch}};
use crate::common::unique::Unique;
use crate::context::arch;
use crate::context::file::{FileDescriptor, FileDescription};
@@ -250,6 +250,11 @@ pub struct Context {
/// else than SIG_DFL, otherwise signals will not be delivered. Userspace is responsible for
/// setting this.
pub sigstack: Option<usize>,
/// An even hackier way to pass the return entry point and stack pointer to new contexts while
/// implementing clone. Before a context has returned to userspace, its IntRegisters cannot be
/// set since there is no interrupt stack (unless the kernel stack is copied, but that is in my
/// opinion hackier and less efficient than this (and UB to do in Rust)).
pub clone_entry: Option<[usize; 2]>,
}
// Necessary because GlobalAlloc::dealloc requires the layout to be the same, and therefore Box
@@ -352,6 +357,7 @@ impl Context {
regs: None,
ptrace_stop: false,
sigstack: None,
clone_entry: None,
};
this.set_addr_space(new_addrspace()?.1);
Ok(this)
@@ -528,8 +534,14 @@ impl Context {
self.addr_space.as_ref().ok_or(Error::new(ESRCH))
}
pub fn set_addr_space(&mut self, addr_space: Arc<RwLock<AddrSpace>>) {
assert!(!self.running);
self.arch.set_page_utable(addr_space.read().frame.utable.start_address().data());
let physaddr = addr_space.read().frame.utable.start_address();
if self.running {
unsafe {
RmmA::set_table(physaddr);
}
}
self.arch.set_page_utable(physaddr.data());
self.addr_space = Some(addr_space);
}
}
+6 -4
View File
@@ -77,8 +77,7 @@ impl AddrSpace {
// TODO: Abstract away this.
let (mut inactive, mut active);
// TODO: aarch64
let mut this_mapper = if self.frame.utable.start_address().data() == unsafe { x86::controlregs::cr3() } as usize {
let mut this_mapper = if self.is_current() {
active = unsafe { ActivePageTable::new(rmm::TableKind::User) };
active.mapper()
} else {
@@ -95,8 +94,8 @@ impl AddrSpace {
for page in new_grant.pages() {
// FIXME: ENOMEM is wrong here, it cannot fail.
let current_frame = this_mapper.translate_page(page).ok_or(Error::new(ENOMEM))?.start_address().data() as *const u8;
let new_frame = new_mapper.mapper().translate_page(page).ok_or(Error::new(ENOMEM))?.start_address().data() as *mut u8;
let current_frame = unsafe { RmmA::phys_to_virt(this_mapper.translate_page(page).ok_or(Error::new(ENOMEM))?.start_address()) }.data() as *const u8;
let new_frame = unsafe { RmmA::phys_to_virt(new_mapper.mapper().translate_page(page).ok_or(Error::new(ENOMEM))?.start_address()) }.data() as *mut u8;
// TODO: Replace this with CoW
unsafe {
@@ -115,6 +114,9 @@ impl AddrSpace {
id,
})
}
pub fn is_current(&self) -> bool {
self.frame.utable.start_address() == unsafe { RmmA::table() }
}
}
#[derive(Debug)]