Skip to content

Commit 5670cbb

Browse files
authored
uh_mem: Properly reset permissions when unsharing pages (#1891)
When we are sharing a page we remove all VTL 0 permissions to that page. Later on, when we re-private the page, we were failing to reset these permissions, which led to failures when the guest tried to use pages it should have had access to. This code is a bit confusing due to conflating private/shared with VTL 1 access permissions. Add a bunch of comments, and fix the reset.
1 parent cb75706 commit 5670cbb

File tree

3 files changed

+13
-36
lines changed

3 files changed

+13
-36
lines changed

openhcl/underhill_mem/src/lib.rs

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use hvdef::HV_PAGE_SIZE;
3232
use hvdef::HvError;
3333
use hvdef::HvMapGpaFlags;
3434
use hvdef::HypercallCode;
35-
use hvdef::Vtl;
3635
use hvdef::hypercall::AcceptMemoryType;
3736
use hvdef::hypercall::HostVisibilityType;
3837
use hvdef::hypercall::HvInputVtl;
@@ -399,7 +398,6 @@ impl HardwareIsolatedMemoryProtector {
399398
fn apply_protections_with_overlay_handling(
400399
&self,
401400
range: MemoryRange,
402-
calling_vtl: Vtl,
403401
target_vtl: GuestVtl,
404402
protections: HvMapGpaFlags,
405403
inner: &mut MutexGuard<'_, HardwareIsolatedMemoryProtectorInner>,
@@ -431,7 +429,7 @@ impl HardwareIsolatedMemoryProtector {
431429
}
432430
// We can only reach here if the range does not contain any overlay
433431
// pages, so now we can apply the protections to the range.
434-
self.apply_protections(range, calling_vtl, target_vtl, protections)?
432+
self.apply_protections(range, target_vtl, protections)?
435433
}
436434

437435
Ok(())
@@ -440,12 +438,11 @@ impl HardwareIsolatedMemoryProtector {
440438
fn apply_protections(
441439
&self,
442440
range: MemoryRange,
443-
calling_vtl: Vtl,
444441
target_vtl: GuestVtl,
445442
protections: HvMapGpaFlags,
446443
) -> Result<(), ApplyVtlProtectionsError> {
447-
if calling_vtl == Vtl::Vtl1 && target_vtl == GuestVtl::Vtl0 {
448-
// Only VTL 1 permissions imposed on VTL 0 are explicitly tracked
444+
if target_vtl == GuestVtl::Vtl0 {
445+
// Only permissions imposed on VTL 0 are explicitly tracked
449446
self.vtl0.update_permission_bitmaps(range, protections);
450447
}
451448
self.acceptor
@@ -590,7 +587,10 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
590587
for &range in &ranges {
591588
if shared && vtl == GuestVtl::Vtl0 {
592589
// Accessing these pages through the encrypted mapping is now
593-
// invalid. Make sure the VTL bitmaps reflect this.
590+
// invalid. Make sure the VTL bitmaps reflect this. We could
591+
// call apply_protections here but that would result in an extra
592+
// hardware interaction that we don't need since we're about to
593+
// unaccept the pages anyways.
594594
self.vtl0
595595
.update_permission_bitmaps(range, HV_MAP_GPA_PERMISSIONS_NONE);
596596
}
@@ -722,20 +722,12 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
722722
// overlay pages won't be host visible, so just apply the default
723723
// protections directly without handling them.
724724
for &range in &ranges {
725-
self.apply_protections(
726-
range,
727-
if self.vtl1_protections_enabled() {
728-
Vtl::Vtl1
729-
} else {
730-
Vtl::Vtl2
731-
},
732-
GuestVtl::Vtl0,
733-
inner.default_vtl_permissions.vtl0,
734-
)
735-
.expect("should be able to apply default protections");
725+
// Make sure we reset the permissions bitmaps for VTL 0.
726+
self.apply_protections(range, GuestVtl::Vtl0, inner.default_vtl_permissions.vtl0)
727+
.expect("should be able to apply default protections");
736728

737729
if let Some(vtl1_protections) = inner.default_vtl_permissions.vtl1 {
738-
self.apply_protections(range, Vtl::Vtl2, GuestVtl::Vtl1, vtl1_protections)
730+
self.apply_protections(range, GuestVtl::Vtl1, vtl1_protections)
739731
.expect(
740732
"everything should be in a state where we can apply VTL protections",
741733
);
@@ -784,7 +776,6 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
784776

785777
fn change_default_vtl_protections(
786778
&self,
787-
calling_vtl: Vtl,
788779
target_vtl: GuestVtl,
789780
vtl_protections: HvMapGpaFlags,
790781
tlb_access: &mut dyn TlbFlushLockAccess,
@@ -837,7 +828,6 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
837828
for range in ranges {
838829
self.apply_protections_with_overlay_handling(
839830
range,
840-
calling_vtl,
841831
target_vtl,
842832
vtl_protections,
843833
&mut inner,
@@ -858,7 +848,6 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
858848

859849
fn change_vtl_protections(
860850
&self,
861-
calling_vtl: Vtl,
862851
target_vtl: GuestVtl,
863852
gpns: &[u64],
864853
protections: HvMapGpaFlags,
@@ -901,7 +890,6 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
901890
for range in ranges {
902891
self.apply_protections_with_overlay_handling(
903892
range,
904-
calling_vtl,
905893
target_vtl,
906894
protections,
907895
&mut inner,
@@ -964,13 +952,8 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
964952

965953
// Everything's validated, change the permissions.
966954
if let Some(new_perms) = new_perms {
967-
self.apply_protections(
968-
MemoryRange::from_4k_gpn_range(gpn..gpn + 1),
969-
Vtl::Vtl2,
970-
vtl,
971-
new_perms,
972-
)
973-
.map_err(|_| HvError::OperationDenied)?;
955+
self.apply_protections(MemoryRange::from_4k_gpn_range(gpn..gpn + 1), vtl, new_perms)
956+
.map_err(|_| HvError::OperationDenied)?;
974957
}
975958

976959
// Nothing from this point on can fail, so we can safely register the overlay page.
@@ -1022,7 +1005,6 @@ impl ProtectIsolatedMemory for HardwareIsolatedMemoryProtector {
10221005
// Restore its permissions.
10231006
self.apply_protections(
10241007
MemoryRange::from_4k_gpn_range(gpn..gpn + 1),
1025-
Vtl::Vtl2,
10261008
vtl,
10271009
overlay_pages[index].previous_permissions,
10281010
)

openhcl/virt_mshv_vtl/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,6 @@ pub trait ProtectIsolatedMemory: Send + Sync {
13801380
/// hardware-isolated VMs, they apply just to the given vtl.
13811381
fn change_default_vtl_protections(
13821382
&self,
1383-
calling_vtl: Vtl,
13841383
target_vtl: GuestVtl,
13851384
protections: HvMapGpaFlags,
13861385
tlb_access: &mut dyn TlbFlushLockAccess,
@@ -1389,7 +1388,6 @@ pub trait ProtectIsolatedMemory: Send + Sync {
13891388
/// Changes the vtl protections on a range of guest memory.
13901389
fn change_vtl_protections(
13911390
&self,
1392-
calling_vtl: Vtl,
13931391
target_vtl: GuestVtl,
13941392
gpns: &[u64],
13951393
protections: HvMapGpaFlags,

openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,6 @@ impl<T, B: HardwareIsolatedBacking> hv1_hypercall::ModifyVtlProtectionMask
12171217
// 1 can set the protections, the permissions should be changed for VTL
12181218
// 0.
12191219
protector.change_vtl_protections(
1220-
self.intercepted_vtl.into(),
12211220
GuestVtl::Vtl0,
12221221
gpa_pages,
12231222
map_flags,
@@ -1299,7 +1298,6 @@ impl<T, B: HardwareIsolatedBacking> hv1_hypercall::EnablePartitionVtl
12991298
// Grant VTL 1 access to lower VTL memory
13001299
tracing::debug!("Granting VTL 1 access to lower VTL memory");
13011300
protector.change_default_vtl_protections(
1302-
Vtl::Vtl2,
13031301
GuestVtl::Vtl1,
13041302
hvdef::HV_MAP_GPA_PERMISSIONS_ALL,
13051303
&mut self.vp.tlb_flush_lock_access(),
@@ -1773,7 +1771,6 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
17731771
}
17741772

17751773
protector.change_default_vtl_protections(
1776-
vtl.into(),
17771774
targeted_vtl,
17781775
protections,
17791776
&mut self.tlb_flush_lock_access(),

0 commit comments

Comments
 (0)