{"id":"CVE-2026-46295","summary":"KVM: x86: Do IRR scan in __kvm_apic_update_irr even if PIR is empty","details":"In the Linux kernel, the following vulnerability has been resolved:\n\nKVM: x86: Do IRR scan in __kvm_apic_update_irr even if PIR is empty\n\nFall back to apic_find_highest_vector() when PID.ON is set but PIR\nturns out to be empty, to correctly report the highest pending interrupt\nfrom the existing IRR.\n\nIn a nested VM stress test, the following WARNING fires in\nvmx_check_nested_events() when kvm_cpu_has_interrupt() reports a pending\ninterrupt but the subsequent kvm_apic_has_interrupt() (which invokes\nvmx_sync_pir_to_irr() again) returns -1:\n\n  WARNING: CPU: 99 PID: 57767 at arch/x86/kvm/vmx/nested.c:4449 vmx_check_nested_events+0x6bf/0x6e0 [kvm_intel]\n  Call Trace:\n   kvm_check_and_inject_events\n   vcpu_enter_guest.constprop.0\n   vcpu_run\n   kvm_arch_vcpu_ioctl_run\n   kvm_vcpu_ioctl\n   __x64_sys_ioctl\n   do_syscall_64\n   entry_SYSCALL_64_after_hwframe\n\nThe root cause is a race between vmx_sync_pir_to_irr() on the target vCPU\nand __vmx_deliver_posted_interrupt() on a sender vCPU.  The sender\nperforms two individually-atomic operations that are not a single\ntransaction:\n\n  1. pi_test_and_set_pir(vector)  -- sets the PIR bit\n  2. pi_test_and_set_on()         -- sets PID.ON\n\nThe following interleaving triggers the bug:\n\n  Sender vCPU (IPI):              Target vCPU (1st sync_pir_to_irr):\n  B1: set PIR[vector]\n                                  A1: pi_clear_on()\n                                  A2: pi_harvest_pir() -\u003e sees B1 bit\n                                  A3: xchg() -\u003e consumes bit, PIR=0\n                                      (1st sync returns correct max_irr)\n  B2: set PID.ON = 1\n\n                                  Target vCPU (2nd sync_pir_to_irr):\n                                  C1: pi_test_on() -\u003e TRUE (from B2)\n                                  C2: pi_clear_on() -\u003e ON=0\n                                  C3: pi_harvest_pir() -\u003e PIR empty\n                                  C4: *max_irr = -1, early return\n                                      IRR NOT SCANNED\n\nThe interrupt is not lost (it resides in the IRR from the first sync and\nis recovered on the next vcpu_enter_guest() iteration), but the incorrect\nmax_irr causes a spurious WARNING and a wasted L2 VM-Enter/VM-Exit cycle.","modified":"2026-07-10T03:53:46.690114645Z","published":"2026-06-08T15:46:22.494Z","related":["openSUSE-SU-2026:11014-1"],"database_specific":{"osv_generated_from":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46295.json","cna_assigner":"Linux"},"references":[{"type":"WEB","url":"https://git.kernel.org/stable/c/33fd0ccd2590b470b65adcca288615ad3b5e3e06"},{"type":"WEB","url":"https://git.kernel.org/stable/c/4b6b06a8b12bfd95f9015074b1430c1480908073"},{"type":"WEB","url":"https://git.kernel.org/stable/c/bb1703949dcaa9a49c338dee075f659f4634214d"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46295.json"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46295"},{"type":"PACKAGE","url":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"}],"affected":[{"ranges":[{"type":"GIT","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","events":[{"introduced":"b41f8638b9d30fbe045b4ef83ff4136c56a57397"},{"fixed":"bb1703949dcaa9a49c338dee075f659f4634214d"},{"fixed":"4b6b06a8b12bfd95f9015074b1430c1480908073"},{"fixed":"33fd0ccd2590b470b65adcca288615ad3b5e3e06"}]}],"database_specific":{"source":"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-46295.json"}},{"package":{"name":"Kernel","ecosystem":"Linux"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"6.16.0"},{"fixed":"6.18.30"}]},{"type":"ECOSYSTEM","events":[{"introduced":"6.19.0"},{"fixed":"7.0.7"}]}],"database_specific":{"source":"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-46295.json"}}],"schema_version":"1.7.5"}