Skip to content

Commit

Permalink
Merge pull request #204 from msft-jlange/pagestate
Browse files Browse the repository at this point in the history
Add utility function to change visibility of SVSM pages
  • Loading branch information
joergroedel authored Jan 11, 2024
2 parents 7cbc6dd + a4110bb commit a77c74b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod address_space;
pub mod alloc;
pub mod guestmem;
pub mod memory;
pub mod page_visibility;
pub mod pagetable;
pub mod ptguards;
pub mod stack;
Expand Down
71 changes: 71 additions & 0 deletions src/mm/page_visibility.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) Microsoft Corporation
//
// Author: Jon Lange (jlange@microsoft.com)

use crate::address::VirtAddr;
use crate::cpu::flush_tlb_global_sync;
use crate::cpu::percpu::this_cpu_mut;
use crate::mm::validate::{
valid_bitmap_clear_valid_4k, valid_bitmap_set_valid_4k, valid_bitmap_valid_addr,
};
use crate::mm::virt_to_phys;
use crate::sev::ghcb::PageStateChangeOp;
use crate::sev::utils::pvalidate;
use crate::sev::PvalidateOp;
use crate::types::{PageSize, PAGE_SIZE};

pub fn make_page_shared(vaddr: VirtAddr) {
// Revoke page validation before changing page state.
pvalidate(vaddr, PageSize::Regular, PvalidateOp::Invalid)
.expect("Pvalidate failed when making page shared");
let paddr = virt_to_phys(vaddr);
if valid_bitmap_valid_addr(paddr) {
valid_bitmap_clear_valid_4k(paddr);
}

// Ask the hypervisor to make the page shared.
let cpu = this_cpu_mut();
cpu.ghcb()
.page_state_change(
paddr,
paddr + PAGE_SIZE,
PageSize::Regular,
PageStateChangeOp::PscShared,
)
.expect("Hypervisor failed to make page shared");

// Update the page tables to map the page as shared.
cpu.get_pgtable()
.set_shared_4k(vaddr)
.expect("Failed to remap shared page in page tables");
flush_tlb_global_sync();
}

pub fn make_page_private(vaddr: VirtAddr) {
// Update the page tables to map the page as private.
let cpu = this_cpu_mut();
cpu.get_pgtable()
.set_encrypted_4k(vaddr)
.expect("Failed to remap private page in page tables");
flush_tlb_global_sync();

// Ask the hypervisor to make the page private.
let paddr = virt_to_phys(vaddr);
cpu.ghcb()
.page_state_change(
paddr,
paddr + PAGE_SIZE,
PageSize::Regular,
PageStateChangeOp::PscPrivate,
)
.expect("Hypervisor failed to make page shared");

// Revoke page validation before changing page state.
pvalidate(vaddr, PageSize::Regular, PvalidateOp::Valid)
.expect("Pvalidate failed when making page private");
if valid_bitmap_valid_addr(paddr) {
valid_bitmap_set_valid_4k(paddr);
}
}

0 comments on commit a77c74b

Please sign in to comment.