Skip to content
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
3 changes: 3 additions & 0 deletions crates/init/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ mkdir -p fs
# cp shell.elf fs/
# ./ls.rs
# cp ls.elf fs/
./sharedMemTest.rs
cp sharedMemTest.elf fs/


cargo run -q -p initfs --bin util \
-- create --compress --out fs.arc --root fs fs --verbose
Expand Down
1 change: 1 addition & 0 deletions crates/init/fs/test2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello worldaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahello world
158 changes: 158 additions & 0 deletions crates/init/sharedMemTest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env bash
#![doc = r##"<!-- Absolutely cursed hacks:
SOURCE="$0" NAME=$(basename "$0" .rs) DIR=$(realpath $(dirname "$0"))
exec "$(dirname "$0")/../ulib/compile.sh" "$0" <<END_MANIFEST
[package]
name = "$NAME"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "$NAME"
path = "$DIR/$NAME.rs"

[dependencies]
ulib = { path = "$DIR/../ulib" }

[profile.standalone]
inherits = "release"
opt-level = 0
panic = "abort"
strip = "debuginfo"

END_MANIFEST
exit # -->"##]
#![no_std]
#![no_main]

#[macro_use]
extern crate ulib;

use ulib::sys::{openat, close, mmap, munmap, wait, exit, MAP_PRIVATE, MAP_SHARED, MAP_FILE};

#[no_mangle]
fn main() {

let root_fd = 3;

let test_file_path = b"test.txt";
let mut test_text_file = openat(root_fd, test_file_path, 0, 0).unwrap();

static HELLO_CHARS: [u8; 5] = *b"hello";
static WORLD_CHARS: [u8; 5] = *b"world";

let mut mmap_addr: *mut u8 =
unsafe { mmap(0, 4096, 0, MAP_PRIVATE | MAP_FILE, test_text_file, 0).unwrap() } as *mut u8;
println!("Memory range is mmaped!");

for i in 0..5 {
let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i)) };
if curr_char != HELLO_CHARS[i] {
panic!(
"mmap filed file has an error at index {}! Expected {} got {}",
i, HELLO_CHARS[i] as char, curr_char as char
);
}
}

println!("mmap of test file succeeded!");
unsafe { munmap(mmap_addr as *mut ()).unwrap() };
_ = close(test_text_file);

println!("starting mmap with offset test 1");
let test_file_path2 = b"test2.txt";
test_text_file = openat(root_fd, test_file_path2, 0, 0).unwrap();
mmap_addr =
unsafe { mmap(0, 4096 * 2, 0, MAP_PRIVATE | MAP_FILE, test_text_file, 6).unwrap() } as *mut u8;
println!("mmap addr: {:x}", mmap_addr as usize);

for i in 0..5 {
let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i)) };
if curr_char != WORLD_CHARS[i] {
panic!(
"mmap filed file has an error at index {}! Expected {} got {}",
i, WORLD_CHARS[i] as char, curr_char as char
);
}
}

println!("done with mmap with offset test 1");

println!("starting mmap with offset test 2");
for i in 0..5 {
let curr_char: u8 = unsafe { *(mmap_addr.wrapping_add(i + 4096)) };
if curr_char != WORLD_CHARS[i] {
panic!(
"mmap filed file has an error at index {}! Expected {} got {}",
i, WORLD_CHARS[i] as char, curr_char as char
);
}
}

println!("done with mmap with offset test 2");
unsafe { munmap(mmap_addr as *mut ()).unwrap() };
_ = close(test_text_file);

println!("Starting shared memory test");

let shared_mem_fd = unsafe { ulib::sys::sys_memfd_create() as u32 };
let shared_frame =
unsafe { ulib::sys::mmap(0, 4096, 0, MAP_SHARED, shared_mem_fd, 0) }.unwrap() as *mut u8;
let end_ptr: *mut u8 = shared_frame.wrapping_add(6);
unsafe { end_ptr.write_volatile('.' as u8) };
assert_eq!(unsafe { end_ptr.read_volatile() }, '.' as u8);

println!("Calling fork");
let wait_fd = unsafe { ulib::sys::sys_fork() } as u32;

