From 28e7565e6df0d217988604c64d573117e6e87135 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Wed, 17 Jan 2024 14:04:28 -0600 Subject: [PATCH] Mitigate behavior from illumos#16183 Until the kernel VMM bits are fixed to properly clear timer state when the LAPIC(s) are reset, we can fix it in userspace. Fixes #597 --- lib/propolis/src/vcpu.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/propolis/src/vcpu.rs b/lib/propolis/src/vcpu.rs index 07a38d578..fa42ca3c3 100644 --- a/lib/propolis/src/vcpu.rs +++ b/lib/propolis/src/vcpu.rs @@ -1254,15 +1254,35 @@ pub mod migrate { } impl VcpuReadWrite for LapicV1 { fn read(vcpu: &Vcpu) -> Result { - let vdi = vcpu + let mut vdi = vcpu .hdl .data_op(bhyve_api::VDC_LAPIC, 1) .for_vcpu(vcpu.id) .read::()?; + if vcpu.hdl.api_version()? <= ApiVersion::V16 { + // Fix up invalid LAPIC timer data from illumos#16183 + if vdi.vl_timer_target != 0 && vdi.vl_lapic.vlp_icr_timer == 0 { + vdi.vl_timer_target = 0; + } + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "post-illumos#16183 kernel emitting bad ICR timer data", + )); + } + Ok(vdi.into()) } fn write(self, vcpu: &Vcpu) -> Result<()> { + // Be wary of illumos#16183 payloads + if self.timer_target != 0 && self.page.icr_timer == 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "ICR-timer does not match timer target time", + )); + } + vcpu.hdl .data_op(bhyve_api::VDC_LAPIC, 1) .for_vcpu(vcpu.id)