All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v2 17/18] KVM: x86: flush TLB separately from MMU reset
Date: Fri, 18 Feb 2022 23:57:19 +0000	[thread overview]
Message-ID: <YhAyX+Bc3x4+ZMTG@google.com> (raw)
In-Reply-To: <20220217210340.312449-18-pbonzini@redhat.com>

On Thu, Feb 17, 2022, Paolo Bonzini wrote:
> For both CR0 and CR4, disassociate the TLB flush logic from the
> MMU role logic.  Instead  of relying on kvm_mmu_reset_context() being
> a superset of various TLB flushes (which is not necessarily going to
> be the case in the future), always call it if the role changes
> but also set the various TLB flush requests according to what is
> in the manual.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

Code is good, a few nits on comments.

Reviewed-by: Sean Christopherson <seanjc@google.com>

> @@ -1057,28 +1064,41 @@ EXPORT_SYMBOL_GPL(kvm_is_valid_cr4);
>  
>  void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
>  {
> +	if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
> +		kvm_mmu_reset_context(vcpu);
> +
>  	/*
> -	 * If any role bit is changed, the MMU needs to be reset.
> -	 *
> -	 * If CR4.PCIDE is changed 1 -> 0, the guest TLB must be flushed.
>  	 * If CR4.PCIDE is changed 0 -> 1, there is no need to flush the TLB
>  	 * according to the SDM; however, stale prev_roots could be reused
>  	 * incorrectly in the future after a MOV to CR3 with NOFLUSH=1, so we
> -	 * free them all.  KVM_REQ_MMU_RELOAD is fit for the both cases; it
> -	 * is slow, but changing CR4.PCIDE is a rare case.
> -	 *
> -	 * If CR4.PGE is changed, the guest TLB must be flushed.
> -	 *
> -	 * Note: resetting MMU is a superset of KVM_REQ_MMU_RELOAD and
> -	 * KVM_REQ_MMU_RELOAD is a superset of KVM_REQ_TLB_FLUSH_GUEST, hence
> -	 * the usage of "else if".
> +	 * free them all.  This is *not* a superset of KVM_REQ_TLB_FLUSH_GUEST
> +	 * or KVM_REQ_TLB_FLUSH_CURRENT, because the hardware TLB is not flushed,
> +	 * so fall through.
>  	 */
> -	if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
> -		kvm_mmu_reset_context(vcpu);
> -	else if ((cr4 ^ old_cr4) & X86_CR4_PCIDE)
> +	if (!tdp_enabled &&
> +	    (cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE))
>  		kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
> -	else if ((cr4 ^ old_cr4) & X86_CR4_PGE)
> -		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
> +
> +	/*
> +	 * The TLB has to be flushed for all PCIDs on:
> +	 * - CR4.PCIDE changed from 1 to 0

Uber nit, grammatically this should use "a ... change", not "changed".  And I
think it's worth calling out that the flush is architecturally required.
Something like this, though I don't like using "conditions" to describe the
cases (can't think of a bette word, obviously).

	/*
	 * A TLB flush for all PCIDs is architecturally required if any of the
	 * following conditions is true:
	 * - CR4.PCIDE is changed from 1 to 0
	 * - CR4.PGE is toggled
	 */

> +	 * - any change to CR4.PGE
> +	 *
> +	 * This is a superset of KVM_REQ_TLB_FLUSH_CURRENT.
> +	 */
> +	if (((cr4 ^ old_cr4) & X86_CR4_PGE) ||
> +	    (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
> +		 kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
> +
> +	/*
> +	 * The TLB has to be flushed for the current PCID on:
> +	 * - CR4.SMEP changed from 0 to 1
> +	 * - any change to CR4.PAE
> +	 */

Same nit plus "architecturally required" feedback fo rthis one.

> +	else if (((cr4 ^ old_cr4) & X86_CR4_PAE) ||
> +		 ((cr4 & X86_CR4_SMEP) && !(old_cr4 & X86_CR4_SMEP)))
> +		 kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
> +
>  }
>  EXPORT_SYMBOL_GPL(kvm_post_set_cr4);
>  
> @@ -11323,15 +11343,17 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>  	static_call(kvm_x86_update_exception_bitmap)(vcpu);
>  
>  	/*
> -	 * Reset the MMU context if paging was enabled prior to INIT (which is
> +	 * A TLB flush is needed if paging was enabled prior to INIT (which is

I appreciate the cleverness in changing only a single like, but I think both
pieces warrant a mention.  How 'bout this, to squeak by with two lines?

	/*
	 * Reset the MMU and flush the TLB if paging was enabled (INIT only, as
	 * CR0 is currently guaranteed to be '0' prior to RESET).  Unlike the

>  	 * implied if CR0.PG=1 as CR0 will be '0' prior to RESET).  Unlike the
>  	 * standard CR0/CR4/EFER modification paths, only CR0.PG needs to be
>  	 * checked because it is unconditionally cleared on INIT and all other
>  	 * paging related bits are ignored if paging is disabled, i.e. CR0.WP,
>  	 * CR4, and EFER changes are all irrelevant if CR0.PG was '0'.
>  	 */
> -	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);
> +	}
>  
>  	/*
>  	 * Intel's SDM states that all TLB entries are flushed on INIT.  AMD's
> -- 
> 2.31.1

  reply	other threads:[~2022-02-18 23:57 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-17 21:03 [PATCH v2 00/18] KVM: MMU: do not unload MMU roots on all role changes Paolo Bonzini
2022-02-17 21:03 ` [PATCH v2 01/18] KVM: x86: host-initiated EFER.LME write affects the MMU Paolo Bonzini
2022-02-18 17:08   ` Sean Christopherson
2022-02-18 17:26     ` Paolo Bonzini
2022-02-23 13:40   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 02/18] KVM: x86: do not deliver asynchronous page faults if CR0.PG=0 Paolo Bonzini
2022-02-18 17:12   ` Sean Christopherson
2022-02-23 14:07   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 03/18] KVM: x86/mmu: WARN if PAE roots linger after kvm_mmu_unload Paolo Bonzini
2022-02-18 17:14   ` Sean Christopherson
2022-02-18 17:23     ` Paolo Bonzini
2022-02-23 14:11       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 04/18] KVM: x86/mmu: avoid NULL-pointer dereference on page freeing bugs Paolo Bonzini
2022-02-18 17:15   ` Sean Christopherson
2022-02-23 14:12   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 05/18] KVM: x86/mmu: use struct kvm_mmu_root_info for mmu->root Paolo Bonzini
2022-02-23 14:39   ` Maxim Levitsky
2022-02-23 15:42     ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 06/18] KVM: x86/mmu: do not consult levels when freeing roots Paolo Bonzini
2022-02-18 17:27   ` Sean Christopherson
2022-02-23 14:59   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 07/18] KVM: x86/mmu: Do not use guest root level in audit Paolo Bonzini
2022-02-18 18:37   ` Sean Christopherson
2022-02-18 18:46     ` Paolo Bonzini
2022-02-23 15:02       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 08/18] KVM: x86/mmu: do not pass vcpu to root freeing functions Paolo Bonzini
2022-02-18 18:39   ` Sean Christopherson
2022-02-23 15:16   ` Maxim Levitsky
2022-02-23 15:48     ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 09/18] KVM: x86/mmu: look for a cached PGD when going from 32-bit to 64-bit Paolo Bonzini
2022-02-18 18:08   ` Sean Christopherson
2022-02-23 16:01   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 10/18] KVM: x86/mmu: load new PGD after the shadow MMU is initialized Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:20   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 11/18] KVM: x86/mmu: Always use current mmu's role when loading new PGD Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:23   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 12/18] KVM: x86/mmu: clear MMIO cache when unloading the MMU Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:32   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 13/18] KVM: x86: reset and reinitialize the MMU in __set_sregs_common Paolo Bonzini
2022-02-19  0:22   ` Sean Christopherson
2022-02-23 16:48   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 14/18] KVM: x86/mmu: avoid indirect call for get_cr3 Paolo Bonzini
2022-02-18 20:30   ` Sean Christopherson
2022-02-19 10:03     ` Paolo Bonzini
2022-02-24 11:02   ` Maxim Levitsky
2022-02-24 15:12     ` Sean Christopherson
2022-02-24 15:14       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 15/18] KVM: x86/mmu: rename kvm_mmu_new_pgd, introduce variant that calls get_guest_pgd Paolo Bonzini
2022-02-18  9:39   ` Paolo Bonzini
2022-02-18 21:00     ` Sean Christopherson
2022-02-24 15:41       ` Maxim Levitsky
2022-02-25 17:40         ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 16/18] KVM: x86: introduce KVM_REQ_MMU_UPDATE_ROOT Paolo Bonzini
2022-02-18 21:45   ` Sean Christopherson
2022-02-19  7:54     ` Paolo Bonzini
2022-02-22 16:06       ` Sean Christopherson
2022-02-24 15:50       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 17/18] KVM: x86: flush TLB separately from MMU reset Paolo Bonzini
2022-02-18 23:57   ` Sean Christopherson [this message]
2022-02-21 15:01     ` Paolo Bonzini
2022-02-24 16:11   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 18/18] KVM: x86: do not unload MMU roots on all role changes Paolo Bonzini
2022-02-24 16:25   ` Maxim Levitsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YhAyX+Bc3x4+ZMTG@google.com \
    --to=seanjc@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.