x86/
tlb.rs

1//! Functions to flush the translation lookaside buffer (TLB).
2
3use core::arch::asm;
4
5/// Invalidate the given address in the TLB using the `invlpg` instruction.
6///
7/// # Safety
8/// This function is unsafe as it causes a general protection fault (GP) if the current privilege
9/// level is not 0.
10pub unsafe fn flush(addr: usize) {
11    asm!("invlpg ({})", in(reg) addr, options(att_syntax, nostack, preserves_flags));
12}
13
14/// Invalidate the TLB completely by reloading the CR3 register.
15///
16/// # Safety
17/// This function is unsafe as it causes a general protection fault (GP) if the current privilege
18/// level is not 0.
19pub unsafe fn flush_all() {
20    use crate::controlregs::{cr3, cr3_write};
21    cr3_write(cr3())
22}
23
24#[cfg(all(test, feature = "vmtest"))]
25mod x86testing {
26    use super::*;
27    use x86test::*;
28
29    #[x86test]
30    fn check_flush_all() {
31        unsafe {
32            flush_all();
33        }
34    }
35
36    #[x86test]
37    fn check_flush() {
38        // A better test would be:
39        // map page, read page, unmap page, read page, flush, read page -> pfault
40        unsafe {
41            flush(0xdeadbeef);
42        }
43    }
44}