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
6 changes: 3 additions & 3 deletions etc/syscalls_linux_aarch64.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
| 0x24 (36) | symlinkat | (const char *oldname, int newdfd, const char *newname) | __arm64_sys_symlinkat | true |
| 0x25 (37) | linkat | (int olddfd, const char *oldname, int newdfd, const char *newname, int flags) | __arm64_sys_linkat | true |
| 0x26 (38) | renameat | (int olddfd, const char *oldname, int newdfd, const char *newname) | __arm64_sys_renameat | true |
| 0x27 (39) | umount | (char *name, int flags) | __arm64_sys_umount | false |
| 0x27 (39) | umount | (char *name, int flags) | __arm64_sys_umount | true |
| 0x28 (40) | mount | (char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) | __arm64_sys_mount | partial |
| 0x29 (41) | pivot_root | (const char *new_root, const char *put_old) | __arm64_sys_pivot_root | false |
| 0x29 (41) | pivot_root | (const char *new_root, const char *put_old) | __arm64_sys_pivot_root | partial |
| 0x2b (43) | statfs | (const char *pathname, struct statfs *buf) | __arm64_sys_statfs | partial |
| 0x2c (44) | fstatfs | (unsigned int fd, struct statfs *buf) | __arm64_sys_fstatfs | partial |
| 0x2d (45) | truncate | (const char *path, long length) | __arm64_sys_truncate | true |
Expand Down Expand Up @@ -158,7 +158,7 @@
| 0x9b (155) | getpgid | (pid_t pid) | __arm64_sys_getpgid | true |
| 0x9c (156) | getsid | (pid_t pid) | __arm64_sys_getsid | true |
| 0x9d (157) | setsid | () | __arm64_sys_setsid | true |
| 0x9e (158) | getgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_getgroups | false |
| 0x9e (158) | getgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_getgroups | stub |
| 0x9f (159) | setgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_setgroups | false |
| 0xa0 (160) | newuname | (struct new_utsname *name) | __arm64_sys_newuname | true |
| 0xa1 (161) | sethostname | (char *name, int len) | __arm64_sys_sethostname | true |
Expand Down
77 changes: 72 additions & 5 deletions libkernel/src/arch/arm64/memory/pg_walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

use super::{
pg_descriptors::L3Descriptor,
pg_tables::{L0Table, L3Table},
pg_tables::{L0Table, L1Table, L3Table},
};
use crate::{
error::{MapError, Result},
memory::{
PAGE_SIZE,
address::{TPA, VA},
address::{PA, TPA, VA},
paging::{
NullTlbInvalidator, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
walk::{RecursiveWalker, WalkContext},
NullTlbInvalidator, PaMapper, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
TableMapper,
permissions::PtePermissions,
walk::{RecursiveWalker, Translator, WalkContext},
},
region::VirtMemoryRegion,
region::{PhysMemoryRegion, VirtMemoryRegion},
},
};

Expand Down Expand Up @@ -111,6 +113,71 @@ pub fn get_pte<PM: PageTableMapper>(
Ok(descriptor)
}

impl Translator for L0Table {
fn translate<PM: PageTableMapper>(
table_pa: TPA<PgTableArray<Self>>,
va: VA,
ctx: &mut WalkContext<PM>,
) -> Result<Option<(PA, usize, PtePermissions)>> {
let desc = unsafe {
ctx.mapper
.with_page_table(table_pa, |pgtable| Self::from_ptr(pgtable).get_desc(va))?
};

match desc.next_table_address() {
Some(next_pa) => L1Table::translate(next_pa, va, ctx),
None if desc.is_valid() => Err(MapError::InvalidDescriptor.into()),
None => Ok(None),
}
}
}

impl Translator for L3Table {
fn translate<PM: PageTableMapper>(
table_pa: TPA<PgTableArray<Self>>,
va: VA,
ctx: &mut WalkContext<PM>,
) -> Result<Option<(PA, usize, PtePermissions)>> {
let desc = unsafe {
ctx.mapper
.with_page_table(table_pa, |pgtable| Self::from_ptr(pgtable).get_desc(va))?
};

match desc.mapped_address() {
Some(pa) => Ok(Some((
pa,
1 << Self::Descriptor::MAP_SHIFT,
desc.permissions().unwrap(),
))),
None if desc.is_valid() => Err(MapError::InvalidDescriptor.into()),
None => Ok(None),
}
}
}

