Skip to content

snp guest vsm: register intercepts #1142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions openhcl/hcl/src/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,6 +2113,7 @@ impl<'a, T: Backing<'a>> ProcessorRunner<'a, T> {
| HvX64RegisterName::VsmVpWaitForTlbLock
| HvX64RegisterName::VsmVpSecureConfigVtl0
| HvX64RegisterName::VsmVpSecureConfigVtl1
| HvX64RegisterName::CrInterceptControl
)
));
self.set_vp_registers_hvcall_inner(vtl, &registers)
Expand Down
29 changes: 28 additions & 1 deletion openhcl/virt_mshv_vtl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,17 @@ struct GuestVsmVpState {
/// next exit to VTL 0.
#[inspect(with = "|x| x.as_ref().map(inspect::AsDebug)")]
vtl0_exit_pending_event: Option<hvdef::HvX64PendingExceptionEvent>,
reg_intercept: SecureRegisterInterceptState,
}

#[cfg(guest_arch = "x86_64")]
impl GuestVsmVpState {
fn new() -> Self {
GuestVsmVpState {
vtl0_exit_pending_event: None,
reg_intercept: Default::default(),
}
}
}

#[cfg(guest_arch = "x86_64")]
Expand Down Expand Up @@ -384,7 +395,10 @@ impl UhCvmVpState {
let apic_base = virt::vp::Apic::at_reset(&inner.caps, vp_info).apic_base;
let lapics = VtlArray::from_fn(|vtl| {
let apic_set = &cvm_partition.lapic[vtl];
let mut lapic = apic_set.add_apic(vp_info);

// The APIC is software-enabled after reset for secure VTLs, to
// maintain compatibility with released versions of secure kernel
let mut lapic = apic_set.add_apic(vp_info, vtl == Vtl::Vtl1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jstarks any concerns with this part of the change? Our other components also do this; without it, if I remember correctly, I couldn't get the intercept delivered to VTL 1.

// Initialize APIC base to match the reset VM state.
lapic.set_apic_base(apic_base).unwrap();
// Only the VTL 0 non-BSP LAPICs should be in the WaitForSipi state.
Expand All @@ -408,6 +422,19 @@ impl UhCvmVpState {
}
}

#[cfg(guest_arch = "x86_64")]
#[derive(Inspect, Default)]
/// Configuration of VTL 1 registration for intercepts on certain registers
pub struct SecureRegisterInterceptState {
#[inspect(with = "|x| inspect::AsHex(u64::from(*x))")]
intercept_control: hvdef::HvRegisterCrInterceptControl,
cr0_mask: u64,
cr4_mask: u64,
// Writes to X86X_IA32_MSR_MISC_ENABLE are dropped, so this is only used so
// that get_vp_register returns the correct value from a set_vp_register
ia32_misc_enable_mask: u64,
}

#[derive(Inspect)]
/// Partition-wide state for CVMs.
struct UhCvmPartitionState {
Expand Down
Loading