Skip to content

Commit

Permalink
Implements syscall 487 (#426)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Nov 7, 2023
1 parent 9607fab commit 3a5decb
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 4 deletions.
25 changes: 25 additions & 0 deletions src/kernel/src/process/cpuset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub const CPU_LEVEL_WHICH: i32 = 3;
pub const CPU_WHICH_TID: i32 = 1;

/// An implementation of `cpuset`.
#[derive(Debug)]
pub struct CpuSet {
mask: CpuMask, // cs_mask
}

impl CpuSet {
pub fn new(mask: CpuMask) -> Self {
Self { mask }
}

pub fn mask(&self) -> &CpuMask {
&self.mask
}
}

/// An implementation of `cpuset_t`.
#[repr(C)]
#[derive(Debug, Default)]
pub struct CpuMask {
pub bits: [u64; 1],
}
81 changes: 77 additions & 4 deletions src/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
pub use self::appinfo::*;
pub use self::cpuset::*;
pub use self::file::*;
pub use self::group::*;
pub use self::rlimit::*;
pub use self::session::*;
pub use self::signal::*;
pub use self::thread::*;

use crate::errno::{EINVAL, ENAMETOOLONG, EPERM, ESRCH};
use crate::errno::{EINVAL, ENAMETOOLONG, EPERM, ERANGE, ESRCH};
use crate::idt::IdTable;
use crate::info;
use crate::signal::{
Expand All @@ -27,6 +28,7 @@ use std::sync::Arc;
use thiserror::Error;

mod appinfo;
mod cpuset;
mod file;
mod group;
mod rlimit;
Expand All @@ -51,7 +53,7 @@ pub struct VProc {
objects: GroupMutex<IdTable<Arc<dyn Any + Send + Sync>>>,
app_info: AppInfo,
ptc: u64,
uptc: AtomicPtr<u8>, // Use a unit type for minimum alignment.
uptc: AtomicPtr<u8>,
mtxg: Arc<MutexGroup>,
}

Expand All @@ -63,7 +65,7 @@ impl VProc {
let vp = Arc::new(Self {
id: Self::new_id(),
threads: mg.new_member(Vec::new()),
cred: Ucred::new(AuthInfo::EXE.clone()),
cred: Ucred::new(AuthInfo::SYS_CORE.clone()),
group: mg.new_member(None),
sigacts: mg.new_member(SignalActs::new()),
files: VProcFiles::new(&mg),
Expand All @@ -82,6 +84,7 @@ impl VProc {
sys.register(416, &vp, Self::sys_sigaction);
sys.register(432, &vp, Self::sys_thr_self);
sys.register(466, &vp, Self::sys_rtprio_thread);
sys.register(487, &vp, Self::sys_cpuset_getaffinity);
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);
Expand Down Expand Up @@ -146,7 +149,7 @@ impl VProc {
let mut threads = self.threads.write();

// TODO: Check how ucred is constructed for a thread.
let cred = Ucred::new(AuthInfo::EXE.clone());
let cred = Ucred::new(AuthInfo::SYS_CORE.clone());
let td = Arc::new(VThread::new(Self::new_id(), cred, &self.mtxg));
let active = Box::new(ActiveThread {
proc: self.clone(),
Expand Down Expand Up @@ -419,6 +422,76 @@ impl VProc {
Ok(SysOut::ZERO)
}

fn sys_cpuset_getaffinity(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
// Get arguments.
let level: i32 = i.args[0].try_into().unwrap();
let which: i32 = i.args[1].try_into().unwrap();
let id: i64 = i.args[2].into();
let cpusetsize: usize = i.args[3].into();
let mask: *mut u8 = i.args[4].into();

// TODO: Refactor this for readability.
if cpusetsize.wrapping_sub(8) > 8 {
return Err(SysErr::Raw(ERANGE));
}

let ttd = self.cpuset_which(which, id)?;
let mut buf = vec![0u8; cpusetsize];

match level {
CPU_LEVEL_WHICH => match which {
CPU_WHICH_TID => {
let v = ttd.cpuset().mask().bits[0].to_ne_bytes();
buf[..v.len()].copy_from_slice(&v);
}
v => todo!("sys_cpuset_getaffinity with which = {v}"),
},
v => todo!("sys_cpuset_getaffinity with level = {v}"),
}

// TODO: What is this?
let x = u32::from_ne_bytes(buf[..4].try_into().unwrap());
let y = (x >> 1 & 0x55) + (x & 0x55) * 2;
let z = (y >> 2 & 0xfffffff3) + (y & 0x33) * 4;

unsafe {
std::ptr::write_unaligned::<u64>(
buf.as_mut_ptr() as _,
(z >> 4 | (z & 0xf) << 4) as u64,
);

std::ptr::copy_nonoverlapping(buf.as_ptr(), mask, cpusetsize);
}

Ok(SysOut::ZERO)
}

/// See `cpuset_which` on the PS4 for a reference.
fn cpuset_which(&self, which: i32, id: i64) -> Result<Arc<VThread>, SysErr> {
let td = match which {
CPU_WHICH_TID => {
if id == -1 {
todo!("cpuset_which with id = -1");
} else {
let threads = self.threads.read();
let td = threads.iter().find(|t| t.id().get() == id as i32).cloned();

if td.is_none() {
return Err(SysErr::Raw(ESRCH));
}

td
}
}
v => todo!("cpuset_which with which = {v}"),
};

match td {
Some(v) => Ok(v),
None => todo!("cpuset_which with td = NULL"),
}
}

// TODO: This should not be here.
fn sys_namedobj_create(self: &Arc<Self>, i: &SysIn) -> Result<SysOut, SysErr> {
// Get arguments.
Expand Down
7 changes: 7 additions & 0 deletions src/kernel/src/process/thread.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::{CpuMask, CpuSet};
use crate::signal::SignalSet;
use crate::ucred::{Privilege, PrivilegeError, Ucred};
use bitflags::bitflags;
Expand All @@ -18,6 +19,7 @@ pub struct VThread {
pri_class: u16, // td_pri_class
base_user_pri: u16, // td_base_user_pri
pcb: GroupMutex<Pcb>, // td_pcb
cpuset: CpuSet, // td_cpuset
}

impl VThread {
Expand All @@ -33,6 +35,7 @@ impl VThread {
fsbase: 0,
flags: PcbFlags::empty(),
}),
cpuset: CpuSet::new(CpuMask::default()), // TODO: Same here.
}
}

Expand Down Expand Up @@ -70,6 +73,10 @@ impl VThread {
self.pcb.write()
}

pub fn cpuset(&self) -> &CpuSet {
&self.cpuset
}

/// An implementation of `priv_check`.
pub fn priv_check(&self, p: Privilege) -> Result<(), PrivilegeError> {
self.cred.priv_check(p)
Expand Down
6 changes: 6 additions & 0 deletions src/kernel/src/syscalls/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ impl<T> From<SysArg> for *mut T {
}
}

impl From<SysArg> for i64 {
fn from(v: SysArg) -> Self {
v.0 as _
}
}

impl From<SysArg> for u64 {
fn from(v: SysArg) -> Self {
v.0 as _
Expand Down
17 changes: 17 additions & 0 deletions src/kernel/src/ucred/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ pub struct AuthInfo {
}

impl AuthInfo {
pub const SYS_CORE: Self = Self {
paid: 0x3800000000000007,
caps: [
0x40001C0000000000,
0x800000000000FF00,
0x0000000000000000,
0x0000000000000000,
],
attrs: [
0x4000400080000000,
0x8000000000000000,
0x0800000000000000,
0xF0000000FFFF4000,
],
unk: [0; 0x40],
};

pub const EXE: Self = Self {
paid: 0x3100000000000001,
caps: [
Expand Down

0 comments on commit 3a5decb

Please sign in to comment.