public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Jim Mattson <jmattson@google.com>
To: "Sean Christopherson" <seanjc@google.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	"Alexander Graf" <agraf@suse.de>,
	"Joerg Roedel" <joro@8bytes.org>, "Avi Kivity" <avi@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	"David Hildenbrand" <david@redhat.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Jim Mattson <jmattson@google.com>
Subject: [RFC PATCH 0/6] KVM: x86: nSVM: Improve virtualization of VMCB12 G_PAT
Date: Fri,  7 Nov 2025 12:11:23 -0800	[thread overview]
Message-ID: <20251107201151.3303170-1-jmattson@google.com> (raw)

There are several problems with KVM's virtualization of the G_PAT
field when nested paging is enabled in VMCB12.

* The VMCB12 G_PAT field is not checked for validity when emulating
  VMRUN.  (APM volume 2, section 15.25.4: Nested Paging and
  VMRUN/#VMEXIT)

* RDMSR(PAT) and WRMSR(PAT) from L2 access L1's PAT MSR rather than
  L2's Guest PAT register. (APM volume 2, section 15.25.2: Replicated
  State)

* The L2 Guest PAT register is not written back to VMCB12 on #VMEXIT
  from L2 to L1. (APM volume 3, Section 4: "VMRUN")

* The value of L2's Guest PAT register is not serialized for
  save/restore when a checkpoint is taken while L2 is active.

Commit 4995a3685f1b ("KVM: SVM: Use a separate vmcb for the nested L2
guest") left this comment in nested_vmcb02_compute_g_pat():

      /* FIXME: merge g_pat from vmcb01 and vmcb12.  */

This comment makes no sense. It is true that there are now three
different PATs to consider: L2's PAT for guest page tables, L1's PAT
for the nested page tables mapping L2 guest physical addresses to L1
guest physical addresses, and L0's PAT for the nested page tables
mapping L1 guest physical addresses to host physical
addresses. However, if there is any "merging" to be done, it would
involve the latter two, and would happen during shadow nested page
table construction. (For the record, I don't think "merging" the two
nested page table PATs is feasible.) In any case, the VMCB12 G_PAT
should be copied unmodified into VMCB02.

Maybe the rest of the current implementation is a consistent quirk
based on the existing nested_vmcb02_compute_g_pat() code that bypasses
L1's request in VMCB12 and copies L1's PAT MSR into vmcb02
instead. However, an L1 hypervisor that does not intercept accesses to
the PAT MSR would legitimately be surprised to find that its L2 guest
can modify the hypervisor's own PAT!

The commits in this series are in an awkward order, because I didn't
want to change nested_vmcb02_compute_g_pat() until I had removed the
call site from svm_set_msr().

The first two commits should arguably be one, but I tried to deal with
the serialization issue separately from the RDMSR/WRMSR issue, despite
the two being intertwined.

I don't like the ugliness of KVM_GET_MSRS saving the L2 Guest PAT
register during a checkpoint, but KVM_SET_MSRS restoring the
architectural PAT MSR on restore (because when KVM_SET_MSRS is called,
L2 is not active). The APM section on replicated state offers a
possible out:

  While nested paging is enabled, all (guest) references to the state
  of the paging registers by x86 code (MOV to/from CRn, etc.) read and
  write the guest copy of the registers

If we consider KVM_{GET,SET}_MSRS not to be "guest" references, we
could always access the architected PAT MSR from userspace, and we
could grab 64 bits from the SVM nested state header to serialize L2's
G_PAT. In some ways, that seems cleaner, but it does mean that
KVM_{GET,SET}_MSR will access L1's PAT, which is irrelevant while L2
is active.

Hence, I am posting this series as an RFC.

Jim Mattson (6):
  KVM: x86: nSVM: Shuffle guest PAT and PAT MSR in
    svm_set_nested_state()
  KVM: x86: nSVM: Redirect PAT MSR accesses to gPAT when NPT is enabled
    in vmcb12
  KVM: x86: nSVM: Copy current vmcb02 g_pat to vmcb12 g_pat on #VMEXIT
  KVM: x86: nSVM: Cache g_pat in vmcb_ctrl_area_cached
  KVM: x86: nSVM: Add validity check for the VMCB12 g_pat
  KVM: x86: nSVM: Use cached VMCB12 g_pat in VMCB02 when using NPT

 arch/x86/include/uapi/asm/kvm.h |  2 ++
 arch/x86/kvm/svm/nested.c       | 35 +++++++++++++++++++++++++++++++--
 arch/x86/kvm/svm/svm.c          | 25 +++++++++++++++--------
 arch/x86/kvm/svm/svm.h          |  1 +
 4 files changed, 53 insertions(+), 10 deletions(-)

-- 
2.51.2.1041.gc1ab5b90ca-goog


             reply	other threads:[~2025-11-07 20:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-07 20:11 Jim Mattson [this message]
2025-11-07 20:11 ` [RFC PATCH 1/6] KVM: x86: nSVM: Shuffle guest PAT and PAT MSR in svm_set_nested_state() Jim Mattson
2025-11-07 20:11 ` [RFC PATCH 2/6] KVM: x86: nSVM: Redirect PAT MSR accesses to gPAT when NPT is enabled in vmcb12 Jim Mattson
2025-11-07 20:11 ` [RFC PATCH 3/6] KVM: x86: nSVM: Copy current vmcb02 g_pat to vmcb12 g_pat on #VMEXIT Jim Mattson
2025-11-07 20:11 ` [RFC PATCH 4/6] KVM: x86: nSVM: Cache g_pat in vmcb_ctrl_area_cached Jim Mattson
2025-11-07 20:11 ` [RFC PATCH 5/6] KVM: x86: nSVM: Add validity check for the VMCB12 g_pat Jim Mattson
2025-11-07 20:11 ` [RFC PATCH 6/6] KVM: x86: nSVM: Use cached VMCB12 g_pat in VMCB02 when using NPT Jim Mattson
2025-11-17 20:56 ` [RFC PATCH 0/6] KVM: x86: nSVM: Improve virtualization of VMCB12 G_PAT Yosry Ahmed

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=20251107201151.3303170-1-jmattson@google.com \
    --to=jmattson@google.com \
    --cc=agraf@suse.de \
    --cc=avi@redhat.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@redhat.com \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox