VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45987

CVE-2026-45987

Description

In the Linux kernel, the following vulnerability has been resolved:

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

After VMRUN in guest mode, nested_sync_control_from_vmcb02() syncs fields written by the CPU from vmcb02 to the cached vmcb12. This is because the cached vmcb12 is used as the authoritative copy of some of the controls, and is the payload when saving/restoring nested state.

int_state is also written by the CPU, specifically bit 0 (i.e. SVM_INTERRUPT_SHADOW_MASK) for nested VMs, but it is not sync'd to cached vmcb12. This does not cause a problem if KVM_SET_NESTED_STATE preceeds KVM_SET_VCPU_EVENTS in the restore path, as an interrupt shadow would be correctly restored to vmcb02 (KVM_SET_VCPU_EVENTS overwrites what KVM_SET_NESTED_STATE restored in int_state).

However, if KVM_SET_VCPU_EVENTS preceeds KVM_SET_NESTED_STATE, an interrupt shadow would be restored into vmcb01 instead of vmcb02. This would mostly be benign for L1 (delays an interrupt), but not for L2. For L2, the vCPU could hang (e.g. if a wakeup interrupt is delivered before a HLT that should have been in an interrupt shadow).

Sync int_state to the cached vmcb12 in nested_sync_control_from_vmcb02() to avoid this problem. With that, KVM_SET_NESTED_STATE restores the correct interrupt shadow state, and if KVM_SET_VCPU_EVENTS follows it would overwrite it with the same value.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

KVM nSVM interrupt shadow sync missing after VMRUN of L2 leads to potential vCPU hang during nested state restore.

Vulnerability

In the Linux kernel's KVM implementation for nested AMD SVM (nSVM), after VMRUN of an L2 guest, the function nested_sync_control_from_vmcb02() fails to synchronize the interrupt shadow (int_state, specifically bit 0 for SVM_INTERRUPT_SHADOW_MASK) from vmcb02 to the cached vmcb12. This affects all kernel versions with KVM nSVM support prior to the stable commit [1].

Exploitation

An attacker requires the ability to manipulate the order of KVM ioctls during nested state restore, specifically performing KVM_SET_VCPU_EVENTS before KVM_SET_NESTED_STATE. This can be achieved by a malicious L1 hypervisor or a privileged user space process with access to the KVM device. The missing sync causes the interrupt shadow to be stored in the wrong VMCB, potentially leading to a vCPU hang when the guest's interrupt handling is relied upon, e.g., if a wakeup interrupt is delivered before a HLT instruction that should have been protected by the interrupt shadow.

Impact

A successful exploitation can cause the L2 guest vCPU to hang, leading to a denial of service for the nested guest. In scenarios where the L2 guest is critical, this may result in service disruption. No privilege escalation or information disclosure is indicated.

Mitigation

The fix is included in the Linux kernel stable commit 497f6af9679fc9c6ce2f438e11ed5d51b1aa8297 [1]. Users should update to a kernel version containing this commit. No workaround is available other than avoiding the specific ioctl ordering during nested state restore, but that may not be practical.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

10
03bee264f8eb

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYosry AhmedFeb 25, 2026Fixed in 7.1-rc1via kernel-cna
1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index 3667f8ba526821..2308e40691c46c 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -521,6 +521,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
1709418535a8

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYosry AhmedFeb 25, 2026Fixed in 6.6.140via kernel-cna
1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index 0e989ebd9a82f2..4ecbf43d62f5e8 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -412,6 +412,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
2f950eeb27af

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYosry AhmedFeb 25, 2026Fixed in 6.12.86via kernel-cna
1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index a18c406bd4f174..54e0430b728121 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -420,6 +420,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
497f6af9679f

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYosry AhmedFeb 25, 2026Fixed in 6.18.27via kernel-cna
1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index d10447ced91159..66effdba2d6076 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -487,6 +487,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
e0377e52f3c1

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYosry AhmedFeb 25, 2026Fixed in 7.0.4via kernel-cna
1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index d2d67336436088..2a35a145b44cd2 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -530,6 +530,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
03bee264f8eb

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index 3667f8ba526821..2308e40691c46c 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -521,6 +521,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
1709418535a8

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index 0e989ebd9a82f2..4ecbf43d62f5e8 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -412,6 +412,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
2f950eeb27af

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index a18c406bd4f174..54e0430b728121 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -420,6 +420,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
497f6af9679f

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index d10447ced91159..66effdba2d6076 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -487,6 +487,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    
e0377e52f3c1

KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2

1 file changed · +1 1
  • arch/x86/kvm/svm/nested.c+1 1 modified
    diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
    index d2d67336436088..2a35a145b44cd2 100644
    --- a/arch/x86/kvm/svm/nested.c
    +++ b/arch/x86/kvm/svm/nested.c
    @@ -530,6 +530,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)
     	u32 mask;
     	svm->nested.ctl.event_inj      = svm->vmcb->control.event_inj;
     	svm->nested.ctl.event_inj_err  = svm->vmcb->control.event_inj_err;
    +	svm->nested.ctl.int_state	= svm->vmcb->control.int_state;
     
     	/* Only a few fields of int_ctl are written by the processor.  */
     	mask = V_IRQ_MASK | V_TPR_MASK;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing synchronization of int_state (interrupt shadow) from vmcb02 to the cached vmcb12 in nested_sync_control_from_vmcb02() after VMRUN of L2."

Attack vector

An attacker controlling a nested L2 guest (or orchestrating a save/restore sequence) can trigger a state-ordering dependency between KVM_SET_VCPU_EVENTS and KVM_SET_NESTED_STATE. If KVM_SET_VCPU_EVENTS is issued before KVM_SET_NESTED_STATE during migration or snapshot restore, the interrupt shadow (bit 0 of int_state, i.e. SVM_INTERRUPT_SHADOW_MASK) is written into vmcb01 instead of vmcb02 because the cached vmcb12 lacks the CPU-written int_state value. For L2, this can cause the vCPU to hang — for example, if a wakeup interrupt arrives before a HLT instruction that should have been inside an interrupt shadow [patch_id=2660675].

Affected code

The function nested_sync_control_from_vmcb02() in arch/x86/kvm/svm/nested.c is at fault. It previously synced event_inj and event_inj_err from vmcb02 to the cached vmcb12, but omitted int_state (bit 0, SVM_INTERRUPT_SHADOW_MASK) which is also written by the CPU for nested VMs [patch_id=2660675].

What the fix does

The patch adds a single line in nested_sync_control_from_vmcb02() to copy svm->vmcb->control.int_state into svm->nested.ctl.int_state, alongside the existing sync of event_inj and event_inj_err [patch_id=2660675]. This ensures that after VMRUN of L2, the CPU-written interrupt shadow is preserved in the cached vmcb12. Consequently, KVM_SET_NESTED_STATE will restore the correct interrupt shadow to vmcb02 regardless of the order of KVM_SET_VCPU_EVENTS and KVM_SET_NESTED_STATE in the restore path.

Preconditions

  • configThe host must be running a KVM-based Linux kernel with nested SVM (nSVM) enabled.
  • configAn L2 guest must be active (nested virtualization in use).
  • inputThe attacker must be able to trigger a save/restore of nested state where KVM_SET_VCPU_EVENTS is called before KVM_SET_NESTED_STATE.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.