Skip to content

Commit

Permalink
Implements sysctl kern.proc.ptc and kern.sched.cpusetsize (#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Oct 25, 2023
1 parent 9a1cba6 commit 5bdc59e
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 22 deletions.
39 changes: 39 additions & 0 deletions src/kernel/src/budget/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::errno::{ENOENT, ENOSYS, ESRCH};
use crate::info;
use crate::process::{VProc, VThread};
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use std::sync::Arc;

/// An implementation of budget system on the PS4.
pub struct Budget {
vp: Arc<VProc>,
}

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

sys.register(610, &budget, Self::sys_budget_get_ptype);

budget
}

fn sys_budget_get_ptype(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
// Check if PID is our process.
let pid: i32 = i.args[0].try_into().unwrap();
let td = VThread::current();

info!("Getting budget process type for process {pid}.");

if td.cred().is_system() || pid == -1 || pid == self.vp.id().get() {
if pid == -1 || pid == self.vp.id().get() {
// TODO: Invoke id_rlock. Not sure why return ENOENT is working here.
Err(SysErr::Raw(ENOENT))
} else {
Err(SysErr::Raw(ESRCH))
}
} else {
Err(SysErr::Raw(ENOSYS))
}
}
}
7 changes: 5 additions & 2 deletions src/kernel/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::arch::MachDep;
use crate::arnd::Arnd;
use crate::budget::Budget;
use crate::ee::{EntryArg, RawFn};
use crate::fs::Fs;
use crate::llvm::Llvm;
Expand All @@ -22,6 +23,7 @@ use std::sync::Arc;

