Skip to content

Commit

Permalink
shift making rootpage writable to paging.rs, adding function for re-s…
Browse files Browse the repository at this point in the history
…etting WP bit after making rootpage writable
  • Loading branch information
sarahspberrypi authored and mkroening committed Sep 25, 2023
1 parent abc7b53 commit 5dfa426
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
4 changes: 0 additions & 4 deletions src/arch/x86_64/kernel/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,10 +784,6 @@ pub fn configure() {
wrmsr(IA32_EFER, rdmsr(IA32_EFER) | EFER_LMA | EFER_SCE | EFER_NXE);
}

// Check rootpagetable and make it writable if it isn't
// Necessary for memory manipulation
crate::arch::x86_64::mm::paging::check_root_pagetable();

//
// CR0 CONFIGURATION
//
Expand Down
34 changes: 24 additions & 10 deletions src/arch/x86_64/mm/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ pub fn map<S>(
flush.flush();
debug!("Had to unmap page {page:?} before mapping.");
}
let result = pt.identity_map(frame, flags, &mut physicalmem::FrameAlloc);
// .unwrap()
// .flush();
pt.identity_map(frame, flags, &mut physicalmem::FrameAlloc)
.unwrap()
.flush();
}
}
}
Expand Down Expand Up @@ -256,7 +256,11 @@ pub fn get_application_page_size() -> usize {
LargePageSize::SIZE as usize
}

pub fn init() {}
pub fn init() {
if crate::arch::x86_64::kernel::is_uefi().is_ok() {
check_root_pagetable();
}
}

pub fn init_page_tables() {
if env::is_uhyve() {
Expand Down Expand Up @@ -284,12 +288,12 @@ pub fn init_page_tables() {
}

/// Checks the address stored in the CR3 register and if necessary, makes its page writable.
pub fn check_root_pagetable() {
fn check_root_pagetable() {
use x86_64::structures::paging::mapper::TranslateResult;
let level_4_table_addr = Cr3::read().0.start_address().as_u64();
let virt_lvl_4_addr = x86_64::VirtAddr::new(level_4_table_addr);
let mut pt = unsafe { identity_mapped_page_table() };
set_cr0_flags();
clear_WP_bit();
match pt.translate(virt_lvl_4_addr) {
TranslateResult::Mapped {
frame,
Expand All @@ -309,21 +313,31 @@ pub fn check_root_pagetable() {
TranslateResult::NotMapped => todo!(),
TranslateResult::InvalidFrameAddress(_) => todo!(),
};
set_WP_bit();
}

/// Clears the WRITE_PROTECT bit in order to write into read-only Pages in supervisor mode
fn set_cr0_flags() {
/// Clears the WRITE_PROTECT bit in order to write into read-only Pages in supervisor mode.
fn clear_WP_bit() {
let mut cr0 = Cr0::read();

//Clear WRITE_PROTECT in order to write in read-only pages in supervisor mode
if cr0.contains(Cr0Flags::WRITE_PROTECT) {
trace!("clear WRITE_PROTECT bit temporarily");
unsafe {
cr0.remove(Cr0Flags::WRITE_PROTECT);
Cr0::write(cr0);
}
trace!("Cr0 flags: {:?}", Cr0::read());
debug!("Cr0 flags: {:?}", Cr0::read());
}
}

/// Sets the WRITE_PROTECT bit in order to prevent writing into read-only Pages even in supervisor mode.
fn set_WP_bit() {
let mut cr0 = Cr0::read();
unsafe {
cr0.insert(Cr0Flags::WRITE_PROTECT);
Cr0::write(cr0);
}
debug!("Cr0 flags: {:?}", Cr0::read());
}

/// This function takes the rootpage and depending on its size (1GiB, 2MiB, 4KiB), changes the flags to make it writable and then flushes the TLB.
Expand Down

0 comments on commit 5dfa426

Please sign in to comment.