From 01078473d6d6b1154aea6832b9a62e87c1610582 Mon Sep 17 00:00:00 2001 From: Amey Narkhede Date: Fri, 9 Jan 2026 14:06:40 +0000 Subject: [PATCH] vcpu: Handle Intel VMX limitation for intr_shadow import Intel VMX rejects setting VM_REG_GUEST_INTR_SHADOW to non-zero values while AMD SVM accepts any value. As per [1], the interrupt shadow is transient state, cleared after one instruction. Ignore EINVAL when attempting to set intr_shadow=true on Intel, as the state loss is benign. In the worst case an interrupt arrives one instruction early. This fixes #1013 [1]: Intel SDM Volume 3C, Section 26.6.1 and 27.7.1 around "Interruptibility State" https://cdrdv2-public.intel.com/825750/326019-sdm-vol-3c.pdf Signed-off-by: Amey Narkhede --- lib/propolis/src/vcpu.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/propolis/src/vcpu.rs b/lib/propolis/src/vcpu.rs index 03509333b..89381054d 100644 --- a/lib/propolis/src/vcpu.rs +++ b/lib/propolis/src/vcpu.rs @@ -971,10 +971,18 @@ pub mod migrate { fn write(self, vcpu: &Vcpu) -> Result<()> { vcpu.set_run_state(self.run_state, Some(self.sipi_vector))?; - vcpu.set_reg( + + // Intel VMX rejects setting intr_shadow to non-zero (AMD is fine). + // This state is transient anyway, cleared after one instruction. + if let Err(e) = vcpu.set_reg( vm_reg_name::VM_REG_GUEST_INTR_SHADOW, u64::from(self.intr_shadow), - )?; + ) { + if !(self.intr_shadow && e.raw_os_error() == Some(libc::EINVAL)) + { + return Err(e); + } + } let ents = [ vdi_field_entry_v1::new(