Skip to content
Snippets Groups Projects
Commit a48ec82f authored by Robert Węcławski's avatar Robert Węcławski
Browse files

Use unused bits 52-61 in first entry of each page table as counter for number of page table entries

parent c2644adf
No related branches found
No related tags found
No related merge requests found
...@@ -59,4 +59,14 @@ impl Entry { ...@@ -59,4 +59,14 @@ impl Entry {
debug_assert!(frame.start_address().get() & !ADDRESS_MASK == 0); debug_assert!(frame.start_address().get() & !ADDRESS_MASK == 0);
self.0 = (frame.start_address().get() as u64) | flags.bits(); self.0 = (frame.start_address().get() as u64) | flags.bits();
} }
/// Get bits 52-61 in entry, used as counter for page table
pub fn counter_bits(&self) -> u64 {
(self.0 & 0x3ff00000_00000000) >> 52
}
/// Set bits 52-61 in entry, used as counter for page table
pub fn set_counter_bits(&mut self, count: u64) {
self.0 = ((self.0 & 0xc00fffff_ffffffff) | (count << 52));
}
} }
...@@ -107,6 +107,7 @@ impl Mapper { ...@@ -107,6 +107,7 @@ impl Mapper {
page.start_address().get(), page.start_address().get(),
p1[page.p1_index()].address().get(), p1[page.p1_index()].flags(), p1[page.p1_index()].address().get(), p1[page.p1_index()].flags(),
frame.start_address().get(), flags); frame.start_address().get(), flags);
p1.increment_entry_count();
p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT); p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT);
MapperFlush::new(page) MapperFlush::new(page)
} }
...@@ -146,6 +147,7 @@ impl Mapper { ...@@ -146,6 +147,7 @@ impl Mapper {
panic!("unmap_inner({:X}): frame not found", page.start_address().get()) panic!("unmap_inner({:X}): frame not found", page.start_address().get())
}; };
p1.decrement_entry_count();
p1[page.p1_index()].set_unused(); p1[page.p1_index()].set_unused();
if keep_parents || ! p1.is_unused() { if keep_parents || ! p1.is_unused() {
...@@ -157,13 +159,14 @@ impl Mapper { ...@@ -157,13 +159,14 @@ impl Mapper {
if let Some(p1_frame) = p2[page.p2_index()].pointed_frame() { if let Some(p1_frame) = p2[page.p2_index()].pointed_frame() {
//println!("Free p1 {:?}", p1_frame); //println!("Free p1 {:?}", p1_frame);
p2.decrement_entry_count();
p2[page.p2_index()].set_unused(); p2[page.p2_index()].set_unused();
deallocate_frames(p1_frame, 1); deallocate_frames(p1_frame, 1);
} else { } else {
panic!("unmap_inner({:X}): p1_frame not found", page.start_address().get()); panic!("unmap_inner({:X}): p1_frame not found", page.start_address().get());
} }
if keep_parents || ! p2.is_unused() { if ! p2.is_unused() {
return frame; return frame;
} }
} else { } else {
...@@ -172,13 +175,14 @@ impl Mapper { ...@@ -172,13 +175,14 @@ impl Mapper {
if let Some(p2_frame) = p3[page.p3_index()].pointed_frame() { if let Some(p2_frame) = p3[page.p3_index()].pointed_frame() {
//println!("Free p2 {:?}", p2_frame); //println!("Free p2 {:?}", p2_frame);
p3.decrement_entry_count();
p3[page.p3_index()].set_unused(); p3[page.p3_index()].set_unused();
deallocate_frames(p2_frame, 1); deallocate_frames(p2_frame, 1);
} else { } else {
panic!("unmap_inner({:X}): p2_frame not found", page.start_address().get()); panic!("unmap_inner({:X}): p2_frame not found", page.start_address().get());
} }
if keep_parents || ! p3.is_unused() { if ! p3.is_unused() {
return frame; return frame;
} }
} else { } else {
...@@ -187,6 +191,7 @@ impl Mapper { ...@@ -187,6 +191,7 @@ impl Mapper {
if let Some(p3_frame) = p4[page.p4_index()].pointed_frame() { if let Some(p3_frame) = p4[page.p4_index()].pointed_frame() {
//println!("Free p3 {:?}", p3_frame); //println!("Free p3 {:?}", p3_frame);
p4.decrement_entry_count();
p4[page.p4_index()].set_unused(); p4[page.p4_index()].set_unused();
deallocate_frames(p3_frame, 1); deallocate_frames(p3_frame, 1);
} else { } else {
......
...@@ -46,10 +46,8 @@ pub struct Table<L: TableLevel> { ...@@ -46,10 +46,8 @@ pub struct Table<L: TableLevel> {
impl<L> Table<L> where L: TableLevel { impl<L> Table<L> where L: TableLevel {
pub fn is_unused(&self) -> bool { pub fn is_unused(&self) -> bool {
for entry in self.entries.iter() { if self.entry_count() > 0 {
if ! entry.is_unused() { return false;
return false;
}
} }
true true
...@@ -60,6 +58,27 @@ impl<L> Table<L> where L: TableLevel { ...@@ -60,6 +58,27 @@ impl<L> Table<L> where L: TableLevel {
entry.set_unused(); entry.set_unused();
} }
} }
/// Set number of entries in first table entry
fn set_entry_count(&mut self, count: u64) {
assert!(count <= ENTRY_COUNT, "count can't be greater than ENTRY_COUNT");
self.entries[0].set_counter_bits(count);
}
/// Get number of entries in first table entry
fn entry_count(&self) -> u64 {
self.entries[0].counter_bits()
}
pub fn increment_entry_count(&mut self) {
let current_count = self.entry_count();
self.set_entry_count(current_count + 1);
}
pub fn decrement_entry_count(&mut self) {
let current_count = self.entry_count();
self.set_entry_count(current_count - 1);
}
} }
impl<L> Table<L> where L: HierarchicalLevel { impl<L> Table<L> where L: HierarchicalLevel {
...@@ -76,6 +95,7 @@ impl<L> Table<L> where L: HierarchicalLevel { ...@@ -76,6 +95,7 @@ impl<L> Table<L> where L: HierarchicalLevel {
assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE), assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE),
"next_table_create does not support huge pages"); "next_table_create does not support huge pages");
let frame = allocate_frames(1).expect("no frames available"); let frame = allocate_frames(1).expect("no frames available");
self.increment_entry_count();
self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */); self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */);
self.next_table_mut(index).unwrap().zero(); self.next_table_mut(index).unwrap().zero();
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment