All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	 Peter Gonda <pgonda@google.com>,
	Michael Roth <michael.roth@amd.com>,
	 Vishal Annapurve <vannapurve@google.com>,
	Ackerly Tng <ackerleytng@google.com>
Subject: Re: [PATCH 15/22] KVM: x86/mmu: Move event re-injection unprotect+retry into common path
Date: Mon, 26 Aug 2024 14:52:22 -0700	[thread overview]
Message-ID: <Zsz5Furdqs2ys1Ps@google.com> (raw)
In-Reply-To: <41d307b3-78d9-4be1-80f0-9a9652e7ee37@redhat.com>

On Wed, Aug 14, 2024, Paolo Bonzini wrote:
> On 8/9/24 21:03, Sean Christopherson wrote:
> > @@ -6037,8 +6018,15 @@ static int kvm_mmu_write_protect_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
> >   	 * execute the instruction.  If no shadow pages were zapped, then the
> >   	 * write-fault is due to something else entirely, i.e. KVM needs to
> >   	 * emulate, as resuming the guest will put it into an infinite loop.
> > +	 *
> > +	 * For indirect MMUs, i.e. if KVM is shadowing the current MMU, try to
> > +	 * unprotect the gfn and retry if an event is awaiting reinjection.  If
> > +	 * KVM emulates multiple instructions before completing even injection,
> > +	 * the event could be delayed beyond what is architecturally allowed,
> > +	 * e.g. KVM could inject an IRQ after the TPR has been raised.
> 
> This paragraph should go before the description of
> kvm_mmu_unprotect_gfn_and_retry:

Hmm, I disagree.  The comment ends up being disconnected from the code, especially
by the end of the series.  E.g. when reading kvm_mmu_write_protect_fault(), someone
would have to jump twice (to kvm_mmu_unprotect_gfn_and_retry and then
__kvm_mmu_unprotect_gfn_and_retry()) in order to understand the checks buried
in kvm_mmu_write_protect_fault().

And the comment also becomes stale when kvm_mmu_unprotect_gfn_and_retry() is
used by x86_emulate_instruction().  That's obviously solvable by extending the
function comment, but then we end up with a rather massive function comment that
documents its callers, not the function itself.

