From: Greg Kroah-Hartman Date: Sat, 25 Jul 2026 06:54:42 +0000 (+0200) Subject: 6.12-stable patches X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=116a0fea4254fe5ad025845870ffaa2be7dac086;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch --- diff --git a/queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch b/queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch new file mode 100644 index 0000000000..e3310bc5fb --- /dev/null +++ b/queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch @@ -0,0 +1,54 @@ +From 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Fri, 17 Jul 2026 12:30:11 +0200 +Subject: KVM: nVMX: Hide shadow VMCS right after VMCLEAR + +From: Hyunwoo Kim + +commit 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 upstream. + +free_nested() frees the shadow VMCS while vmcs01 still points to it. But +because it is asynchronous with respect to loaded_vmcs_clear(), the vCPU +might migrate before the pointer is cleared and __loaded_vmcs_clear() +may then execute VMCLEAR. + +The VMCS needs to stay attached until its explicit VMCLEAR completes, but +then it can be hidden and the page safely freed. + +Fixes: 355f4fb1405e ("kvm: nVMX: VMCLEAR an active shadow VMCS after last use") +Cc: stable@vger.kernel.org +Signed-off-by: Hyunwoo Kim +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/vmx/nested.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -325,6 +325,7 @@ static void vmx_switch_vmcs(struct kvm_v + static void free_nested(struct kvm_vcpu *vcpu) + { + struct vcpu_vmx *vmx = to_vmx(vcpu); ++ struct vmcs *shadow_vmcs; + + if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01)) + vmx_switch_vmcs(vcpu, &vmx->vmcs01); +@@ -342,9 +343,15 @@ static void free_nested(struct kvm_vcpu + vmx->nested.current_vmptr = INVALID_GPA; + if (enable_shadow_vmcs) { + vmx_disable_shadow_vmcs(vmx); +- vmcs_clear(vmx->vmcs01.shadow_vmcs); +- free_vmcs(vmx->vmcs01.shadow_vmcs); ++ ++ /* ++ * Keep the pointer visible until after VMCLEAR, so migration ++ * can clear an active shadow VMCS on the old CPU. ++ */ ++ shadow_vmcs = vmx->vmcs01.shadow_vmcs; ++ vmcs_clear(shadow_vmcs); + vmx->vmcs01.shadow_vmcs = NULL; ++ free_vmcs(shadow_vmcs); + } + kfree(vmx->nested.cached_vmcs12); + vmx->nested.cached_vmcs12 = NULL; diff --git a/queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch b/queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch new file mode 100644 index 0000000000..26d137392f --- /dev/null +++ b/queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch @@ -0,0 +1,86 @@ +From 2abd5287f08319fa35764566b15c6e22cb1068db Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Mon, 13 Jul 2026 08:15:33 -0700 +Subject: KVM: x86: Check for invalid/obsolete root *after* making MMU pages available + +From: Sean Christopherson + +commit 2abd5287f08319fa35764566b15c6e22cb1068db upstream. + +Check for a "stale" page fault, i.e. for an invalid and/or obsolete root, +after making MMU pages available for the shadow MMU. If reclaiming shadow +pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to +map memory into an invalid root. On its own, populating an invalid root is +"fine", but because child shadow pages inherit their parent's role, any +children created during the map/fetch will be created as invalid pages, +thus violating KVM's invariant that invalid pages are never on the list of +active MMU pages. + +Note, the underlying flaw has existed since KVM first started tracking +invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root +pagetables"), but the true badness only came along in 2020 (Linux 5.9) +with the invariant that invalid shadow pages can't be on the list of +active pages. + +Note #2, inheriting role.invalid when creating child shadow pages is also +far from ideal; that flaw will be addressed separately. + +Reported-by: Hyunwoo Kim +Fixes: f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/mmu.c | 9 +++++---- + arch/x86/kvm/mmu/paging_tmpl.h | 10 ++++++---- + 2 files changed, 11 insertions(+), 8 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4601,16 +4601,17 @@ static int direct_page_fault(struct kvm_ + + orig_pfn = fault->pfn; + +- r = RET_PF_RETRY; + write_lock(&vcpu->kvm->mmu_lock); + +- if (is_page_fault_stale(vcpu, fault)) +- goto out_unlock; +- + r = make_mmu_pages_available(vcpu); + if (r) + goto out_unlock; + ++ if (is_page_fault_stale(vcpu, fault)) { ++ r = RET_PF_RETRY; ++ goto out_unlock; ++ } ++ + r = direct_map(vcpu, fault); + + out_unlock: +--- a/arch/x86/kvm/mmu/paging_tmpl.h ++++ b/arch/x86/kvm/mmu/paging_tmpl.h +@@ -839,15 +839,17 @@ static int FNAME(page_fault)(struct kvm_ + + orig_pfn = fault->pfn; + +- r = RET_PF_RETRY; + write_lock(&vcpu->kvm->mmu_lock); + +- if (is_page_fault_stale(vcpu, fault)) +- goto out_unlock; +- + r = make_mmu_pages_available(vcpu); + if (r) + goto out_unlock; ++ ++ if (is_page_fault_stale(vcpu, fault)) { ++ r = RET_PF_RETRY; ++ goto out_unlock; ++ } ++ + r = FNAME(fetch)(vcpu, fault, &walker); + + out_unlock: diff --git a/queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch b/queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch new file mode 100644 index 0000000000..35f2ad571d --- /dev/null +++ b/queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch @@ -0,0 +1,76 @@ +From 52f2f7c30126037975389aa04d24c506a5177c35 Mon Sep 17 00:00:00 2001 +From: Phil Rosenthal +Date: Sat, 18 Jul 2026 12:50:23 -0400 +Subject: KVM: x86/mmu: Fix use-after-free on vendor module reload + +From: Phil Rosenthal + +commit 52f2f7c30126037975389aa04d24c506a5177c35 upstream. + +mmu_destroy_caches() destroys pte_list_desc_cache and +mmu_page_header_cache, but leaves both pointers unchanged. The pointers +live in kvm.ko, and therefore survive when a vendor module is unloaded +while kvm.ko remains loaded. + +If creation of pte_list_desc_cache fails during a subsequent vendor +module load, its assignment sets pte_list_desc_cache to NULL and the +error path calls mmu_destroy_caches(). mmu_page_header_cache still +points to the cache destroyed during the preceding vendor module +unload. Passing that stale pointer to kmem_cache_destroy() causes a +slab use-after-free. + +Reproduce the issue on a v7.1.3 kernel with CONFIG_KASAN=y, +CONFIG_KASAN_GENERIC=y, CONFIG_KVM=m, and CONFIG_KVM_INTEL=m. A +one-shot test hook forces pte_list_desc_cache to NULL on the second +invocation of kvm_mmu_vendor_module_init(): + + 1. Load kvm.ko and kvm-intel.ko, creating both caches. + 2. Unload only kvm_intel, leaving kvm.ko loaded. + 3. Reload kvm_intel and force initialization through the -ENOMEM path. + +KASAN reports: + + BUG: KASAN: slab-use-after-free in + kvm_mmu_vendor_module_init+0x5b/0x170 [kvm] + ... + kmem_cache_destroy+0x21/0x1d0 + kvm_mmu_vendor_module_init+0x5b/0x170 [kvm] + ... + Allocated by task 16817: + __kmem_cache_create_args+0x12c/0x3b0 + __kmem_cache_create.constprop.0+0xb6/0xf0 [kvm] + kvm_mmu_vendor_module_init+0x13b/0x170 [kvm] + ... + Freed by task 16820: + kmem_cache_destroy+0x117/0x1d0 + kvm_mmu_vendor_module_exit+0x21/0x30 [kvm] + +Clear both pointers immediately after destroying their caches so that +the stored state reflects the caches' lifetime and repeated cleanup is +safe. + +With the fix applied, the same injected vendor module reload fails with +-ENOMEM as expected and produces no KASAN report. + +Fixes: cb498ea2ce1d ("KVM: Portability: Combine kvm_init and kvm_init_x86") +Cc: stable@vger.kernel.org +Signed-off-by: Phil Rosenthal +Message-ID: <20260718-kvm-mmu-cache-uaf-v3-1-e103b93c74e1@phil.gs> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/mmu.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -7230,7 +7230,9 @@ static struct shrinker *mmu_shrinker; + static void mmu_destroy_caches(void) + { + kmem_cache_destroy(pte_list_desc_cache); ++ pte_list_desc_cache = NULL; + kmem_cache_destroy(mmu_page_header_cache); ++ mmu_page_header_cache = NULL; + } + + static void kvm_wake_nx_recovery_thread(struct kvm *kvm) diff --git a/queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch b/queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch new file mode 100644 index 0000000000..24336ad576 --- /dev/null +++ b/queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch @@ -0,0 +1,64 @@ +From e800decd9c0ac4349bcd8f8f9b29fd21fe93165e Mon Sep 17 00:00:00 2001 +From: Venkatesh Srinivas +Date: Wed, 15 Jul 2026 23:42:35 +0000 +Subject: KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN + +From: Venkatesh Srinivas + +commit e800decd9c0ac4349bcd8f8f9b29fd21fe93165e upstream. + +On Intel platforms with a VMX preemption timer and APICv, if a VMM +calls KVM_GET_LAPIC before KVM_GET_MSRS to save the vCPU state, it is +possible to lose a pending timer interrupt. + +If the thread running these ioctls is migrated to another core after +calling KVM_GET_LAPIC but before KVM_GET_MSRS and the guest is using +their LAPIC timer in TSC-deadline mode, not only does the save LAPIC +state not carry the pending interrupt, the TSCDEADLINE MSR will be +zeroed. + +After migration across CPUs, KVM_GET_MSRS calls vcpu_load, posting the +interrupt and clearing the MSR: +vcpu_load() -> + kvm_arch_vcpu_load() -> + kvm_lapic_restart_hv_timer() -> + start_hv_timer() -> + apic_timer_expired() -> + kvm_apic_inject_pending_timer_irqs() + . post interrupt into the LAPIC state + . clear IA32_TSCDEADLINE + +The saved LAPIC state will be missing the pending interrupt and the saved +MSR will be zero. Oops. + +Fix by only posting an interrupt when we're attempting to enter the guest +(vcpu->wants_to_run == true), not for vcpu_load from other paths. + +Assisted-by: gemini:gemini-3.1-pro-preview +Debugged-by: David Matlack +Debugged-by: Sean Christopherson +Debugged-by: Jim Mattson +Debugged-by: James Houghton +Signed-off-by: Venkatesh Srinivas +Message-ID: <20260715234234.15382-2-venkateshs@chromium.org> +Reviewed-by: James Houghton +Reviewed-by: Chao Gao +Cc: stable@vger.kernel.org +Fixes: ae95f566b3d2 ("KVM: X86: TSCDEADLINE MSR emulation fastpath", 2020-05-15) +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/lapic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1923,7 +1923,7 @@ static void apic_timer_expired(struct kv + if (apic_lvtt_tscdeadline(apic) || ktimer->hv_timer_in_use) + ktimer->expired_tscdeadline = ktimer->tscdeadline; + +- if (!from_timer_fn && apic->apicv_active) { ++ if (!from_timer_fn && apic->apicv_active && vcpu->wants_to_run) { + WARN_ON(kvm_get_running_vcpu() != vcpu); + kvm_apic_inject_pending_timer_irqs(apic); + return; diff --git a/queue-6.12/series b/queue-6.12/series index 0e7a6a4e6f..c22ed8bec4 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -11,3 +11,7 @@ fs-proc-task_mmu-fix-make_uffd_wp_huge_pte-prot-upda.patch seqlock-cure-some-more-scoped_seqlock-optimization-fails.patch seqlock-allow-kasan-to-fail-optimizing.patch seqlock-allow-ubsan_alignment-to-fail-optimizing.patch +kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch +kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch +kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch +kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch