Skip to content

Commit

Permalink
Fixes incorrect keg_small_init implementation (#1246)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Jan 12, 2025
1 parent a5972f0 commit f2ef2e2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
32 changes: 28 additions & 4 deletions kernel/src/uma/keg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use super::slab::RcFree;
use super::UmaFlags;
use crate::config::PAGE_SIZE;
use crate::uma::slab::{Free, SlabHdr};
use crate::uma::Uma;
use core::alloc::Layout;
use core::cmp::max;
use core::num::NonZero;

/// Implementation of `uma_keg` structure.
Expand All @@ -15,7 +17,7 @@ impl UmaKeg {
/// | Version | Offset |
/// |---------|--------|
/// |PS4 11.00|0x13CF40|
pub(super) fn new(size: NonZero<usize>, _: usize, mut flags: UmaFlags) -> Self {
pub(super) fn new(size: NonZero<usize>, align: usize, mut flags: UmaFlags) -> Self {
if flags.has(UmaFlags::Vm) {
todo!()
}
Expand All @@ -41,10 +43,12 @@ impl UmaKeg {

min = min.pad_to_align();

// Get UMA_FRITM_SZ and UMA_FRITMREF_SZ.
let free_item = min.size() - off;
let available = PAGE_SIZE.get() - min.size();

// TODO: Not sure why we need space at least for 2 free item?
if (size.get() + (min.size() - off)) > (PAGE_SIZE.get() - min.size()) {
todo!()
} else {
if (size.get() + free_item) > available {
// TODO: Set uk_ppera, uk_ipers and uk_rsize.
if !flags.has(UmaFlags::Internal) {
flags |= UmaFlags::Offpage;
Expand All @@ -53,6 +57,26 @@ impl UmaKeg {
flags |= UmaFlags::Hash;
}
}
} else {
// Get uk_rsize.
let rsize = max(size, Uma::SMALLEST_UNIT);
let rsize = if (align & rsize.get()) == 0 {
rsize.get()
} else {
// Size is not multiple of alignment, align up.
align + 1 + (!align & rsize.get())
};

// Get uk_ipers.
let ipers = available / (rsize + free_item);

// TODO: Verify if this valid for PAGE_SIZE < 0x4000.
if !flags.has(UmaFlags::Internal | UmaFlags::Cacheonly)
&& (available % (rsize + free_item)) >= Uma::MAX_WASTE.get()
&& (PAGE_SIZE.get() / rsize) > ipers
{
todo!()
}
}
}

Expand Down
12 changes: 10 additions & 2 deletions kernel/src/uma/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use self::zone::*;

use crate::config::PAGE_SIZE;
use alloc::string::String;
use alloc::sync::Arc;
use core::num::NonZero;
Expand All @@ -14,8 +15,13 @@ mod zone;
pub struct Uma {}

impl Uma {
/// See `uma_startup` on the Orbis for a reference. Beware that our implementation cannot access
/// the CPU context due to this function can be called before context activation.
/// `UMA_SMALLEST_UNIT`.
const SMALLEST_UNIT: NonZero<usize> = NonZero::new(PAGE_SIZE.get() / 256).unwrap();

/// `UMA_MAX_WASTE`.
const MAX_WASTE: NonZero<usize> = NonZero::new(PAGE_SIZE.get() / 10).unwrap();

/// See `uma_startup` on the Orbis for a reference.
///
/// # Reference offsets
/// | Version | Offset |
Expand Down Expand Up @@ -67,4 +73,6 @@ pub enum UmaFlags {
VToSlab = 0x2000,
/// `UMA_ZFLAG_INTERNAL`.
Internal = 0x20000000,
/// `UMA_ZFLAG_CACHEONLY`.
Cacheonly = 0x80000000,
}

0 comments on commit f2ef2e2

Please sign in to comment.