Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [RFC PATCH 00/22] KVM: apply chainsaw to struct kvm_mmu
@ 2026-05-11 15:06 Paolo Bonzini
  2026-05-11 15:06 ` [PATCH 01/22] KVM: x86: remove nested_mmu from mmu_is_nested() Paolo Bonzini
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Paolo Bonzini @ 2026-05-11 15:06 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: jon, mtosatti

The kvm_mmu is a "god data structure" that includes three different
tasks: describing the guest page table's format, walking the guest
page tables and building the page tables.  This means that the
(already poorly named) nested_mmu is only used in part, since it
has no page tables to construct.

Furthermore, some parts are reused across guest and host page
tables (such as the reserved bits detector) but others are not;
for example permission_fault is replaced by simplified code such as
is_executable_pte().

This series cleans this up by splitting kvm_mmu in three parts:

- kvm_pagewalk is the page table walker.  There are two of them
  per vCPU, cpu_walk and tdp_walk.  walk_mmu is *always* replaced
  by cpu_walk no matter if running an L1 or L2 guest, unlike in the
  current code that moves it between root_mmu and nested_mmu.

- kvm_mmu retains the page table building functionality.  It uses
  a page table walker to build shadow pages; that is always cpu_walk
  for root_mmu or tdp_walk for guest_mmu.

- kvm_page_format allows KVM to operate on PTEs that already exist.
  Both kvm_pagewalk and kvm_mmu have their own kvm_page_format, though
  at least for now kvm_mmu only uses it for reserved bit checks.

This is in general an interesting cleanup, not least because it reduces
the confusion between guest_mmu and nested_mmu.  See for example the
comment "Exempt nested MMUs" which actually exempts guest_mmu.  While I'm
not going as far as renaming guest_mmu, there is indeed less confusion
due nested_mmu coming before the introduction of guest_mmu and stealing
the obvious name.  However, the last patch also shows the code reuse
benefits can be used for new features too.

By adapting the permission_fault() machinery and using it to test SPTEs
against struct kvm_page_fault, it makes it possible to support SPTEs
that have XS!=XU; these were not supported yet by KVM, but could now be
added via memory attributes.

I'm posting this as RFC to give an early preview of this, while trying
to sort out David's reported issue with MBEC.  It's tested very lightly;
in particular, right now npt=0 seems broken for Linux guests and I also
have not tried Intel or 32-bit hosts at all.

Paolo

ps: part of the work was done with help from AI, especially for the more
    mechanical patches.  However all the planning of each commit was
    done by me and I used the LLM essentially as a "natural language
    Coccinelle" (e.g., "move gva_to_gpa from struct kvm_mmu to struct
    kvm_pagewalk.  if the function that calls it has a variable of
    type kvm_pagewalk, use it instead of mmu->w").  Since there's
    really just one way to do the work given the prompts that I used,
    I still consider even the individual patches to be assisted by LLMs
    and not generated.  Alas, the patches were created prior to
    the introduction of Documentation/process/coding-assistants.rst;
    if required, I can go back and try to figure out which of the
    refactoring patches were done this way.


Paolo Bonzini (22):
  KVM: x86: remove nested_mmu from mmu_is_nested()
  KVM: x86: move pdptrs out of the MMU
  KVM: x86: check that kvm_handle_invpcid is only invoked with shadow
    paging
  KVM: x86/hyperv: remove unnecessary mmu_is_nested() check
  KVM: x86/mmu: introduce struct kvm_pagewalk
  KVM: x86/mmu: move get_guest_pgd to struct kvm_pagewalk
  KVM: x86/mmu: move gva_to_gpa to struct kvm_pagewalk
  KVM: x86/mmu: move get_pdptr to struct kvm_pagewalk
  KVM: x86/mmu: move inject_page_fault to struct kvm_pagewalk
  KVM: x86/mmu: move CPU-related fields to struct kvm_pagewalk
  KVM: x86/mmu: change CPU-role accessor fields to take struct
    kvm_pagewalk
  KVM: x86/mmu: move remaining permission fields to struct kvm_pagewalk
  KVM: x86/mmu: pass struct kvm_pagewalk to kvm_mmu_invalidate_addr
  KVM: x86/mmu: change walk_mmu to struct kvm_pagewalk
  KVM: x86/mmu: change nested_mmu.w to nested_cpu_walk
  KVM: x86/mmu: make cpu_walk a value
  KVM: x86/mmu: pull struct kvm_pagewalk out of struct kvm_mmu
  KVM: x86/mmu: cleanup functions that initialize shadow MMU
  KVM: x86/mmu: pull page format to a new struct
  KVM: x86/mmu: merge struct rsvd_bits_validate into struct
    kvm_page_format
  KVM: x86/mmu: parameterize update_permission_bitmask()
  KVM: x86/mmu: use kvm_page_format to test SPTEs

 arch/x86/include/asm/kvm_host.h |  75 +++---
 arch/x86/kvm/hyperv.c           |   7 +-
 arch/x86/kvm/kvm_cache_regs.h   |   4 +-
 arch/x86/kvm/mmu.h              |  31 +--
 arch/x86/kvm/mmu/mmu.c          | 411 +++++++++++++++-----------------
 arch/x86/kvm/mmu/paging_tmpl.h  |  88 +++----
 arch/x86/kvm/mmu/spte.c         |   4 +-
 arch/x86/kvm/mmu/spte.h         |  64 ++---
 arch/x86/kvm/mmu/tdp_mmu.c      |   3 +-
 arch/x86/kvm/svm/nested.c       |  22 +-
 arch/x86/kvm/svm/svm.c          |   2 +-
 arch/x86/kvm/vmx/nested.c       |  29 ++-
 arch/x86/kvm/vmx/vmx.c          |  22 +-
 arch/x86/kvm/x86.c              |  67 +++---
 arch/x86/kvm/x86.h              |   2 +-
 15 files changed, 411 insertions(+), 420 deletions(-)

-- 
2.52.0


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

end of thread, other threads:[~2026-05-11 15:07 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11 15:06 [RFC PATCH 00/22] KVM: apply chainsaw to struct kvm_mmu Paolo Bonzini
2026-05-11 15:06 ` [PATCH 01/22] KVM: x86: remove nested_mmu from mmu_is_nested() Paolo Bonzini
2026-05-11 15:06 ` [PATCH 02/22] KVM: x86: move pdptrs out of the MMU Paolo Bonzini
2026-05-11 15:06 ` [PATCH 03/22] KVM: x86: check that kvm_handle_invpcid is only invoked with shadow paging Paolo Bonzini
2026-05-11 15:06 ` [PATCH 04/22] KVM: x86/hyperv: remove unnecessary mmu_is_nested() check Paolo Bonzini
2026-05-11 15:06 ` [PATCH 05/22] KVM: x86/mmu: introduce struct kvm_pagewalk Paolo Bonzini
2026-05-11 15:06 ` [PATCH 06/22] KVM: x86/mmu: move get_guest_pgd to " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 07/22] KVM: x86/mmu: move gva_to_gpa " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 08/22] KVM: x86/mmu: move get_pdptr " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 09/22] KVM: x86/mmu: move inject_page_fault " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 10/22] KVM: x86/mmu: move CPU-related fields " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 11/22] KVM: x86/mmu: change CPU-role accessor fields to take " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 12/22] KVM: x86/mmu: move remaining permission fields to " Paolo Bonzini
2026-05-11 15:06 ` [PATCH 13/22] KVM: x86/mmu: pass struct kvm_pagewalk to kvm_mmu_invalidate_addr Paolo Bonzini
2026-05-11 15:06 ` [PATCH 14/22] KVM: x86/mmu: change walk_mmu to struct kvm_pagewalk Paolo Bonzini
2026-05-11 15:06 ` [PATCH 15/22] KVM: x86/mmu: change nested_mmu.w to nested_cpu_walk Paolo Bonzini
2026-05-11 15:06 ` [PATCH 16/22] KVM: x86/mmu: make cpu_walk a value Paolo Bonzini
2026-05-11 15:06 ` [PATCH 17/22] KVM: x86/mmu: pull struct kvm_pagewalk out of struct kvm_mmu Paolo Bonzini
2026-05-11 15:06 ` [PATCH 18/22] KVM: x86/mmu: cleanup functions that initialize shadow MMU Paolo Bonzini
2026-05-11 15:06 ` [PATCH 19/22] KVM: x86/mmu: pull page format to a new struct Paolo Bonzini
2026-05-11 15:06 ` [PATCH 20/22] KVM: x86/mmu: merge struct rsvd_bits_validate into struct kvm_page_format Paolo Bonzini
2026-05-11 15:06 ` [PATCH 21/22] KVM: x86/mmu: parameterize update_permission_bitmask() Paolo Bonzini
2026-05-11 15:06 ` [PATCH 22/22] KVM: x86/mmu: use kvm_page_format to test SPTEs Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox