Message ID | 20240408231115.1387279-1-seanjc@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: x86/mmu: Precisely invalidate MMU root_role during CPUID update | expand |
On Mon, 08 Apr 2024 16:11:15 -0700, Sean Christopherson wrote: > Set kvm_mmu_page_role.invalid to mark the various MMU root_roles invalid > during CPUID update in order to force a refresh, instead of zeroing out > the entire role. This fixes a bug where kvm_mmu_free_roots() incorrectly > thinks a root is indirect, i.e. not a TDP MMU, due to "direct" being > zeroed, which in turn causes KVM to take mmu_lock for write instead of > read. > > [...] Applied super quickly to kvm-x86 fixes, so that it gets time in -next before I pass it on to Paolo. This is the last commit in "fixes", so it's easy to drop and/or modify if there's an issue. [1/1] KVM: x86/mmu: Precisely invalidate MMU root_role during CPUID update https://github.com/kvm-x86/linux/commit/4fa96da3e6fe -- https://github.com/kvm-x86/linux/tree/next
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 992e651540e8..1eadefdb4bf2 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5576,9 +5576,9 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) * that problem is swept under the rug; KVM's CPUID API is horrific and * it's all but impossible to solve it without introducing a new API. */ - vcpu->arch.root_mmu.root_role.word = 0; - vcpu->arch.guest_mmu.root_role.word = 0; - vcpu->arch.nested_mmu.root_role.word = 0; + vcpu->arch.root_mmu.root_role.invalid = 1; + vcpu->arch.guest_mmu.root_role.invalid = 1; + vcpu->arch.nested_mmu.root_role.invalid = 1; vcpu->arch.root_mmu.cpu_role.ext.valid = 0; vcpu->arch.guest_mmu.cpu_role.ext.valid = 0; vcpu->arch.nested_mmu.cpu_role.ext.valid = 0;
Set kvm_mmu_page_role.invalid to mark the various MMU root_roles invalid during CPUID update in order to force a refresh, instead of zeroing out the entire role. This fixes a bug where kvm_mmu_free_roots() incorrectly thinks a root is indirect, i.e. not a TDP MMU, due to "direct" being zeroed, which in turn causes KVM to take mmu_lock for write instead of read. Note, paving over the entire role was largely unintentional, commit 7a458f0e1ba1 ("KVM: x86/mmu: remove extended bits from mmu_role, rename field") simply missed that "invalid" could be set. Fixes: 576a15de8d29 ("KVM: x86/mmu: Free TDP MMU roots while holding mmy_lock for read") Reported-by: syzbot+dc308fcfcd53f987de73@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/0000000000009b38080614c49bdb@google.com Cc: Phi Nguyen <phind.uet@gmail.com> Signed-off-by: Sean Christopherson <seanjc@google.com> --- arch/x86/kvm/mmu/mmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) base-commit: 8cb4a9a82b21623dbb4b3051dd30d98356cf95bc