Skip to content

Commit 81c1093

Browse files
sean-jcjfvogel
authored andcommitted
KVM: nSVM: Enter guest mode before initializing nested NPT MMU
commit 46d6c6f upstream. When preparing vmcb02 for nested VMRUN (or state restore), "enter" guest mode prior to initializing the MMU for nested NPT so that guest_mode is set in the MMU's role. KVM's model is that all L2 MMUs are tagged with guest_mode, as the behavior of hypervisor MMUs tends to be significantly different than kernel MMUs. Practically speaking, the bug is relatively benign, as KVM only directly queries role.guest_mode in kvm_mmu_free_guest_mode_roots() and kvm_mmu_page_ad_need_write_protect(), which SVM doesn't use, and in paths that are optimizations (mmu_page_zap_pte() and shadow_mmu_try_split_huge_pages()). And while the role is incorprated into shadow page usage, because nested NPT requires KVM to be using NPT for L1, reusing shadow pages across L1 and L2 is impossible as L1 MMUs will always have direct=1, while L2 MMUs will have direct=0. Hoist the TLB processing and setting of HF_GUEST_MASK to the beginning of the flow instead of forcing guest_mode in the MMU, as nothing in nested_vmcb02_prepare_control() between the old and new locations touches TLB flush requests or HF_GUEST_MASK, i.e. there's no reason to present inconsistent vCPU state to the MMU. Fixes: 69cb877 ("KVM: nSVM: move MMU setup to nested_prepare_vmcb_control") Cc: stable@vger.kernel.org Reported-by: Yosry Ahmed <yosry.ahmed@linux.dev> Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev> Link: https://lore.kernel.org/r/20250130010825.220346-1-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit 55057ec275f7ad8016f74f274e45468fb0ed78a9) Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
1 parent 858a1b8 commit 81c1093

File tree

2 files changed

+6
-6
lines changed

2 files changed

+6
-6
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5593,7 +5593,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
55935593
union kvm_mmu_page_role root_role;
55945594

55955595
/* NPT requires CR0.PG=1. */
5596-
WARN_ON_ONCE(cpu_role.base.direct);
5596+
WARN_ON_ONCE(cpu_role.base.direct || !cpu_role.base.guest_mode);
55975597

55985598
root_role = cpu_role.base;
55995599
root_role.level = kvm_mmu_get_tdp_level(vcpu);

arch/x86/kvm/svm/nested.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,11 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm,
646646
u32 pause_count12;
647647
u32 pause_thresh12;
648648

649+
nested_svm_transition_tlb_flush(vcpu);
650+
651+
/* Enter Guest-Mode */
652+
enter_guest_mode(vcpu);
653+
649654
/*
650655
* Filled at exit: exit_code, exit_code_hi, exit_info_1, exit_info_2,
651656
* exit_int_info, exit_int_info_err, next_rip, insn_len, insn_bytes.
@@ -762,11 +767,6 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm,
762767
}
763768
}
764769

765-
nested_svm_transition_tlb_flush(vcpu);
766-
767-
/* Enter Guest-Mode */
768-
enter_guest_mode(vcpu);
769-
770770
/*
771771
* Merge guest and host intercepts - must be called with vcpu in
772772
* guest-mode to take effect.

0 commit comments

Comments
 (0)