Skip to content
Open
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
2 changes: 1 addition & 1 deletion etc/syscalls_linux_aarch64.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@
| 0x114 (276) | renameat2 | (int olddfd, const char *oldname, int newdfd, const char *newname, unsigned int flags) | __arm64_sys_renameat2 | true |
| 0x115 (277) | seccomp | (unsigned int op, unsigned int flags, void *uargs) | __arm64_sys_seccomp | false |
| 0x116 (278) | getrandom | (char *ubuf, size_t len, unsigned int flags) | __arm64_sys_getrandom | true |
| 0x117 (279) | memfd_create | (const char *uname, unsigned int flags) | __arm64_sys_memfd_create | false |
| 0x117 (279) | memfd_create | (const char *uname, unsigned int flags) | __arm64_sys_memfd_create | true |
| 0x118 (280) | bpf | (int cmd, union bpf_attr *uattr, unsigned int size) | __arm64_sys_bpf | false |
| 0x119 (281) | execveat | (int fd, const char *filename, const char *const *argv, const char *const *envp, int flags) | __arm64_sys_execveat | false |
| 0x11a (282) | userfaultfd | (int flags) | __arm64_sys_userfaultfd | false |
Expand Down
3 changes: 3 additions & 0 deletions src/arch/arm64/exceptions/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
},
fs::{
dir::sys_getdents64,
memfd::sys_memfd_create,
pipe::sys_pipe2,
syscalls::{
at::{
Expand Down Expand Up @@ -755,6 +756,8 @@ pub async fn handle_syscall(mut ctx: ProcessCtx) {
.await
}
0x116 => sys_getrandom(TUA::from_value(arg1 as _), arg2 as _, arg3 as _).await,
0x117 => sys_memfd_create(&ctx, TUA::from_value(arg1 as _), arg2 as _).await,
0x118 => Err(KernelError::NotSupported),
0x11d => {
sys_copy_file_range(
&ctx,
Expand Down
107 changes: 107 additions & 0 deletions src/fs/memfd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use crate::fs::fops::FileOps;
use crate::fs::open_file::{FileCtx, OpenFile};
use crate::memory::uaccess::{copy_from_user_slice, copy_to_user_slice};
use crate::process::fd_table::FdFlags;
use crate::sched::syscall_ctx::ProcessCtx;
use crate::sync::Mutex;
use alloc::boxed::Box;
use alloc::sync::Arc;
use alloc::vec::Vec;
use async_trait::async_trait;
use core::ffi::c_char;
use libkernel::fs::{OpenFlags, SeekFrom};
use libkernel::memory::address::{TUA, UA};

pub struct MemFd {
data: Mutex<Vec<u8>>,
}

impl MemFd {
fn new() -> Self {
Self {
data: Mutex::new(Vec::new()),
}
}
}

#[async_trait]
impl FileOps for MemFd {
async fn readat(
&mut self,
buf: UA,
count: usize,
offset: u64,
) -> libkernel::error::Result<usize> {
if count == 0 {
return Ok(0);
}
let data = self.data.lock().await;
let offset = offset as usize;
if offset >= data.len() {
return Ok(0);
}
let available = data.len() - offset;
let read_len = available.min(count);
copy_to_user_slice(&data[offset..offset + read_len], buf).await?;
Ok(read_len)
}

async fn writeat(
&mut self,
buf: UA,
count: usize,
offset: u64,
) -> libkernel::error::Result<usize> {
if count == 0 {
return Ok(0);
}
let mut data = self.data.lock().await;
let offset = offset as usize;
let end = offset + count;
if end > data.len() {
data.resize(end, 0);
}
copy_from_user_slice(buf, &mut data[offset..end]).await?;
Ok(count)
}

async fn truncate(&mut self, _ctx: &FileCtx, new_size: usize) -> libkernel::error::Result<()> {
let mut data = self.data.lock().await;
data.resize(new_size, 0);
Ok(())
}

async fn seek(&mut self, ctx: &mut FileCtx, pos: SeekFrom) -> libkernel::error::Result<u64> {
fn saturating_add_signed(u: u64, i: i64) -> u64 {
if i >= 0 {
u.saturating_add(i as u64)
} else {
u.saturating_sub((-i) as u64)
}
}

let size = self.data.lock().await.len() as u64;
ctx.pos = match pos {
SeekFrom::Start(x) => x,
SeekFrom::End(x) => saturating_add_signed(size, x),
SeekFrom::Current(x) => saturating_add_signed(ctx.pos, x),
};

Ok(ctx.pos)
}
}

pub async fn sys_memfd_create(
ctx: &ProcessCtx,
_name: TUA<c_char>,
_flags: u32,
) -> libkernel::error::Result<usize> {
let memfd = MemFd::new();
let open_file = Arc::new(OpenFile::new(Box::new(memfd), OpenFlags::empty()));
Ok(ctx
.shared()
.fd_table
.lock_save_irq()
.insert_with_flags(open_file, FdFlags::empty())?
.as_raw() as usize)
}
1 change: 1 addition & 0 deletions src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use reg::RegFile;

pub mod dir;
pub mod fops;
pub mod memfd;
pub mod open_file;
pub mod pipe;
pub mod reg;
Expand Down
Loading