From 83f8cdd2def7ee6d8e32bd95e542921521c10eb3 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Mon, 1 Apr 2024 15:33:31 +0800 Subject: [PATCH] vmm: Avoid kernel panic when unmasking guest IRQ on AMD Assigning KVM_IRQFD (when unmasking a guest IRQ) after KVM_SET_GSI_ROUTING can avoid kernel panic on the guest that is not patched with commit a80ced6ea514 (KVM: SVM: fix panic on out-of-bounds guest IRQ) on AMD systems. Meanwhile, it is required to deassign KVM_IRQFD (when masking a guest IRQ) before KVM_SET_GSI_ROUTING (see #3827). Fixes: #6353 Signed-off-by: Yi Wang Signed-off-by: Bo Chen --- vmm/src/interrupt.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index d6a68081b..09c50b6dd 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -177,18 +177,29 @@ impl InterruptSourceGroup for MsiInterruptGroup { route: self.vm.make_routing_entry(route.gsi, &config), masked, }; + + // When mask a msi irq, entry.masked is set to be true, + // and the gsi will not be passed to KVM through KVM_SET_GSI_ROUTING. + // So it's required to call disable() (which deassign KVM_IRQFD) before + // set_gsi_routes() to avoid kernel panic (see #3827) if masked { route.disable(&self.vm)?; - } else { - route.enable(&self.vm)?; } + let mut routes = self.gsi_msi_routes.lock().unwrap(); routes.insert(route.gsi, entry); if set_gsi { - return self.set_gsi_routes(&routes); - } else { - return Ok(()); + self.set_gsi_routes(&routes)?; } + + // Assign KVM_IRQFD after KVM_SET_GSI_ROUTING to avoid + // panic on kernel which not have commit a80ced6ea514 + // (KVM: SVM: fix panic on out-of-bounds guest IRQ). + if !masked { + route.enable(&self.vm)?; + } + + return Ok(()); } Err(io::Error::new(