/// Translates the VA into a physical region plus an offset and permissions.
pub fn translate<PM: PageTableMapper>(
l0_table: TPA<PgTableArray<L0Table>>,
va: VA,
mapper: &mut PM,
) -> Result<Option<(PhysMemoryRegion, usize, PtePermissions)>> {
let mut walk_ctx = WalkContext {
mapper,
// Safe to not invalidate the TLB, as we are not modifying any PTEs.
invalidator: &NullTlbInvalidator {},
};

if let Some((pa, blk_sz, perms)) = L0Table::translate(l0_table, va, &mut walk_ctx)? {
debug_assert!(blk_sz.is_power_of_two());

let offset = va.value() & (blk_sz - 1);

Ok(Some((PhysMemoryRegion::new(pa, blk_sz), offset, perms)))
} else {
Ok(None)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 10 additions & 0 deletions libkernel/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ pub struct CharDevDescriptor {
/// The minor device number (identifies the device instance).
pub minor: u64,
}

impl CharDevDescriptor {
/// Encodes this device descriptor into a Linux-style `dev_t` value.
pub const fn dev_t(self) -> u64 {
(self.minor & 0xff)
| ((self.major & 0xfff) << 8)
| ((self.minor & !0xff) << 12)
| ((self.major & !0xfff) << 32)
}
}
6 changes: 6 additions & 0 deletions scripts/qemu_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
parser.add_argument("--memory", default="2G")
parser.add_argument("--debug", action="store_true", help="Enable QEMU debugging")
parser.add_argument("--display", action="store_true", help="Add a display device to the VM")
parser.add_argument("--disk", action="store_true", help="Add a disk device to the VM")



Expand Down Expand Up @@ -41,6 +42,7 @@
"-rtc": "base=utc,clock=host",
"-nographic": None,
"-s": None,
"-snapshot": None,
"-kernel": bin_executable_location,
"-append": f"{append_args} --rootfs=ext4fs --automount=/dev,devfs --automount=/tmp,tmpfs --automount=/proc,procfs --automount=/sys,sysfs",
}
Expand All @@ -59,6 +61,10 @@
default_args["-serial"] = "stdio"
extra_args += ["-device", "virtio-gpu-device"]

if args.disk:
default_args["-drive"] = "file=rootfs.img,format=raw,if=none,cache=none,id=x0"
extra_args += ["-device", "virtio-blk-device,drive=x0"]

qemu_command = ["qemu-system-aarch64"]

for key, value in default_args.items():
Expand Down
11 changes: 8 additions & 3 deletions src/arch/arm64/exceptions/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use crate::{
iov::{sys_preadv, sys_preadv2, sys_pwritev, sys_pwritev2, sys_readv, sys_writev},
listxattr::{sys_flistxattr, sys_listxattr, sys_llistxattr},
mount::sys_mount,
pivot_root::sys_pivot_root,
removexattr::{sys_fremovexattr, sys_lremovexattr, sys_removexattr},
rw::{sys_pread64, sys_pwrite64, sys_read, sys_write},
seek::sys_lseek,
Expand All @@ -45,6 +46,7 @@ use crate::{
statfs::{sys_fstatfs, sys_statfs},
sync::{sys_fdatasync, sys_fsync, sys_sync, sys_syncfs},
trunc::{sys_ftruncate, sys_truncate},
umount::sys_umount2,
},
},
kernel::{
Expand All @@ -71,9 +73,9 @@ use crate::{
caps::{sys_capget, sys_capset},
clone::sys_clone,
creds::{
sys_getegid, sys_geteuid, sys_getgid, sys_getresgid, sys_getresuid, sys_getsid,
sys_gettid, sys_getuid, sys_setfsgid, sys_setfsuid, sys_setgid, sys_setregid,
sys_setresgid, sys_setresuid, sys_setreuid, sys_setsid, sys_setuid,
sys_getegid, sys_geteuid, sys_getgid, sys_getgroups, sys_getresgid, sys_getresuid,
sys_getsid, sys_gettid, sys_getuid, sys_setfsgid, sys_setfsuid, sys_setgid,
sys_setregid, sys_setresgid, sys_setresuid, sys_setreuid, sys_setsid, sys_setuid,
},
epoll::{sys_epoll_create1, sys_epoll_ctl, sys_epoll_pwait},
exec::sys_execve,
Expand Down Expand Up @@ -284,6 +286,7 @@ pub async fn handle_syscall(mut ctx: ProcessCtx) {
)
.await
}
0x27 => sys_umount2(&ctx, TUA::from_value(arg1 as _), arg2 as _).await,
0x28 => {
sys_mount(
&ctx,
Expand All @@ -295,6 +298,7 @@ pub async fn handle_syscall(mut ctx: ProcessCtx) {
)
.await
}
0x29 => sys_pivot_root(&ctx, TUA::from_value(arg1 as _), TUA::from_value(arg2 as _)).await,
0x2b => sys_statfs(&ctx, TUA::from_value(arg1 as _), TUA::from_value(arg2 as _)).await,
0x2c => sys_fstatfs(&ctx, arg1.into(), TUA::from_value(arg2 as _)).await,
0x2d => sys_truncate(&ctx, TUA::from_value(arg1 as _), arg2 as _).await,
Expand Down Expand Up @@ -616,6 +620,7 @@ pub async fn handle_syscall(mut ctx: ProcessCtx) {
0x9b => sys_getpgid(&ctx, arg1 as _),
0x9c => sys_getsid(&ctx).await,
0x9d => sys_setsid(&ctx).await,
0x9e => sys_getgroups(&ctx, arg1 as _, TUA::from_value(arg2 as _)).map_err(|e| match e {}),
Comment thread
arihant2math marked this conversation as resolved.
0xa0 => sys_uname(TUA::from_value(arg1 as _)).await,
0xa1 => sys_sethostname(&ctx, TUA::from_value(arg1 as _), arg2 as _).await,
0xa3 => Err(KernelError::InvalidValue),
Expand Down
17 changes: 8 additions & 9 deletions src/arch/arm64/memory/address_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use libkernel::{
pg_descriptors::{L3Descriptor, MemoryType},
pg_tables::{L0Table, MapAttributes, MappingContext, map_range},
pg_tear_down::tear_down_address_space,
pg_walk::{get_pte, walk_and_modify_region},
pg_walk::{translate as translate_va, walk_and_modify_region},
},
error::{KernelError, MapError, Result},
memory::{
Expand Down Expand Up @@ -137,16 +137,15 @@ impl UserAddressSpace for Arm64ProcessAddressSpace {
}

fn translate(&self, va: VA) -> Option<PageInfo> {
let pte = get_pte(
self.l0_table,
va.page_aligned(),
&mut PageOffsetPgTableMapper {},
)
.unwrap()?;
let (region, offset, perms) =
translate_va(self.l0_table, va, &mut PageOffsetPgTableMapper {})
.ok()
.flatten()?;
let pa = region.start_address().add_bytes(offset);

Some(PageInfo {
pfn: pte.mapped_address()?.to_pfn(),
perms: pte.permissions()?,
pfn: pa.to_pfn(),
perms,
})
}

Expand Down
17 changes: 6 additions & 11 deletions src/arch/arm64/memory/mmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use libkernel::{
arch::arm64::memory::{
pg_descriptors::MemoryType,
pg_tables::{L0Table, MapAttributes, MappingContext, map_range},
pg_walk::get_pte,
pg_walk::translate as translate_va,
},
error::Result,
memory::{
address::{PA, TPA, VA},
paging::{PaMapper, PgTableArray, permissions::PtePermissions},
paging::{PgTableArray, permissions::PtePermissions},
proc_vm::address_space::KernAddressSpace,
region::{PhysMemoryRegion, VirtMemoryRegion},
},
Expand Down Expand Up @@ -39,16 +39,11 @@ impl Arm64KernelAddressSpace {
map_range(self.kernel_l0, map_attrs, &mut ctx)
}

pub fn translate(&self, va: VA) -> Option<PA> {
let pg_offset = va.page_offset();

let pte = get_pte(self.kernel_l0, va, &mut PageOffsetPgTableMapper {})
pub fn translate(&self, va: VA) -> Option<(PhysMemoryRegion, usize)> {
translate_va(self.kernel_l0, va, &mut PageOffsetPgTableMapper {})
.ok()
.flatten()?;

let pa = pte.mapped_address()?;

Some(pa.add_bytes(pg_offset))
.flatten()
.map(|(region, offset, _)| (region, offset))
}

pub fn table_pa(&self) -> PA {
Expand Down
Loading
Loading