if wait_fd == 0 {
for _i in 0..1000000 {
if unsafe { end_ptr.read_volatile() } == ('!' as u8) {
break;
}
}

let end_val: u8 = unsafe { end_ptr.read_volatile() };
if end_val != ('!' as u8) {
println!(
"Error: child expected to see '!' with val {} and instead found {}",
('!' as u8),
end_val
);
ulib::sys::exit(5);
}

for i in 0..5 {
let curr_char = unsafe { *shared_frame.wrapping_add(i) } as char;
if curr_char != (HELLO_CHARS[i] as char) {
println!(
"Child found wrong char at index {}. Expected {} found {}",
i,
(HELLO_CHARS[i] as char),
curr_char
);
ulib::sys::exit(5);
}
}

println!("Child is done");
ulib::sys::exit(0);
} else {
unsafe {
core::ptr::copy_nonoverlapping(
&raw const HELLO_CHARS[0],
shared_frame,
HELLO_CHARS.len(),
);
shared_frame.wrapping_add(6).write('!' as u8);
}

let child_exit_val = wait(wait_fd).unwrap();
assert_eq!(child_exit_val, 0);
println!("done with shared memory test, parent received exit code 0 from child");
}

_ = unsafe { munmap(shared_frame as *mut ()) };

exit(15);
}
24 changes: 22 additions & 2 deletions crates/kernel/src/fs/initfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use initfs::{Archive, ArchiveError};

