Re: [REGRESSION] KVM: x86: OVMF boot hang with SMM enabled after commit b3e6212dea2e ("KVM: x86: Use active memslots for the per-vCPU MMIO cache")

From: Sami Farin

Date: Thu Oct 29 2026 - 06:44:00 EST


On Wed, Oct 28, 2026 at 19:42:38 +0100, Paolo Bonzini wrote:
...
1) if this patch gives the WARN (with vanilla 6.18.58):

diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index cfe96962a4e4..a96d839a317b 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -263,6 +263,7 @@ static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
vcpu->arch.mmio_access = access;
vcpu->arch.mmio_gfn = gfn;
vcpu->arch.mmio_gen = gen;
+ WARN_ON_ONCE((gen & 1) != kvm_arch_vcpu_memslots_id(vcpu));
}

This did not trigger, but would it have been better to do
WARN_ON_ONCE((gen % kvm_arch_nr_memslot_as_ids(vcpu->kvm)) != kvm_arch_vcpu_memslots_id(vcpu));

Anyways, I tried this with 6.18.58, but I cannot reproduce the infinite loop anymore!
I have Intel Core i5-13600K, qemu-11.1.2.

Please disregard and drop this patch.

After deeper tracing to understand why deterministic reproduction was elusive,
I looked into how memslot generations are initialized and incremented in
virt/kvm/kvm_main.c:1667-1673:

/*
* Generations must be unique even across address spaces. We do not need
* a global counter for that, instead the generation space is evenly split
* across address spaces. For example, with two address spaces, address
* space 0 will use generations 0, 2, 4, ... while address space 1 will
* use generations 1, 3, 5, ...
*/
gen += kvm_arch_nr_memslot_as_ids(kvm);

Because KVM seeds AS 0 with 0 and AS 1 with 1, and steps each update by 2,
AS 0 generations are strictly even while AS 1 generations are strictly odd.
The generation sets are disjoint (AS0 ∩ AS1 = ∅).

Commit b3e6212dea2e ("KVM: x86: Use active memslots for the per-vCPU MMIO
cache") already fixed this completely by switching from kvm_memslots() to
kvm_vcpu_memslots(). Because the active memslots' generation already embeds
address-space parity in bit 0, an MMIO entry cached in SMM (odd generation)
can never produce a false cache hit in normal mode (even generation). Tracking
mmio_as_id separately is redundant.

The Windows 11 / OVMF boot freeze that originally motivated this was traced
separately to high-vCPU SMI rendezvous lock contention during an NVRAM write
storm on dirty boot, completely unrelated to the MMIO cache.

Sorry for the noise.

Thanks,
Sami

static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)

2) if patch 1 or patch 2 separately are enough to fix the issue;

If you have time, can you also check if it fails to boot even before reaching Windows (you can try any Linux ISO, or even with no disk at all)? Also, just to cover all bases is your machine Intel or AMD?

Thanks,

Paolo


--
Do what you love because life is too short for anything else.