Skip to content
Open
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
82 changes: 77 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::{Address, TPA, VA},
paging::{
NullTlbInvalidator, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
walk::{RecursiveWalker, WalkContext},
NullTlbInvalidator, PaMapper, PageTableEntry, PageTableMapper, PgTable, PgTableArray,
TableMapper,
permissions::PtePermissions,
walk::{RecursiveWalker, Translatable, Translator, WalkContext},
},
region::VirtMemoryRegion,
region::{PhysMemoryRegion, VirtMemoryRegion},
},
};

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

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

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

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

match desc.mapped_address() {
Some(pa) => Ok(Some((
Address::from_value(pa.value()),
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 @@ -21,6 +21,7 @@ def find_objcopy():
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 @@ -48,6 +49,7 @@ def find_objcopy():
"-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 @@ -66,6 +68,10 @@ def find_objcopy():
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 @@ -37,6 +37,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 @@ -46,6 +47,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 @@ -72,9 +74,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 @@ -295,6 +297,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 @@ -306,6 +309,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 @@ -627,6 +631,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