diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c4a06214cde6..09c6df00ebb6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9731,18 +9731,23 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_x86_call(set_efer)(vcpu, 0); kvm_x86_call(update_exception_bitmap)(vcpu); - /* - * On the standard CR0/CR4/EFER modification paths, there are several - * complex conditions determining whether the MMU has to be reset and/or - * which PCIDs have to be flushed. However, CR0.WP and the paging-related - * bits in CR4 and EFER are irrelevant if CR0.PG was '0'; and a reset+flush - * is needed anyway if CR0.PG was '1' (which can only happen for INIT, as - * CR0 will be '0' prior to RESET). So we only need to check CR0.PG here. - */ - if (old_cr0 & X86_CR0_PG) { + if (old_cr0 & X86_CR0_PG) kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); - kvm_mmu_reset_context(vcpu); - } + + /* + * Unconditionally reset the MMU, even though super strictly speaking, + * a MMU reset is only necessary if and only one of the page role bits + * is changing. All of the CR0/CR4/EFER bits effectively get covered + * by checking CR0.PG=1, as CR0.WP and the paging-related bits in CR4 + * and EFER are irrelevant if CR0.PG was '0'. Subtly, if the vCPU was + * in guest mode (L2) or SMM (although emulating INIT in SMM _should_ + * be impossible), an MMU reset is also necessary as "guest mode" and + * "smm" are both encoded in the shadow page role. As a result, the + * only scenarios where an MMU reset is *not* needed is if the vCPU is + * in Real Mode or Unpaged Protected Mode, and micro-optimizing those + * paths are not worth the risk of running with a stale MMU context. + */ + kvm_mmu_reset_context(vcpu); /* * Intel's SDM states that all TLB entries are flushed on INIT. AMD's