kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/22] KVM: x86: Fix multiple #PF RO infinite loop bugs
@ 2024-08-09 19:02 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
                   ` (22 more replies)
  0 siblings, 23 replies; 53+ messages in thread
From: Sean Christopherson @ 2024-08-09 19:02 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini
  Cc: kvm, linux-kernel, Peter Gonda, Michael Roth, Vishal Annapurve,
	Ackerly Tng

The folks doing TDX enabling ran into a problem where exposing a read-only
memslot to a TDX guest put it into an infinite loop.  The most immediate
issue is that KVM never creates MMIO SPTEs for RO memslots, because except
for TDX (which isn't officially supported yet), such SPTEs can't distinguish
between reads and writes, i.e. would trigger MMIO on everything and thus
defeat the purpose of having a RX memslot.

That breaks TDX, SEV-ES, and SNP, i.e. VM types that rely on MMIO caching
to reflect MMIO faults into the guest as #VC/#VE, as the guest never sees
the fault, KVM refuses to emulate, the guest loops indefinitely.  That's
patch 1.

Patches 2-4 fix an amusing number of other bugs that made it difficult to
figure out the true root cause.

The rest is a bunch of cleanups to consolidate all of the unprotect+retry
paths (there are four-ish).

As a bonus, adding RET_PF_WRITE_PROTECTED obviates the need for
kvm_lookup_pfn()[*].

[*] https://lore.kernel.org/all/63c41e25-2523-4397-96b4-557394281443@redhat.com

Sean Christopherson (22):
  KVM: x86: Disallow read-only memslots for SEV-ES and SEV-SNP (and TDX)
  KVM: VMX: Set PFERR_GUEST_{FINAL,PAGE}_MASK if and only if the GVA is
    valid
  KVM: x86/mmu: Trigger unprotect logic only on write-protection page
    faults
  KVM: x86/mmu: Skip emulation on page fault iff 1+ SPs were unprotected
  KVM: x86: Retry to-be-emulated insn in "slow" unprotect path iff sp is
    zapped
  KVM: x86: Get RIP from vCPU state when storing it to last_retry_eip
  KVM: x86: Store gpa as gpa_t, not unsigned long, when unprotecting for
    retry
  KVM: x86/mmu: Apply retry protection to "fast nTDP unprotect" path
  KVM: x86/mmu: Try "unprotect for retry" iff there are indirect SPs
  KVM: x86/mmu: Replace PFERR_NESTED_GUEST_PAGE with a more descriptive
    helper
  KVM: x86: Move EMULTYPE_ALLOW_RETRY_PF to x86_emulate_instruction()
  KVM: x86: Fold retry_instruction() into x86_emulate_instruction()
  KVM: x86/mmu: Don't try to unprotect an INVALID_GPA
  KVM: x86/mmu: Always walk guest PTEs with WRITE access when
    unprotecting
  KVM: x86/mmu: Move event re-injection unprotect+retry into common path
  KVM: x86: Remove manual pfn lookup when retrying #PF after failed
    emulation
  KVM: x86: Check EMULTYPE_WRITE_PF_TO_SP before unprotecting gfn
  KVM: x86: Apply retry protection to "unprotect on failure" path
  KVM: x86: Update retry protection fields when forcing retry on
    emulation failure
  KVM: x86: Rename
    reexecute_instruction()=>kvm_unprotect_and_retry_on_failure()
  KVM: x86/mmu: Subsume kvm_mmu_unprotect_page() into the and_retry()
    version
  KVM: x86/mmu: Detect if unprotect will do anything based on
    invalid_list

 arch/x86/include/asm/kvm_host.h |  16 ++-
 arch/x86/kvm/mmu/mmu.c          | 175 ++++++++++++++++++++++----------
 arch/x86/kvm/mmu/mmu_internal.h |   3 +
 arch/x86/kvm/mmu/mmutrace.h     |   1 +
 arch/x86/kvm/mmu/paging_tmpl.h  |   2 +-
 arch/x86/kvm/mmu/tdp_mmu.c      |   6 +-
 arch/x86/kvm/vmx/vmx.c          |   5 +-
 arch/x86/kvm/x86.c              | 133 +++++++-----------------
 include/linux/kvm_host.h        |   7 ++
 virt/kvm/kvm_main.c             |   5 +-
 10 files changed, 184 insertions(+), 169 deletions(-)


base-commit: 332d2c1d713e232e163386c35a3ba0c1b90df83f
-- 
2.46.0.76.ge559c4bf1a-goog


^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2025-12-23 16:06 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).