mod arch;
mod arnd;
mod budget;
mod console;
mod ee;
mod errno;
Expand Down Expand Up @@ -123,10 +125,10 @@ fn main() -> ExitCode {

let mut log = info!();

writeln!(log, "Page size : {}", mm.page_size()).unwrap();
writeln!(log, "Page size : {:#x}", mm.page_size()).unwrap();
writeln!(
log,
"Allocation granularity: {}",
"Allocation granularity: {:#x}",
mm.allocation_granularity()
)
.unwrap();
Expand Down Expand Up @@ -185,6 +187,7 @@ fn run<E: crate::ee::ExecutionEngine>(
let fs = Fs::new(root, app, vp, &mut syscalls);
RegMgr::new(&mut syscalls);
MachDep::new(&mut syscalls);
Budget::new(vp, &mut syscalls);

// Initialize runtime linker.
info!("Initializing runtime linker.");
Expand Down
4 changes: 0 additions & 4 deletions src/kernel/src/memory/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ impl<'a> VPages<'a> {
self.ptr as _
}

pub fn len(&self) -> usize {
self.len
}

pub fn end(&self) -> *const u8 {
unsafe { self.ptr.add(self.len) }
}
Expand Down
29 changes: 15 additions & 14 deletions src/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use self::session::*;
pub use self::signal::*;
pub use self::thread::*;

use crate::errno::{EINVAL, ENAMETOOLONG, ENOENT, ENOSYS, EPERM, ESRCH};
use crate::errno::{EINVAL, ENAMETOOLONG, EPERM, ESRCH};
use crate::idt::IdTable;
use crate::info;
use crate::signal::{
Expand All @@ -20,6 +20,8 @@ use llt::{SpawnError, Thread};
use std::any::Any;
use std::mem::zeroed;
use std::num::NonZeroI32;
use std::ptr::null_mut;
use std::sync::atomic::AtomicPtr;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
use thiserror::Error;
Expand Down Expand Up @@ -48,6 +50,8 @@ pub struct VProc {
limits: [ResourceLimit; ResourceLimit::NLIMITS], // p_limit
objects: GroupMutex<IdTable<Arc<dyn Any + Send + Sync>>>,
app_info: AppInfo,
ptc: u64,
uptc: AtomicPtr<u8>, // Use a unit type for minimum alignment.
mtxg: Arc<MutexGroup>,
}

Expand All @@ -66,6 +70,8 @@ impl VProc {
objects: mg.new_member(IdTable::new(0x1000)),
limits,
app_info: AppInfo::new(),
ptc: 0,
uptc: AtomicPtr::new(null_mut()),
mtxg: mg,
});

Expand All @@ -79,7 +85,6 @@ impl VProc {
sys.register(557, &vp, Self::sys_namedobj_create);
sys.register(585, &vp, Self::sys_is_in_sandbox);
sys.register(587, &vp, Self::sys_get_authinfo);
sys.register(610, &vp, Self::sys_budget_get_ptype);

Ok(vp)
}
Expand Down Expand Up @@ -108,6 +113,14 @@ impl VProc {
&self.app_info
}

pub fn ptc(&self) -> u64 {
self.ptc
}

pub fn uptc(&self) -> &AtomicPtr<u8> {
&self.uptc
}

pub fn mutex_group(&self) -> &Arc<MutexGroup> {
&self.mtxg
}
Expand Down Expand Up @@ -478,18 +491,6 @@ impl VProc {
Ok(SysOut::ZERO)
}

fn sys_budget_get_ptype(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
// Check if PID is our process.
let pid: i32 = i.args[0].try_into().unwrap();

if pid != -1 && pid != self.id.get() {
return Err(SysErr::Raw(ENOSYS));
}

// TODO: Invoke id_rlock. Not sure why return ENOENT is working here.
Err(SysErr::Raw(ENOENT))
}

fn new_id() -> NonZeroI32 {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);

Expand Down
72 changes: 70 additions & 2 deletions src/kernel/src/sysctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::process::VProc;
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
use std::any::Any;
use std::cmp::min;
use std::ptr::null_mut;
use std::sync::atomic::Ordering;
use std::sync::Arc;

/// A registry of system parameters.
Expand Down Expand Up @@ -316,6 +318,26 @@ impl Sysctl {
Ok(())
}

fn kern_proc_ptc(
&self,
_: &'static Oid,
_: &Arg,
_: usize,
req: &mut SysctlReq,
) -> Result<(), SysErr> {
req.write(&self.vp.ptc().to_ne_bytes())?;

self.vp.uptc().store(
req.old
.as_mut()
.map(|v| v.as_mut_ptr())
.unwrap_or(null_mut()),
Ordering::Relaxed,
);

Ok(())
}

fn kern_usrstack(
&self,
_: &'static Oid,
Expand Down Expand Up @@ -527,7 +549,7 @@ static KERN_PROC_CHILDREN: OidList = OidList {

static KERN_PROC_APPINFO: Oid = Oid {
parent: &KERN_PROC_CHILDREN,
link: None, // TODO: Implement this.
link: Some(&KERN_PROC_PTC), // TODO: Use a proper value.
number: Sysctl::KERN_PROC_APPINFO,
kind: 0xC0040001,
arg1: None, // TODO: This value on the PS4 is not null.
Expand All @@ -539,6 +561,20 @@ static KERN_PROC_APPINFO: Oid = Oid {
enabled: true,
};

static KERN_PROC_PTC: Oid = Oid {
parent: &KERN_PROC_CHILDREN,
link: None, // TODO: Implement this.
number: 0x2B,
kind: 0x90040009,
arg1: None,
arg2: 0,
name: "ptc",
handler: Some(Sysctl::kern_proc_ptc),
fmt: "LU",
descr: "Process time counter",
enabled: true,
};

static KERN_USRSTACK: Oid = Oid {
parent: &KERN_CHILDREN,
link: Some(&KERN_ARANDOM), // TODO: Use a proper value.
Expand All @@ -555,7 +591,7 @@ static KERN_USRSTACK: Oid = Oid {

static KERN_ARANDOM: Oid = Oid {
parent: &KERN_CHILDREN,
link: Some(&KERN_SMP), // TODO: Use a proper value.
link: Some(&KERN_SCHED), // TODO: Use a proper value.
number: Sysctl::KERN_ARND,
kind: 0x80048005,
arg1: None,
Expand All @@ -567,6 +603,38 @@ static KERN_ARANDOM: Oid = Oid {
enabled: true,
};

static KERN_SCHED: Oid = Oid {
parent: &KERN_CHILDREN,
link: Some(&KERN_SMP), // TODO: Use a proper value.
number: 0x2A0,
kind: 0xC0000001,
arg1: Some(&KERN_SCHED_CHILDREN),
arg2: 0,
name: "sched",
handler: None,
fmt: "N",
descr: "Scheduler",
enabled: false,
};

static KERN_SCHED_CHILDREN: OidList = OidList {
first: Some(&KERN_SCHED_CPUSETSIZE), // TODO: Use a proper value.
};

static KERN_SCHED_CPUSETSIZE: Oid = Oid {
parent: &KERN_SCHED_CHILDREN,
link: None,
number: 0x4E4,
kind: 0x80040002,
arg1: None,
arg2: 8,
name: "cpusetsize",
handler: Some(Sysctl::handle_int),
fmt: "I",
descr: "sizeof(cpuset_t)",
enabled: true,
};

static KERN_SMP: Oid = Oid {
parent: &KERN_CHILDREN,
link: None, // TODO: Implement this.
Expand Down

0 comments on commit 5bdc59e

Please sign in to comment.