Skip to content

Commit ed7efaa

Browse files
committed
Fix potential stale
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
1 parent 9954908 commit ed7efaa

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

  • src/hyperlight_host/src/hypervisor/virtual_machine

src/hyperlight_host/src/hypervisor/virtual_machine/whp.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,12 @@ impl VirtualMachine for WhpVm {
555555
let whp_regs: [(WHV_REGISTER_NAME, Align16<WHV_REGISTER_VALUE>); WHP_SREGS_NAMES_LEN] =
556556
sregs.into();
557557

558+
// TODO: Remove this filter and instead fix the callers to pass
559+
// the correct APIC_BASE value (e.g. read it from the VP before
560+
// the first set_sregs, or use 0xFEE00900 in standard_64bit_defaults).
561+
// Filtering here causes AMD/SVM bugs because SVM_CLEAN_FIELD_AVIC
562+
// is never dirtied after WHvResetPartition (see reset_partition).
563+
//
558564
// When LAPIC emulation is active (always with hw-interrupts),
559565
// skip writing APIC_BASE. The generic CommonSpecialRegisters
560566
// defaults APIC_BASE to 0 which would globally disable the LAPIC.
@@ -730,6 +736,23 @@ impl VirtualMachine for WhpVm {
730736
#[cfg(feature = "hw-interrupts")]
731737
Self::init_lapic_bulk(self.partition)
732738
.map_err(|e| RegisterError::ResetPartition(e.into()))?;
739+
740+
// With hw-interrupts, set_sregs filters out APIC_BASE to
741+
// avoid disabling the LAPIC (the snapshot sregs default it
742+
// to 0). On AMD/SVM this means SVM_CLEAN_FIELD_AVIC is
743+
// never dirtied after the VMCB rebuild, causing the CPU to
744+
// use stale cached AVIC state on VMRUN which corrupts guest
745+
// memory reads. Re-writing APIC_BASE to its post-reset
746+
// value forces the dirty bit via ValSetEmulatedApicBase.
747+
#[cfg(feature = "hw-interrupts")]
748+
{
749+
let apic_base = self.sregs()?.apic_base;
750+
self.set_registers(&[(
751+
WHvX64RegisterApicBase,
752+
Align16(WHV_REGISTER_VALUE { Reg64: apic_base }),
753+
)])
754+
.map_err(|e| RegisterError::ResetPartition(e.into()))?;
755+
}
733756
}
734757
Ok(())
735758
}

0 commit comments

Comments
 (0)