Skip to content

Commit

Permalink
Merge pull request #472 from rust-osdev/fix/pcid-no-flush
Browse files Browse the repository at this point in the history
add write_pcid_no_flush
  • Loading branch information
Freax13 authored Mar 19, 2024
2 parents 115f0e4 + 472d863 commit 306b3e1
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/registers/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ mod x86_64 {
#[inline]
pub unsafe fn write(frame: PhysFrame, flags: Cr3Flags) {
unsafe {
Cr3::write_raw(frame, flags.bits() as u16);
Cr3::write_raw_impl(false, frame, flags.bits() as u16);
}
}

Expand All @@ -322,7 +322,22 @@ mod x86_64 {
#[inline]
pub unsafe fn write_pcid(frame: PhysFrame, pcid: Pcid) {
unsafe {
Cr3::write_raw(frame, pcid.value());
Cr3::write_raw_impl(false, frame, pcid.value());
}
}

/// Write a new P4 table address into the CR3 register without flushing existing TLB entries for
/// the PCID.
///
/// ## Safety
///
/// Changing the level 4 page table is unsafe, because it's possible to violate memory safety by
/// changing the page mapping.
/// [`Cr4Flags::PCID`] must be set before calling this method.
#[inline]
pub unsafe fn write_pcid_no_flush(frame: PhysFrame, pcid: Pcid) {
unsafe {
Cr3::write_raw_impl(true, frame, pcid.value());
}
}

Expand All @@ -334,8 +349,13 @@ mod x86_64 {
/// changing the page mapping.
#[inline]
pub unsafe fn write_raw(frame: PhysFrame, val: u16) {
unsafe { Self::write_raw_impl(false, frame, val) }
}

#[inline]
unsafe fn write_raw_impl(top_bit: bool, frame: PhysFrame, val: u16) {
let addr = frame.start_address();
let value = addr.as_u64() | val as u64;
let value = ((top_bit as u64) << 63) | addr.as_u64() | val as u64;

unsafe {
asm!("mov cr3, {}", in(reg) value, options(nostack, preserves_flags));
Expand Down

0 comments on commit 306b3e1

Please sign in to comment.