Skip to content

Commit

Permalink
Generate object IDs correctly. (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbittman authored Jan 12, 2025
1 parent 2f43564 commit 3d4f4fa
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 53 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/kernel/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static KSO_MANAGER: Once<KsoManager> = Once::new();

fn get_kso_manager() -> &'static KsoManager {
KSO_MANAGER.call_once(|| {
let root = Arc::new(crate::obj::Object::new());
let root = Arc::new(crate::obj::Object::new_kernel());
crate::obj::register_object(root.clone());
KsoManager {
root,
Expand Down Expand Up @@ -171,7 +171,7 @@ pub fn create_busroot(
bt: BusType,
kaction: fn(DeviceRef, cmd: u32, arg: u64, arg2: u64) -> Result<KactionValue, KactionError>,
) -> DeviceRef {
let obj = Arc::new(crate::obj::Object::new());
let obj = Arc::new(crate::obj::Object::new_kernel());
crate::obj::register_object(obj.clone());
let device = Arc::new(Device {
inner: Mutex::new(DeviceInner {
Expand Down Expand Up @@ -199,7 +199,7 @@ pub fn create_device(
id: DeviceId,
kaction: fn(DeviceRef, cmd: u32, arg: u64, arg: u64) -> Result<KactionValue, KactionError>,
) -> DeviceRef {
let obj = Arc::new(crate::obj::Object::new());
let obj = Arc::new(crate::obj::Object::new_kernel());
crate::obj::register_object(obj.clone());
let device = Arc::new(Device {
inner: Mutex::new(DeviceInner {
Expand Down Expand Up @@ -236,7 +236,7 @@ impl Device {
}

pub fn add_info<T>(&self, info: &T) {
let obj = Arc::new(crate::obj::Object::new());
let obj = Arc::new(crate::obj::Object::new_kernel());
obj.write_base(info);
crate::obj::register_object(obj.clone());
self.inner
Expand All @@ -246,7 +246,7 @@ impl Device {
}

pub fn add_mmio(&self, start: PhysAddr, end: PhysAddr, ct: CacheType, info: u64) {
let obj = Arc::new(crate::obj::Object::new());
let obj = Arc::new(crate::obj::Object::new_kernel());
obj.map_phys(start, end, ct);
let mmio_info = MmioInfo {
length: (end - start) as u64,
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/initrd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn init(modules: &[BootModule]) {
);
let mut total_alloc = 0;
for e in tar.entries() {
let obj = obj::Object::new();
let obj = obj::Object::new_kernel();
logln!(
"[kernel::initrd] loading {:?} -> {:x}",
e.filename(),
Expand Down
23 changes: 13 additions & 10 deletions src/kernel/src/instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ use core::{ops::Sub, time::Duration};

use twizzler_abi::syscall::TimeSpan;

use crate::time::TICK_SOURCES;
use crate::time::{Ticks, TICK_SOURCES};

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Instant(TimeSpan);

impl Instant {
pub fn now() -> Instant {
let ticks = { TICK_SOURCES.lock()[0].read() };
let ticks = {
TICK_SOURCES
.lock()
.get(0)
.map(|ts| ts.read())
.unwrap_or(Ticks::default())
};
let span = ticks.value * ticks.rate;
Instant(span)
}
Expand All @@ -21,14 +27,11 @@ impl Instant {

#[allow(dead_code)]
pub fn actually_monotonic() -> bool {
// use twizzler_runtime_api::Monotonicity;
// let runtime = twizzler_runtime_api::get_runtime();
// match runtime.actual_monotonicity() {
// Monotonicity::NonMonotonic => false,
// Monotonicity::Weak => true,
// Monotonicity::Strict => true,
// }
true
TICK_SOURCES
.lock()
.get(0)
.map(|ts| ts.info().is_monotonic())
.unwrap_or_default()
}

pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/memory/context/virtmem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ mod test {

#[kernel_test]
fn test_kernel_object() {
let obj = crate::obj::Object::new();
let obj = crate::obj::Object::new_kernel();
let obj = Arc::new(obj);
crate::obj::register_object(obj.clone());

Expand Down
48 changes: 44 additions & 4 deletions src/kernel/src/obj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use core::{
sync::atomic::{AtomicU32, Ordering},
};

use twizzler_abi::object::{ObjID, MAX_SIZE};
use twizzler_abi::{
meta::MetaFlags,
object::{ObjID, MAX_SIZE},
};

use self::{pages::Page, thread_sync::SleepInfo};
use crate::{
Expand Down Expand Up @@ -138,6 +141,39 @@ impl From<usize> for PageNumber {
}

static OID: core::sync::atomic::AtomicU64 = core::sync::atomic::AtomicU64::new(1);

fn backup_id_gen() -> ObjID {
((OID.fetch_add(1, Ordering::SeqCst) as u128) | (1u128 << 64)).into()
}

fn gen_id(nonce: ObjID, kuid: ObjID, flags: MetaFlags) -> ObjID {
#[repr(C)]
struct Ids {
nonce: ObjID,
kuid: ObjID,
flags: MetaFlags,
}
let mut ids = Ids { nonce, kuid, flags };
let ptr = core::ptr::addr_of_mut!(ids).cast::<u8>();
let slice = unsafe { core::slice::from_raw_parts_mut(ptr, size_of::<Ids>()) };
let hash = crate::crypto::sha256(slice);
let mut id_buf = [0u8; 16];
id_buf.copy_from_slice(&hash[0..16]);
for i in 0..16 {
id_buf[i] ^= hash[i + 16];
}
u128::from_ne_bytes(id_buf).into()
}

pub fn calculate_new_id(kuid: ObjID, flags: MetaFlags) -> ObjID {
let mut buf = [0u8; 16];
if !crate::random::getrandom(&mut buf, true) {
return backup_id_gen();
}
let nonce = u128::from_ne_bytes(buf);
gen_id(nonce.into(), kuid, flags)
}

impl Object {
pub fn is_pending_delete(&self) -> bool {
self.flags.load(Ordering::SeqCst) & OBJ_DELETED != 0
Expand Down Expand Up @@ -190,9 +226,9 @@ impl Object {
Some((v, token))
}

pub fn new() -> Self {
pub fn new(id: ObjID) -> Self {
Self {
id: ((OID.fetch_add(1, Ordering::SeqCst) as u128) | (1u128 << 64)).into(),
id,
flags: AtomicU32::new(0),
range_tree: Mutex::new(range::PageRangeTree::new()),
sleep_info: Mutex::new(SleepInfo::new()),
Expand All @@ -201,6 +237,10 @@ impl Object {
}
}

pub fn new_kernel() -> Self {
Self::new(calculate_new_id(0.into(), MetaFlags::default()))
}

pub fn add_context(&self, ctx: &ContextRef) {
self.contexts.lock().insert(ctx)
}
Expand Down Expand Up @@ -233,7 +273,7 @@ pub enum InvalidateMode {

impl Default for Object {
fn default() -> Self {
Self::new()
Self::new_kernel()
}
}

Expand Down
21 changes: 4 additions & 17 deletions src/kernel/src/random/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use jitter::maybe_add_jitter_entropy_source;
use crate::{
mutex::{LockGuard, Mutex},
once::Once,
syscall::sync::sys_thread_sync,
thread::{entry::run_closure_in_new_thread, priority::Priority},
};

Expand All @@ -31,14 +30,12 @@ struct EntropySources {

impl EntropySources {
pub fn new() -> Self {
logln!("Created new entropy sources list");
Self {
sources: Vec::new(),
}
}

pub fn has_sources(&self) -> bool {
logln!("source count: {}", self.source_count());
self.source_count() != 0
}

Expand All @@ -49,9 +46,7 @@ impl EntropySources {
&mut self,
) -> Result<(), ()> {
let source = Source::try_new()?;
logln!("pushing source!");
self.sources.push((Box::new(source), Contributor::new()));
logln!("Sources count: {}", self.source_count());
Ok(())
}

Expand All @@ -70,15 +65,14 @@ impl EntropySources {
}
}
}
// logln!("contributed entropy to pool");
}
}

static ACCUMULATOR: Once<Mutex<Accumulator>> = Once::new();
static ENTROPY_SOURCES: Once<Mutex<EntropySources>> = Once::new();

/// Generates randomness and fills the out buffer with entropy.
///
///
/// Will optionally block while waiting for entropy events.
///
/// Returns whether or not it successfully filled the out buffer with entropy
Expand All @@ -91,14 +85,12 @@ pub fn getrandom(out: &mut [u8], nonblocking: bool) -> bool {
if let Ok(()) = res {
return true;
}
logln!("need to seed accumulator");
// try_fill_random_data only fails if unseeded
// so the rest is trying to seed it/wait for it to be seeded
let mut entropy_sources = ENTROPY_SOURCES
.call_once(|| Mutex::new(EntropySources::new()))
.lock();
if entropy_sources.has_sources() {
logln!("has sources");
entropy_sources.contribute_entropy(acc.borrow_mut());
acc.try_fill_random_data(out)
.expect("Should be seeded now & therefore shouldn't return an error");
Expand All @@ -110,12 +102,12 @@ pub fn getrandom(out: &mut [u8], nonblocking: bool) -> bool {
// doesn't block, returns false instead
false
} else {
// TODO: block on a condvar or something.
// otherwise schedule and recurse in again after this thread gets picked up again
// this way it allows other work to get done, work that might result in entropy events

// block for 2 seconds and hope for other entropy-generating work to get done in the
// meantime
logln!("recursing");
// sys_thread_sync(&mut [], Some(&mut Duration::from_secs(2))).expect(
// "shouldn't panic because sys_thread_sync doesn't panic if no ops are passed in",
// );
Expand Down Expand Up @@ -184,13 +176,8 @@ mod test {
#[kernel_test]
fn test_rand_gen() {
let registered_jitter_entropy = maybe_add_jitter_entropy_source();
let mut into = [0u8; 1024];
logln!("jitter entropy registered: {}", registered_jitter_entropy);

getrandom(&mut into, false);
for byte in into {
logln!("{}", byte);
}
// logln!("Into: {:?}", into)
let mut into = [0u8; 1024];
assert_eq!(getrandom(&mut into, false), true);
}
}
10 changes: 6 additions & 4 deletions src/kernel/src/syscall/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use alloc::{
};

use twizzler_abi::{
meta::MetaFlags,
object::{ObjID, Protections},
syscall::{
CreateTieSpec, HandleType, MapFlags, MapInfo, NewHandleError, ObjectCreate,
Expand All @@ -15,20 +16,21 @@ use crate::{
arch::context::ArchContext,
memory::context::{Context, ContextRef},
mutex::Mutex,
obj::{LookupFlags, Object, ObjectRef},
obj::{calculate_new_id, LookupFlags, Object, ObjectRef},
once::Once,
security::get_sctx,
thread::{current_memory_context, current_thread_ref},
};

pub fn sys_object_create(
_create: &ObjectCreate,
create: &ObjectCreate,
srcs: &[ObjectSource],
_ties: &[CreateTieSpec],
) -> Result<ObjID, ObjectCreateError> {
let obj = Arc::new(Object::new());
let id = calculate_new_id(create.kuid, MetaFlags::default());
let obj = Arc::new(Object::new(id));
for src in srcs {
if src.id.as_u128() == 0 {
if src.id.raw() == 0 {
crate::obj::copy::zero_ranges(&obj, src.dest_start as usize, src.len)
} else {
let so = crate::obj::lookup_object(src.id, LookupFlags::empty())
Expand Down
1 change: 1 addition & 0 deletions src/kernel/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use twizzler_abi::syscall::{ClockInfo, FemtoSeconds};

use crate::spinlock::Spinlock;

#[derive(Default, Debug, Clone, Copy)]
pub struct Ticks {
pub value: u64,
pub rate: FemtoSeconds,
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/userinit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
};

pub fn create_blank_object() -> ObjectRef {
let obj = crate::obj::Object::new();
let obj = crate::obj::Object::new_kernel();
let obj = Arc::new(obj);
crate::obj::register_object(obj.clone());
obj
Expand Down
4 changes: 2 additions & 2 deletions src/lib/twizzler-abi/src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use crate::{
};

/// Flags for objects.
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
#[repr(transparent)]
pub struct MetaFlags(u32);

/// A nonce for avoiding object ID collision.
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
#[repr(transparent)]
pub struct Nonce(u128);

Expand Down
12 changes: 6 additions & 6 deletions src/lib/twizzler-abi/src/syscall/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ bitflags! {
#[repr(C)]
/// Full object creation specification, minus ties.
pub struct ObjectCreate {
kuid: ObjID,
bt: BackingType,
lt: LifetimeType,
flags: ObjectCreateFlags,
pub kuid: ObjID,
pub bt: BackingType,
pub lt: LifetimeType,
pub flags: ObjectCreateFlags,
}
impl ObjectCreate {
/// Build a new object create specification.
Expand All @@ -110,8 +110,8 @@ impl ObjectCreate {
/// A specification of ties to create.
/// (see [the book](https://twizzler-operating-system.github.io/nightly/book/object_lifetime.html) for more information on ties).
pub struct CreateTieSpec {
id: ObjID,
flags: CreateTieFlags,
pub id: ObjID,
pub flags: CreateTieFlags,
}

impl CreateTieSpec {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/twizzler-abi/src/syscall/time/units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub struct NanoSeconds(pub u64);
#[repr(transparent)]
pub struct PicoSeconds(pub u64);

#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Default)]
#[repr(transparent)]
pub struct FemtoSeconds(pub u64);

Expand Down

0 comments on commit 3d4f4fa

Please sign in to comment.