Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(kernel/vm): allocate virtual memory spot #165

Merged
merged 56 commits into from
Dec 15, 2024
Merged
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0d7947e
refactor: use xmas-elf instead of object
JonasKruckenberg Nov 23, 2024
82903c1
refactor(loader): remove `alloc` dependency
JonasKruckenberg Nov 23, 2024
03351d3
refactor: remove `panic-abort` crate
JonasKruckenberg Nov 23, 2024
a015e07
refactor: remove `elf` feature from kmm and move into loader
JonasKruckenberg Nov 23, 2024
15877be
cleanup
JonasKruckenberg Nov 24, 2024
9b59ea8
wip
JonasKruckenberg Nov 27, 2024
42bb36a
feat: `Riscv64Sv39::from_active`
JonasKruckenberg Nov 28, 2024
a7bf4dc
feat(sync): `Once::try_call_once`
JonasKruckenberg Nov 28, 2024
57f3bf2
chore: debug printing for page tables
JonasKruckenberg Nov 28, 2024
34a39d7
chore: bring back kernel parsing
JonasKruckenberg Nov 28, 2024
95aba25
refactor(loader): use `pmm` for memory management
JonasKruckenberg Dec 6, 2024
c3a52ff
refactor: cleanup kernel for refactor
JonasKruckenberg Dec 6, 2024
09fa1b8
refactor: reduce memory size for QEMU
JonasKruckenberg Dec 6, 2024
7687068
remove kmm
JonasKruckenberg Dec 7, 2024
532c1f3
Merge branch 'main' into new-vm2
JonasKruckenberg Dec 7, 2024
60d940c
fmt & fixes
JonasKruckenberg Dec 7, 2024
0c5ffe7
cleanup
JonasKruckenberg Dec 10, 2024
071001d
feat(loader): allocate & map kernel heap
JonasKruckenberg Dec 10, 2024
d52cf83
wip
JonasKruckenberg Dec 10, 2024
33097ee
fix(loader): correctly report memory regions ptr and len
JonasKruckenberg Dec 11, 2024
ed7de8a
wip(wavltree): impl Send and Sync for tree
JonasKruckenberg Dec 11, 2024
f4ec629
fmt
JonasKruckenberg Dec 11, 2024
5e417bd
refactor: move `vmm` crate into kernel
JonasKruckenberg Dec 11, 2024
5abeeed
wip
JonasKruckenberg Dec 11, 2024
d55558a
refactor(pmm): remove overengineered arch trait
JonasKruckenberg Dec 12, 2024
ae5e4ab
wavltree fixes
JonasKruckenberg Dec 12, 2024
4307fa3
cleanup
JonasKruckenberg Dec 12, 2024
e5c0581
fmt
JonasKruckenberg Dec 12, 2024
51c38a1
Merge branch 'main' into new-vm2
JonasKruckenberg Dec 12, 2024
21029ae
Merge branch 'main' into new-vm2
JonasKruckenberg Dec 12, 2024
470dcd6
Update once.rs
JonasKruckenberg Dec 12, 2024
102c70c
Merge branch 'main' into new-vm2
JonasKruckenberg Dec 12, 2024
7a1a735
cleanup
JonasKruckenberg Dec 12, 2024
f602dd3
refactor: report FDT memory region through `BootInfo.memory_regions` …
JonasKruckenberg Dec 12, 2024
b2610e7
cleanup
JonasKruckenberg Dec 12, 2024
7a623b6
fix: report FDT through memory regions array
JonasKruckenberg Dec 12, 2024
a144dcd
fix: correctly handle unmapping
JonasKruckenberg Dec 12, 2024
2f2de68
clippy
JonasKruckenberg Dec 12, 2024
12ad8bd
fix: use virtual FDT address is test runner
JonasKruckenberg Dec 12, 2024
ae78433
refactor: rename `AddressSpace:: phys_offset` to `AddressSpace:: phys…
JonasKruckenberg Dec 12, 2024
62d6be3
docs
JonasKruckenberg Dec 12, 2024
a38bb24
fmt
JonasKruckenberg Dec 12, 2024
2456619
feat(wavltree): implement lifecycle hooks
JonasKruckenberg Dec 13, 2024
ac66b51
feat(kernel/vm): implement efficient gap search state
JonasKruckenberg Dec 13, 2024
7d3a63c
feat(kernel/vm): use prng for ASLR
JonasKruckenberg Dec 13, 2024
0e7f7ae
refactor: remove ambiguous and broken `cursor`/`cursor_mut` in favor …
JonasKruckenberg Dec 12, 2024
a91258b
chore(wavltree): release v0.0.1 (#161)
github-actions[bot] Dec 12, 2024
3976974
chore(deps): update rust crate target-lexicon to 0.13.0 (#157)
renovate[bot] Dec 12, 2024
590938a
feat(kernel): parse FDT on startup
JonasKruckenberg Dec 13, 2024
4f9616f
fix: seed ASLR prng from provided seed
JonasKruckenberg Dec 13, 2024
7401f98
feat(kernel/vm): allocate virtual memory spot
JonasKruckenberg Dec 13, 2024
10be9a9
wip: test the pick_spot impl
JonasKruckenberg Dec 13, 2024
d35d64c
clippy & fmt
JonasKruckenberg Dec 14, 2024
88a3941
refactor: move find_spot tests into tests
JonasKruckenberg Dec 14, 2024
6a0c727
fmt
JonasKruckenberg Dec 14, 2024
077ed06
update from main
JonasKruckenberg Dec 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(kernel/vm): implement efficient gap search state
This change uses the `wavltree` lifecycle hooks to maintain an augmented version of the WAVLTree that supports more efficient gap search. This is inspired by a similar inspiration in the Zircon kernel and works by tracking the largest and smallest address of each nodes subtree, as well as the biggest gap in each subtree.
  • Loading branch information
JonasKruckenberg committed Dec 14, 2024
commit ac66b5182677b128757e5a172191eac027d6ff2c
97 changes: 96 additions & 1 deletion kernel/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,25 +278,82 @@ impl AddressSpace {

pin_project! {
pub struct Mapping {
links: wavltree::Links<Mapping>,
range: Range<VirtualAddress>,
flags: pmm::Flags,
links: wavltree::Links<Mapping>,
min_first_byte: VirtualAddress,
max_last_byte: VirtualAddress,
max_gap: usize
}
}
impl fmt::Debug for Mapping {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Mapping")
.field("range", &self.range)
.field("flags", &self.flags)
.field("min_first_byte", &self.min_first_byte)
.field("max_last_byte", &self.max_last_byte)
.field("max_gap", &self.max_gap)
.finish_non_exhaustive()
}
}
impl Mapping {
pub fn new(range: Range<VirtualAddress>, flags: pmm::Flags) -> Self {
Self {
links: wavltree::Links::default(),
min_first_byte: range.start,
max_last_byte: range.end,
range,
flags,
max_gap: 0,
}
}

unsafe fn update(
mut node: NonNull<Self>,
left: Option<NonNull<Self>>,
right: Option<NonNull<Self>>,
) {
let node = node.as_mut();
let mut left_max_gap = 0;
let mut right_max_gap = 0;

if let Some(left) = left {
let left = left.as_ref();
let left_gap = gap(left.max_last_byte, node.range.start);
left_max_gap = cmp::max(left_gap, left.max_gap);
node.min_first_byte = left.min_first_byte;
} else {
node.min_first_byte = node.range.start;
}

if let Some(right) = right {
let right = right.as_ref();
let right_gap = gap(node.range.end, right.min_first_byte);
right_max_gap = cmp::max(right_gap, unsafe { right.max_gap });
node.max_last_byte = right.max_last_byte;
} else {
node.max_last_byte = node.range.end;
}

node.max_gap = cmp::max(left_max_gap, right_max_gap);

fn gap(left_last_byte: VirtualAddress, right_first_byte: VirtualAddress) -> usize {
debug_assert!(
left_last_byte < right_first_byte,
"subtraction would underflow: {left_last_byte} >= {right_first_byte}"
);
right_first_byte.sub_addr(left_last_byte)
}
}

fn propagate_to_root(mut maybe_node: Option<NonNull<Self>>) {
while let Some(node) = maybe_node {
let links = unsafe { &node.as_ref().links };
unsafe {
Self::update(node, links.left(), links.right());
}
maybe_node = links.parent();
}
}
}
Expand Down Expand Up @@ -333,4 +390,42 @@ unsafe impl wavltree::Linked for Mapping {
fn get_key(&self) -> &Self::Key {
&self.range.start
}

fn after_insert(self: Pin<&mut Self>) {
debug_assert_eq!(self.min_first_byte, self.range.start);
debug_assert_eq!(self.max_last_byte, self.range.end);
debug_assert_eq!(self.max_gap, 0);
Self::propagate_to_root(self.links.parent());
}

fn after_remove(self: Pin<&mut Self>, parent: Option<NonNull<Self>>) {
Self::propagate_to_root(parent);
}

fn after_rotate(
mut self: Pin<&mut Self>,
parent: NonNull<Self>,
sibling: Option<NonNull<Self>>,
lr_child: Option<NonNull<Self>>,
side: Side,
) {
log::trace!("after rotate pivot: {self:?} parent: {parent:?} sibling: {sibling:?} lr_child: {lr_child:?}");

let mut this = self.project();
let _parent = unsafe { parent.as_ref() };

*this.min_first_byte = _parent.min_first_byte;
*this.max_last_byte = _parent.max_last_byte;
*this.max_gap = _parent.max_gap;

if side == Side::Left {
unsafe {
Self::update(parent, sibling, lr_child);
}
} else {
unsafe {
Self::update(parent, lr_child, sibling);
}
}
}
}