use crate::arch::memory::palloc::{Size4KiB, PAGE_ALLOCATOR};
use crate::process::fd::{
boxed_future, ArcFd, DirEntry, FileDescResult, FileDescriptor, FileKind, SmallFuture,
};
Expand Down Expand Up @@ -252,8 +253,27 @@ impl FileDescriptor for InitFsFile {
boxed_future(async move { Err(()) })
}
}
fn mmap_page(&self, _offset: u64) -> SmallFuture<Option<FileDescResult>> {
boxed_future(async move { None })
fn mmap_page(&self, offset: u64) -> SmallFuture<Option<FileDescResult>> {
if self.header.is_dir() {
return boxed_future(async move { None });
}

//File case, need to call read
boxed_future(async move {
let page = PAGE_ALLOCATOR.get().alloc_mapped_frame::<Size4KiB>();
let page_paddr = page.paddr;
let page_virt = PAGE_ALLOCATOR.get().get_mapped_frame::<Size4KiB>(page);
let buf_ref = unsafe { core::slice::from_raw_parts_mut(page_virt as *mut u8, 4096) };
match self.read(offset, buf_ref).await.as_result() {
Ok(_val) => {
return Some(FileDescResult::ok(page_paddr as u64));
}
Err(_val) => {
println!("Read failed");
return None;
}
}
})
}
fn as_any(&self) -> &dyn core::any::Any {
self
Expand Down
44 changes: 37 additions & 7 deletions crates/kernel/src/process/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use crate::event::context::Context;
use crate::event::exceptions::DataAbortISS;
use crate::syscall::proc::exit_user_thread;

use crate::syscall::fb_hack::MemFd;

use super::fd::ArcFd;

#[derive(Debug)]
Expand All @@ -38,7 +40,7 @@ pub struct MemoryRangeNode {
#[derive(Clone)]
pub enum MappingKind {
Anon,
File(ArcFd),
File { fd: ArcFd, offset: usize },
}

impl UserAddrSpace {
Expand Down Expand Up @@ -94,6 +96,13 @@ impl UserAddrSpace {
.await
.unwrap();

//Don't want to copy data in shared mem
if let MappingKind::File { fd, .. } = &node.kind {
if let Some(_s) = fd.as_any().downcast_ref::<MemFd>() {
continue;
}
}

let src_data = node.start as *const u8;
let dst_data = node.start as *mut u8;
let buf_ptr: *mut u8 = buffer.as_mut_ptr().cast();
Expand Down Expand Up @@ -194,18 +203,29 @@ impl UserAddrSpace {
};

let leaf = unsafe { desc.leaf };

if leaf.is_valid() {
let new_desc = TranslationDescriptor::unset();
unsafe {
set_translation_descriptor(self.table, virt_addr, 3, 0, new_desc, false)
.unwrap()
}
//Need this invalidation here or it still accesses old page
unsafe {
core::arch::asm! {
"dsb ISH",
"tlbi vaae1, {0}",
in(reg) (virt_addr >> 12)
//options(readonly, nostack, preserves_flags)
}
}

// TODO: free it
match &vme.kind {
MappingKind::Anon => {
// TODO: free
}
MappingKind::File(_arc) => {
MappingKind::File { .. } => {
// TODO: notify file that it's unused?
// (for ref counts, page cache?)
}
Expand Down Expand Up @@ -254,12 +274,23 @@ impl UserAddrSpace {

desc
}
MappingKind::File(fd) => {
MappingKind::File {
fd: arc_fd,
offset: file_offset,
} => {
let offset = vaddr - vme.start;
let page = match fd.mmap_page(offset as u64).await.map(|r| r.as_result()) {
let page = match arc_fd
.mmap_page(offset as u64 + (*file_offset as u64))
.await
.map(|r| r.as_result())
{
Some(Ok(page)) => page,
Some(Err(_e)) => return Err(MmapError::FileError),
None => return Err(MmapError::FileError),
Some(Err(_e)) => {
return Err(MmapError::FileError);
}
None => {
return Err(MmapError::FileError);
}
};
let desc = LeafDescriptor::new(page as usize)
.union(LeafDescriptor::UNPRIVILEGED_ACCESS)
Expand Down Expand Up @@ -310,7 +341,6 @@ unsafe impl Sync for UserAddrSpace {}
pub fn page_fault_handler(ctx: &mut Context, far: usize, _iss: DataAbortISS) -> *mut Context {
run_async_handler(ctx, async move |mut context: HandlerContext<'_>| {
let proc = context.cur_process().unwrap();

// TODO: make sure misaligned loads don't loop here?
let page_addr = (far / PAGE_SIZE) * PAGE_SIZE;

Expand Down
2 changes: 1 addition & 1 deletion crates/kernel/src/syscall/fb_hack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub unsafe fn sys_memfd_create(ctx: &mut Context) -> *mut Context {
})
}

struct MemFd {
pub struct MemFd {
pages: SpinLock<BTreeMap<usize, PhysicalPage<Size4KiB>>>,
}

Expand Down
10 changes: 6 additions & 4 deletions crates/kernel/src/syscall/mmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ bitflags::bitflags! {
}
struct MmapFlags: u32 {
const MAP_FIXED = 1 << 0;
const MAP_ANONYMOUS = 1 << 1;
const MAP_ANONYMOUS = 1 << 1; //if not set this indicates file
const MAP_SHARED = 1 << 2; //if not set indicates private mapping
}
}

Expand All @@ -32,12 +33,13 @@ pub unsafe fn sys_mmap(ctx: &mut Context) -> *mut Context {
};

let fd = ctx.regs[4];
// TODO: File offset
let _offset = ctx.regs[5];
let offset = ctx.regs[5];

run_async_handler(ctx, async move |mut context: HandlerContext<'_>| {
let proc = context.cur_process().unwrap();

let _is_shared: bool = flags.contains(MmapFlags::MAP_SHARED);

let kind = if flags.contains(MmapFlags::MAP_ANONYMOUS) {
MappingKind::Anon
} else {
Expand All @@ -46,7 +48,7 @@ pub unsafe fn sys_mmap(ctx: &mut Context) -> *mut Context {
context.regs().regs[0] = i64::from(-1) as usize;
return context.resume_final();
};
MappingKind::File(file)
MappingKind::File { fd: file, offset }
};

let res;
Expand Down
1 change: 0 additions & 1 deletion crates/kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ pub unsafe fn register_syscalls() {

register_syscall_handler(21, time::sys_get_time_ms);
register_syscall_handler(22, time::sys_sleep_ms);

register_syscall_handler(23, fb_hack::sys_acquire_fb);
register_syscall_handler(24, fb_hack::sys_memfd_create);
register_syscall_handler(25, fb_hack::sys_poll_key_event);
Expand Down
Loading