Skip to content

Commit

Permalink
Use GuestVtl
Browse files Browse the repository at this point in the history
  • Loading branch information
sluck-msft committed Oct 25, 2024
1 parent dc689ca commit 8e58e32
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 38 deletions.
60 changes: 37 additions & 23 deletions openhcl/underhill_mem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,10 @@ mod mapping {
}

impl DefaultVtlPermissions {
fn set(&mut self, vtl: Vtl, permissions: HvMapGpaFlags) {
fn set(&mut self, vtl: GuestVtl, permissions: HvMapGpaFlags) {
match vtl {
Vtl::Vtl0 => self.vtl0 = permissions,
Vtl::Vtl1 => self.vtl1 = Some(permissions),
Vtl::Vtl2 => unreachable!(),
GuestVtl::Vtl0 => self.vtl0 = permissions,
GuestVtl::Vtl1 => self.vtl1 = Some(permissions),
}
}
}
Expand Down Expand Up @@ -616,7 +615,11 @@ mod mapping {
// TODO CVM GUEST VSM: track the permissions directly in
// underhill. For now, use rmpquery.
assert!(self.isolation == IsolationType::Snp);
let rmpadjust = self.mshv_vtl.rmpquery_page(gpa, vtl);
let rmpadjust = self.mshv_vtl.rmpquery_page(
gpa,
vtl.try_into()
.expect("only query non-VTL 2 permissions on hardware cvm"),
);

GpaVtlPermissions::Snp(rmpadjust)
}
Expand Down Expand Up @@ -690,7 +693,7 @@ mod mapping {
}

struct HypercallOverlayProtector {
vtl: Vtl,
vtl: GuestVtl,
protector: Arc<dyn ProtectIsolatedMemory>,
}

Expand Down Expand Up @@ -745,7 +748,7 @@ mod mapping {

fn apply_protections_with_overlay_handling(
&self,
vtl: Vtl,
vtl: GuestVtl,
ranges: &[MemoryRange],
protections: HvMapGpaFlags,
) -> Result<(), ApplyVtlProtectionsError> {
Expand All @@ -754,27 +757,33 @@ mod mapping {
for range in ranges {
match overlay_lock.as_mut() {
Some(overlay) if range.contains_addr(overlay.gpn * HV_PAGE_SIZE) => {
overlay.permissions.set(vtl, protections);
overlay.permissions.set(vtl.into(), protections);

let overlay_address = overlay.gpn * HV_PAGE_SIZE;
let overlay_offset = range.offset_of(overlay_address).unwrap();
let (left, right) = range.split_at_offset(overlay_offset);

self.acceptor
.apply_protections_from_flags(left, vtl, protections)?;
self.acceptor.apply_protections_from_flags(
left,
vtl.into(),
protections,
)?;
let sub_range =
MemoryRange::new((overlay.gpn + 1) * HV_PAGE_SIZE..right.end());
if !sub_range.is_empty() {
self.acceptor.apply_protections_from_flags(
sub_range,
vtl,
vtl.into(),
protections,
)?;
}
}
_ => {
self.acceptor
.apply_protections_from_flags(*range, vtl, protections)?;
self.acceptor.apply_protections_from_flags(
*range,
vtl.into(),
protections,
)?;
}
}
}
Expand All @@ -784,14 +793,14 @@ mod mapping {
/// Restore the original protections on the page that is overlaid.
fn restore_overlay_permissions(
&self,
vtl: Vtl,
vtl: GuestVtl,
overlay: &HypercallOverlay,
) -> Result<(), ApplyVtlProtectionsError> {
let range =
MemoryRange::new(overlay.gpn * HV_PAGE_SIZE..(overlay.gpn + 1) * HV_PAGE_SIZE);

self.acceptor
.apply_protections(range, vtl, overlay.permissions)?;
.apply_protections(range, vtl.into(), overlay.permissions)?;

Ok(())
}
Expand Down Expand Up @@ -1026,11 +1035,10 @@ mod mapping {

fn change_vtl_protections(
&self,
vtl: Vtl,
vtl: GuestVtl,
gpns: &[u64],
protections: HvMapGpaFlags,
) -> HvRepResult {
assert!(vtl < Vtl::Vtl2);
// Validate the ranges are RAM.
for &gpn in gpns {
if !self
Expand Down Expand Up @@ -1072,15 +1080,15 @@ mod mapping {

fn hypercall_overlay_protector(
self: Arc<Self>,
vtl: Vtl,
vtl: GuestVtl,
) -> Box<dyn VtlProtectHypercallOverlay> {
Box::new(HypercallOverlayProtector {
vtl,
protector: self.clone(),
})
}

fn change_hypercall_overlay(&self, vtl: Vtl, gpn: u64) {
fn change_hypercall_overlay(&self, vtl: GuestVtl, gpn: u64) {
// Should already have written contents to the page via the guest
// memory object, confirming that this is a guest page
assert!(self
Expand All @@ -1101,15 +1109,21 @@ mod mapping {

let current_permissions = match self.acceptor.isolation {
IsolationType::Vbs => unreachable!(),
IsolationType::Snp => self.acceptor.vtl_permissions(vtl, gpn * HV_PAGE_SIZE),
IsolationType::Snp => self
.acceptor
.vtl_permissions(vtl.into(), gpn * HV_PAGE_SIZE),
IsolationType::Tdx => {
// TODO TDX GUEST VSM: implement acceptor.vtl_permissions
// For now, since guest vsm isn't enabled, this overlay can
// only exist for VTL 0, which can't change its own
// permissions. So assume that the permissions haven't
// changed since VTL 2 initialized guest memory and they're
// still all.
GpaVtlPermissions::new(IsolationType::Tdx, vtl, HV_MAP_GPA_PERMISSIONS_ALL)
GpaVtlPermissions::new(
IsolationType::Tdx,
vtl.into(),
HV_MAP_GPA_PERMISSIONS_ALL,
)
}
};

Expand All @@ -1121,15 +1135,15 @@ mod mapping {
self.acceptor
.apply_protections_from_flags(
MemoryRange::new(gpn * HV_PAGE_SIZE..(gpn + 1) * HV_PAGE_SIZE),
vtl,
vtl.into(),
HV_MAP_GPA_PERMISSIONS_ALL,
)
.expect("applying vtl protections should succeed");

// TODO CVM GUEST VSM: flush TLB
}

fn disable_hypercall_overlay(&self, vtl: Vtl) {
fn disable_hypercall_overlay(&self, vtl: GuestVtl) {
let _lock = self.inner.lock();

let mut overlay = self.hypercall_overlay[vtl].lock();
Expand Down
16 changes: 8 additions & 8 deletions openhcl/virt_mshv_vtl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,7 @@ pub trait ProtectIsolatedMemory: Send + Sync {
/// Changes the vtl protections on a range of guest memory.
fn change_vtl_protections(
&self,
vtl: Vtl,
vtl: GuestVtl,
gpns: &[u64],
protections: HvMapGpaFlags,
) -> HvRepResult;
Expand All @@ -1142,14 +1142,14 @@ pub trait ProtectIsolatedMemory: Send + Sync {
/// VTL.
fn hypercall_overlay_protector(
self: Arc<Self>,
vtl: Vtl,
vtl: GuestVtl,
) -> Box<dyn VtlProtectHypercallOverlay>;

/// Changes the overlay for the hypercall code page for a target VTL.
fn change_hypercall_overlay(&self, vtl: Vtl, gpn: u64);
fn change_hypercall_overlay(&self, vtl: GuestVtl, gpn: u64);

/// Disables the overlay for the hypercall code page for a target VTL.
fn disable_hypercall_overlay(&self, vtl: Vtl);
fn disable_hypercall_overlay(&self, vtl: GuestVtl);
}

impl UhPartition {
Expand Down Expand Up @@ -1374,10 +1374,10 @@ impl UhPartition {
tsc_frequency,
ref_time,
hypercall_page_protectors: VtlArray::from_fn(|vtl| {
params
.isolated_memory_protector
.as_ref()
.map(|p| p.clone().hypercall_overlay_protector(vtl))
params.isolated_memory_protector.as_ref().map(|p| {
p.clone()
.hypercall_overlay_protector(vtl.try_into().expect("no vtl 2"))
})
}),
}))
} else {
Expand Down
10 changes: 4 additions & 6 deletions openhcl/virt_mshv_vtl/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1387,20 +1387,18 @@ impl<T: CpuIo, B: Backing> hv1_hypercall::ModifyVtlProtectionMask
}

if let Some(vtl) = target_vtl {
if vtl > self.vp.last_vtl() {
return Err((HvError::AccessDenied, 0));
}
let _target_vtl = self.target_vtl_no_higher(vtl).map_err(|e| (e, 0))?;
}

let target_vtl = target_vtl.unwrap_or(self.vp.last_vtl());
let target_vtl = target_vtl.unwrap_or(self.vp.last_vtl().into());
if target_vtl == Vtl::Vtl0 {
return Err((HvError::InvalidParameter, 0));
}

// A VTL cannot change its own VTL permissions until it has enabled VTL protection and
// configured default permissions. Higher VTLs are not under this restriction (as they may
// need to apply default permissions before VTL protection is enabled).
if target_vtl == self.vp.last_vtl() {
if target_vtl == self.vp.last_vtl().into() {
if let Some(guest_vsm) = self.vp.partition.guest_vsm.read().get_vtl1() {
if !guest_vsm.enable_vtl_protection {
return Err((HvError::AccessDenied, 0));
Expand Down Expand Up @@ -1436,7 +1434,7 @@ impl<T: CpuIo, B: Backing> hv1_hypercall::ModifyVtlProtectionMask
.isolated_memory_protector
.as_ref()
.expect("has a memory protector")
.change_vtl_protections(Vtl::Vtl0, gpa_pages, map_flags)?;
.change_vtl_protections(GuestVtl::Vtl0, gpa_pages, map_flags)?;
} else {
// TODO VBS GUEST VSM: verify this logic is correct
// TODO VBS GUEST VSM: validation on map_flags, similar to default
Expand Down
2 changes: 1 addition & 1 deletion openhcl/virt_mshv_vtl/src/processor/snp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ impl UhProcessor<'_, SnpBacked> {

// TODO CVM GUEST VSM actually check and run vtl 1
self.unlock_tlb_lock(Vtl::Vtl2);
let tlb_halt = self.should_halt_for_tlb_unlock(Vtl::Vtl0);
let tlb_halt = self.should_halt_for_tlb_unlock(GuestVtl::Vtl0);

self.runner.set_halted(
self.backing.lapics[GuestVtl::Vtl0].halted
Expand Down

0 comments on commit 8e58e32

Please sign in to comment.