> 
> 	 * There are two cases in which we try to unprotect the page here
> 	 * preemptively, i.e. zap any shadow pages, before emulating the
> 	 * instruction.
> 	 *
> 	 * First, the access may be due to L1 accessing nested NPT/EPT entries
> 	 * used for L2, i.e. if the gfn being written is for gPTEs that KVM is
> 	 * shadowing and has write-protected.  In this case, because AMD CPUs
> 	 * walk nested page table using a write operation, walking NPT entries
> 	 * in L1 can trigger write faults even when L1 isn't modifying PTEs.
> 	 * KVM would then emulate an excessive number of L1 instructions
> 	 * without triggering KVM's write-flooding detection, i.e. without
> 	 * unprotecting the gfn.  This is detected as a RO violation while
> 	 * translating the guest page when the current MMU is direct.
> 	 *
> 	 * Second, for indirect MMUs, i.e. if KVM is shadowing the current MMU,
> 	 * unprotect the gfn and reenter the guest if an event is awaiting
> 	 * reinjection.  If KVM emulates multiple instructions before completing
> 	 * event injection, the event could be delayed beyond what is
> 	 * architecturally allowed, e.g. KVM could inject an IRQ after the
> 	 * TPR has been raised.
> 	 *
> 	 * In both cases, if one or more shadow pages were zapped, skip
> 	 * emulation and resume L1 to let it natively execute the instruction.
> 	 * If no shadow pages were zapped, then the write-fault is due to
> 	 * something else entirely and KVM needs to emulate, as resuming
> 	 * the guest will put it into an infinite loop.
> 
> Thanks,
> 
> Paolo
> 
> >   	 */
> > -	if (direct && (is_write_to_guest_page_table(error_code)) &&
> > +	if (((direct && is_write_to_guest_page_table(error_code)) ||
> > +	     (!direct && kvm_event_needs_reinjection(vcpu))) &&
> >   	    kvm_mmu_unprotect_gfn_and_retry(vcpu, cr2_or_gpa))
> >   		return RET_PF_FIXED;
> 

  reply	other threads:[~2024-08-26 21:52 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-09 19:02 [PATCH 00/22] KVM: x86: Fix multiple #PF RO infinite loop bugs Sean Christopherson
2024-08-09 19:02 ` [PATCH 01/22] KVM: x86: Disallow read-only memslots for SEV-ES and SEV-SNP (and TDX) Sean Christopherson
2024-08-14 16:31   ` Paolo Bonzini
2025-12-03 13:04   ` Naveen N Rao
2025-12-23 16:06     ` Sean Christopherson
2024-08-09 19:02 ` [PATCH 02/22] KVM: VMX: Set PFERR_GUEST_{FINAL,PAGE}_MASK if and only if the GVA is valid Sean Christopherson
2024-08-14 11:11   ` Yuan Yao
2024-08-09 19:03 ` [PATCH 03/22] KVM: x86/mmu: Trigger unprotect logic only on write-protection page faults Sean Christopherson
2024-08-14 11:42   ` Yuan Yao
2024-08-14 14:21     ` Sean Christopherson
2024-08-15  8:30       ` Yuan Yao
2024-08-14 16:40   ` Paolo Bonzini
2024-08-14 19:34     ` Sean Christopherson
2024-08-09 19:03 ` [PATCH 04/22] KVM: x86/mmu: Skip emulation on page fault iff 1+ SPs were unprotected Sean Christopherson
2024-08-14 14:22   ` Yuan Yao
2024-08-15 23:31     ` Yao Yuan
2024-08-23  0:39       ` Sean Christopherson
2024-08-23 23:46         ` Sean Christopherson
2024-08-26 20:28           ` Sean Christopherson
2024-08-14 16:47   ` Paolo Bonzini
2024-08-09 19:03 ` [PATCH 05/22] KVM: x86: Retry to-be-emulated insn in "slow" unprotect path iff sp is zapped Sean Christopherson
2024-08-09 19:03 ` [PATCH 06/22] KVM: x86: Get RIP from vCPU state when storing it to last_retry_eip Sean Christopherson
2024-08-14 17:01   ` Paolo Bonzini
2024-08-09 19:03 ` [PATCH 07/22] KVM: x86: Store gpa as gpa_t, not unsigned long, when unprotecting for retry Sean Christopherson
2024-08-09 19:03 ` [PATCH 08/22] KVM: x86/mmu: Apply retry protection to "fast nTDP unprotect" path Sean Christopherson
2024-08-09 19:03 ` [PATCH 09/22] KVM: x86/mmu: Try "unprotect for retry" iff there are indirect SPs Sean Christopherson
2024-08-14 17:30   ` Paolo Bonzini
2024-08-15 14:09     ` Sean Christopherson
2024-08-15 16:48       ` Paolo Bonzini
2024-08-28 23:28         ` Sean Christopherson
2024-08-09 19:03 ` [PATCH 10/22] KVM: x86/mmu: Replace PFERR_NESTED_GUEST_PAGE with a more descriptive helper Sean Christopherson
2024-08-14 17:32   ` Paolo Bonzini
2024-08-15 14:10     ` Sean Christopherson
2024-08-09 19:03 ` [PATCH 11/22] KVM: x86: Move EMULTYPE_ALLOW_RETRY_PF to x86_emulate_instruction() Sean Christopherson
2024-08-09 19:03 ` [PATCH 12/22] KVM: x86: Fold retry_instruction() into x86_emulate_instruction() Sean Christopherson
2024-08-09 19:03 ` [PATCH 13/22] KVM: x86/mmu: Don't try to unprotect an INVALID_GPA Sean Christopherson
2024-08-09 19:03 ` [PATCH 14/22] KVM: x86/mmu: Always walk guest PTEs with WRITE access when unprotecting Sean Christopherson
2024-08-09 19:03 ` [PATCH 15/22] KVM: x86/mmu: Move event re-injection unprotect+retry into common path Sean Christopherson
2024-08-14 17:43   ` Paolo Bonzini
2024-08-26 21:52     ` Sean Christopherson [this message]
2024-08-09 19:03 ` [PATCH 16/22] KVM: x86: Remove manual pfn lookup when retrying #PF after failed emulation Sean Christopherson
2024-08-14 17:50   ` Paolo Bonzini
2024-08-09 19:03 ` [PATCH 17/22] KVM: x86: Check EMULTYPE_WRITE_PF_TO_SP before unprotecting gfn Sean Christopherson
2024-08-14 17:53   ` Paolo Bonzini
2024-08-09 19:03 ` [PATCH 18/22] KVM: x86: Apply retry protection to "unprotect on failure" path Sean Christopherson
2024-08-09 19:03 ` [PATCH 19/22] KVM: x86: Update retry protection fields when forcing retry on emulation failure Sean Christopherson
2024-08-09 19:03 ` [PATCH 20/22] KVM: x86: Rename reexecute_instruction()=>kvm_unprotect_and_retry_on_failure() Sean Christopherson
2024-08-09 19:03 ` [PATCH 21/22] KVM: x86/mmu: Subsume kvm_mmu_unprotect_page() into the and_retry() version Sean Christopherson
2024-08-09 19:03 ` [PATCH 22/22] KVM: x86/mmu: Detect if unprotect will do anything based on invalid_list Sean Christopherson
2024-08-14 17:57   ` Paolo Bonzini
2024-08-15 14:25     ` Sean Christopherson
2024-08-30 23:54       ` Sean Christopherson
2024-08-14 17:58 ` [PATCH 00/22] KVM: x86: Fix multiple #PF RO infinite loop bugs Paolo Bonzini

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=Zsz5Furdqs2ys1Ps@google.com \
    --to=seanjc@google.com \
    --cc=ackerleytng@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=pgonda@google.com \
    --cc=vannapurve@google.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.