Skip to content

Commit

Permalink
refactors idt (#661)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuchAFuriousDeath committed Feb 18, 2024
1 parent 4d5042c commit 23a17a9
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 116 deletions.
9 changes: 2 additions & 7 deletions src/kernel/src/budget/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::errno::{ENOENT, ENOSYS, ESRCH};
use crate::idt::Idt;
use crate::idt::{Entry, Idt};
use crate::info;
use crate::process::VThread;
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use std::convert::Infallible;
use std::sync::{Arc, Mutex};

/// An implementation of budget system on the PS4.
Expand All @@ -25,12 +24,8 @@ impl BudgetManager {
pub fn create(&self, budget: Budget) -> usize {
let name = budget.name.clone();
let mut budgets = self.budgets.lock().unwrap();
let (entry, id) = budgets
.alloc::<_, Infallible>(|_| Ok(Arc::new(budget)))
.unwrap();

entry.set_name(Some(name));
entry.set_ty(0x2000);
let id = budgets.alloc_infallible(|_| Entry::new(Some(name), Arc::new(budget), 0x2000));

id
}
Expand Down
8 changes: 6 additions & 2 deletions src/kernel/src/fs/dev/cdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,18 @@ pub(super) trait Device: Debug + Sync + Send + 'static {
#[allow(unused_variables)]
fn read(
self: Arc<Self>,
data: &mut [u8],
data: &mut UioMut,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
Err(Box::new(DefaultError::ReadNotSupported))
}

#[allow(unused_variables)]
fn write(self: Arc<Self>, data: &[u8], td: Option<&VThread>) -> Result<usize, Box<dyn Errno>> {
fn write(
self: Arc<Self>,
data: &mut Uio,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
Err(Box::new(DefaultError::WriteNotSupported))
}

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ pub enum VFileType {

bitflags! {
/// Flags for [`VFile`].
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VFileFlags: u32 {
const READ = 0x00000001; // FREAD
const WRITE = 0x00000002; // FWRITE
Expand Down
26 changes: 13 additions & 13 deletions src/kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,19 @@ impl Fs {
Ok(SysOut::ZERO)
}

fn revoke(&self, vn: Arc<Vnode>, td: &VThread) -> Result<(), RevokeError> {
let vattr = vn.getattr().map_err(RevokeError::GetAttrError)?;

if td.cred().effective_uid() != vattr.uid() {
td.priv_check(Privilege::VFS_ADMIN)?;
}

vn.revoke(RevokeFlags::REVOKE_ALL)
.map_err(RevokeError::RevokeFailed)?;

Ok(())
}

fn sys_readv(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
let fd: i32 = i.args[0].try_into().unwrap();
let iovec: *mut IoVec = i.args[1].into();
Expand Down Expand Up @@ -728,19 +741,6 @@ impl Fs {
todo!()
}

fn revoke(&self, vn: Arc<Vnode>, td: &VThread) -> Result<(), RevokeError> {
let vattr = vn.getattr().map_err(RevokeError::GetAttrError)?;

if td.cred().effective_uid() != vattr.uid() {
td.priv_check(Privilege::VFS_ADMIN)?;
}

vn.revoke(RevokeFlags::REVOKE_ALL)
.map_err(RevokeError::RevokeFailed)?;

Ok(())
}

fn sys_mkdir(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
let path = unsafe { i.args[0].to_path() }?.unwrap();
let mode: u32 = i.args[1].try_into().unwrap();
Expand Down
14 changes: 3 additions & 11 deletions src/kernel/src/idt/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ pub struct Entry<T> {
}

impl<T> Entry<T> {
pub(super) fn new(data: T) -> Self {
pub fn new(name: Option<String>, data: T, ty: u16) -> Self {
Self {
name: None,
name: name,
data,
ty: 0,
ty,
}
}

Expand All @@ -22,12 +22,4 @@ impl<T> Entry<T> {
pub fn ty(&self) -> u16 {
self.ty
}

pub fn set_name(&mut self, v: Option<String>) {
self.name = v;
}

pub fn set_ty(&mut self, v: u16) {
self.ty = v;
}
}
17 changes: 15 additions & 2 deletions src/kernel/src/idt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::convert::Infallible;

pub use self::entry::*;

mod entry;
Expand Down Expand Up @@ -27,10 +29,21 @@ impl<T> Idt<T> {
}
}

pub fn alloc_infallible<F>(&mut self, factory: F) -> usize
where
F: FnOnce(usize) -> Entry<T>,
{
let Ok((_, id)) = self.alloc::<_, Infallible>(|id| Ok(factory(id))) else {
unreachable!();
};

id
}

/// See `id_alloc` on the PS4 for a reference.
pub fn alloc<F, E>(&mut self, factory: F) -> Result<(&mut Entry<T>, usize), E>
where
F: FnOnce(usize) -> Result<T, E>,
F: FnOnce(usize) -> Result<Entry<T>, E>,
{
// Allocate a new set if necessary.
let id = self.next;
Expand All @@ -47,7 +60,7 @@ impl<T> Idt<T> {
assert!(entry.is_none());

// Set the value.
let value = entry.insert(Entry::new(factory(id)?));
let value = entry.insert(factory(id)?);

// Update table states.
self.next += 1;
Expand Down
3 changes: 3 additions & 0 deletions src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::kqueue::KernelQueueManager;
use crate::llvm::Llvm;
use crate::log::{print, LOGGER};
use crate::memory::{MemoryManager, MemoryManagerError};
use crate::namedobj::NamedObjManager;
use crate::net::NetManager;
use crate::osem::OsemManager;
use crate::process::{VProc, VProcInitError, VThread};
Expand Down Expand Up @@ -47,6 +48,7 @@ mod kqueue;
mod llvm;
mod log;
mod memory;
mod namedobj;
mod net;
mod osem;
mod process;
Expand Down Expand Up @@ -289,6 +291,7 @@ fn run<E: crate::ee::ExecutionEngine>(
&mut syscalls,
)?;

NamedObjManager::new(&mut syscalls, &proc);
OsemManager::new(&mut syscalls, &proc);

// Initialize runtime linker.
Expand Down
64 changes: 64 additions & 0 deletions src/kernel/src/namedobj/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::{
errno::EINVAL,
idt::Entry,
info,
process::VProc,
syscalls::{SysErr, SysIn, SysOut, Syscalls},
};
use std::sync::Arc;

pub struct NamedObjManager {
proc: Arc<VProc>,
}

impl NamedObjManager {
pub fn new(sys: &mut Syscalls, proc: &Arc<VProc>) -> Arc<Self> {
let namedobj = Arc::new(Self { proc: proc.clone() });

sys.register(557, &namedobj, Self::sys_namedobj_create);

namedobj
}

fn sys_namedobj_create(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
// Get arguments.
let name = unsafe { i.args[0].to_str(32) }?.ok_or(SysErr::Raw(EINVAL))?;
let data: usize = i.args[1].into();
let flags: u32 = i.args[2].try_into().unwrap();

// Allocate the entry.
let mut table = self.proc.objects_mut();

let obj = NamedObj::new(name, data);

let id = table.alloc_infallible(|_| {
Entry::new(
Some(name.to_owned()),
Arc::new(obj),
(flags as u16) | 0x1000,
)
});

info!(
"Named object '{}' (ID = {}) was created with data = {:#x} and flags = {:#x}.",
name, id, data, flags
);

Ok(id.into())
}
}

#[derive(Debug)]
pub struct NamedObj {
name: String,
data: usize,
}

impl NamedObj {
pub fn new(name: impl Into<String>, data: usize) -> Self {
Self {
name: name.into(),
data,
}
}
}
8 changes: 3 additions & 5 deletions src/kernel/src/osem/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::errno::EINVAL;
use crate::idt::Entry;
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use crate::VProc;
use bitflags::bitflags;
use std::convert::Infallible;
use std::sync::Arc;

pub struct OsemManager {
Expand Down Expand Up @@ -37,10 +37,8 @@ impl OsemManager {

let mut objects = self.proc.objects_mut();

let (entry, id) = objects.alloc::<_, Infallible>(|_| Ok(Osem::new(flags)))?;

entry.set_name(Some(name.to_owned()));
entry.set_ty(0x120);
let id = objects
.alloc_infallible(|_| Entry::new(Some(name.to_owned()), Osem::new(flags), 0x120));

Ok(id.into())
}
Expand Down
68 changes: 39 additions & 29 deletions src/kernel/src/process/filedesc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use gmtx::{Gutex, GutexGroup};
use macros::Errno;
use std::collections::VecDeque;
use std::convert::Infallible;
use std::num::NonZeroI32;
use std::num::{NonZeroI32, TryFromIntError};
use std::sync::Arc;
use thiserror::Error;

Expand Down Expand Up @@ -90,11 +90,11 @@ impl FileDesc {
return i as i32;
}

// This should never happened.
// This should never happen.
panic!("Too many files has been opened.");
}

// TODO: implement capabilities
// TODO: (maybe) implement capabilities

/// See `fget` on the PS4 for a reference.
pub fn get(&self, fd: i32) -> Result<Arc<VFile>, GetFileError> {
Expand All @@ -113,27 +113,28 @@ impl FileDesc {

/// See `_fget` and `fget_unlocked` on the PS4 for a reference.
fn get_internal(&self, fd: i32, flags: VFileFlags) -> Result<Arc<VFile>, GetFileError> {
if fd < 0 {
return Err(GetFileError::NegativeFd(fd));
}
let fd: usize = fd.try_into()?;

let files = self.files.write();

if fd as usize >= files.len() {
return Err(GetFileError::FdOutOfRange(fd));
}
let file = files
.get(fd as usize)
.ok_or(GetFileError::FdOutOfRange)? // None means the file descriptor is out of range
.as_ref()
.ok_or(GetFileError::NoFile)?; // Some(None) means the file descriptor is not associated with a file

loop {
if let None = files.get(fd as usize) {
return Err(GetFileError::NoFile(fd));
match flags {
VFileFlags::WRITE | VFileFlags::READ if !file.flags().intersects(flags) => {
return Err(GetFileError::BadFlags(flags, file.flags()));
}

todo!()
_ => {}
}

Ok(file.clone())
}

pub fn free(&self, fd: i32) -> Result<(), FreeError> {
let fd: usize = fd.try_into().map_err(|_| FreeError::NegativeFd)?;
let fd: usize = fd.try_into()?;

let mut files = self.files.write();

Expand All @@ -147,25 +148,28 @@ impl FileDesc {
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum GetFileError {
#[error("got negative file descriptor {0}")]
NegativeFd(i32),
#[error("got negative file descriptor")]
#[errno(EBADF)]
NegativeFd,

#[error("file descriptor {0} out of range")]
FdOutOfRange(i32),
#[error("file descriptor is out of range")]
#[errno(EBADF)]
FdOutOfRange,

#[error("no file assoiated with file descriptor {0}")]
NoFile(i32),
#[error("no file assoiated with file descriptor")]
#[errno(EBADF)]
NoFile,

#[error("bad flags associated with file descriptor: expected {0:?}, file has {1:?}")]
#[errno(EBADF)]
BadFlags(VFileFlags, VFileFlags),
}

impl Errno for GetFileError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::NegativeFd(_) => EBADF,
Self::FdOutOfRange(_) => EBADF,
Self::NoFile(_) => EBADF,
}
impl From<TryFromIntError> for GetFileError {
fn from(_: TryFromIntError) -> Self {
GetFileError::NegativeFd
}
}

Expand Down Expand Up @@ -193,3 +197,9 @@ pub enum FreeError {
#[errno(EBADF)]
NoFile,
}

impl From<TryFromIntError> for FreeError {
fn from(_: TryFromIntError) -> Self {
FreeError::NegativeFd
}
}
Loading

0 comments on commit 23a17a9

Please sign in to comment.