From f52d556e0e1bf2350b3b42cff198550a267ceb0b Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Wed, 15 Nov 2023 22:40:07 +0100 Subject: example/long_mode: demonstrate mmio exits for virtually mapped but not physically backed memory --- examples/long_mode.rs | 14 +++++++++++--- guest/guest64.S | 7 +++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/long_mode.rs b/examples/long_mode.rs index 5969a48..03a77a4 100644 --- a/examples/long_mode.rs +++ b/examples/long_mode.rs @@ -76,8 +76,11 @@ fn setup_long_mode_4level_paging(mem: &mut UserMem) -> PhysAddr { // 0x3000 | PT | VirtAddr // 0x4000 +-------+ <----- +-------+ 0x0000 // | Guest | | Guest | - // | (16K) | | (16K) | - // 0x8000 +-------+ <----- +-------+ 0x4000 + // | (16K) | | (20K) | + // 0x8000 +-------+ | | 0x4000 + // UN-MAPPED | | + // ( 4k) | | + // 0x9000 +-------+ <----- +-------+ 0x5000 // // PML4 : Page Map Level 4 // PDP : Page Directory Pointer @@ -85,7 +88,7 @@ fn setup_long_mode_4level_paging(mem: &mut UserMem) -> PhysAddr { // PT : Page Table // // PML4, PDP, PD will contain a single entry at index 0. - // PT will contain 4 page table entries (PTE) at index {0,1,2,3} -> 4 * 4K = 16K. + // PT will contain 5 page table entries (PTE) at index {0,1,2,3,4} -> 5 * 4K = 20K. let mut w = |addr: PhysAddr, val: u64| mem.load(addr, &val.to_le_bytes()); @@ -105,6 +108,11 @@ fn setup_long_mode_4level_paging(mem: &mut UserMem) -> PhysAddr { w(PhysAddr(0x3010), PAGE_ENTRY_PRESENT | PAGE_ENTRY_RW | 0x6000); // PTE[3] maps Virt [0x3000:0x3fff] -> Phys [0x7000:0x7fff]. w(PhysAddr(0x3018), PAGE_ENTRY_PRESENT | PAGE_ENTRY_RW | 0x7000); + // PTE[4] maps Virt [0x4000:0x4fff] -> Phys [0x8000:0x8fff] + // + // The PA range is not backed by a memory mapping in the VM and hence + // writing to the VA range from the guest should trigger a VM MMIO exit. + w(PhysAddr(0x3020), PAGE_ENTRY_PRESENT | PAGE_ENTRY_RW | 0x8000); // Return address of PML4. PhysAddr(0x0000) diff --git a/guest/guest64.S b/guest/guest64.S index 533d186..1ca91a5 100644 --- a/guest/guest64.S +++ b/guest/guest64.S @@ -18,6 +18,13 @@ mov byte ptr ds:[0x2002], 0xcc mov byte ptr ds:[0x2003], 0xdd + // Write to virtually mapped by not physically mapped address, this should + // trigger a `KVM_EXIT_MMIO (w)`. + mov byte ptr ds:[0x4000], 0x12 + mov byte ptr ds:[0x4001], 0x34 + mov byte ptr ds:[0x4002], 0x56 + mov byte ptr ds:[0x4003], 0x78 + // Trigger `KVM_EXIT_HLT`. hlt -- cgit v1.2.3