All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Jim Mattson <jmattson@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Thomas Gleixner <tglx@kernel.org>, 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>,
	Shuah Khan <shuah@kernel.org>,
	kvm@vger.kernel.org,  linux-kernel@vger.kernel.org,
	linux-kselftest@vger.kernel.org,  Yosry Ahmed <yosry@kernel.org>,
	Yosry Ahmed <yosry.ahmed@linux.dev>
Subject: Re: [PATCH v5 08/10] KVM: x86: nSVM: Save/restore gPAT with KVM_{GET,SET}_NESTED_STATE
Date: Wed, 4 Mar 2026 09:11:53 -0800	[thread overview]
Message-ID: <aahn2ZfDAJTj-Afn@google.com> (raw)
In-Reply-To: <20260224005500.1471972-9-jmattson@google.com>

On Mon, Feb 23, 2026, Jim Mattson wrote:
> Add a 'flags' field to the SVM nested state header, and use bit 0 of the
> flags to indicate that gPAT is stored in the nested state.
> 
> If in guest mode with NPT enabled, store the current vmcb->save.g_pat value
> into the header of the nested state, and set the flag.
> 
> Note that struct kvm_svm_nested_state_hdr is included in a union padded to
> 120 bytes, so there is room to add the flags field and the gpat field
> without changing any offsets.
> 
> Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
> Signed-off-by: Jim Mattson <jmattson@google.com>
> Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> ---
>  arch/x86/include/uapi/asm/kvm.h |  5 +++++
>  arch/x86/kvm/svm/nested.c       | 17 +++++++++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
> index 846a63215ce1..664d04d1db3f 100644
> --- a/arch/x86/include/uapi/asm/kvm.h
> +++ b/arch/x86/include/uapi/asm/kvm.h
> @@ -495,6 +495,8 @@ struct kvm_sync_regs {
>  
>  #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE	0x00000001
>  
> +#define KVM_STATE_SVM_VALID_GPAT	0x00000001
> +
>  /* vendor-independent attributes for system fd (group 0) */
>  #define KVM_X86_GRP_SYSTEM		0
>  #  define KVM_X86_XCOMP_GUEST_SUPP	0
> @@ -531,6 +533,9 @@ struct kvm_svm_nested_state_data {
>  
>  struct kvm_svm_nested_state_hdr {
>  	__u64 vmcb_pa;
> +	__u32 flags;
> +	__u32 reserved;
> +	__u64 gpat;
>  };
>  
>  /* for KVM_CAP_NESTED_STATE */
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index 26f758e294ab..5a35277f2364 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -1893,6 +1893,10 @@ static int svm_get_nested_state(struct kvm_vcpu *vcpu,
>  	/* First fill in the header and copy it out.  */
>  	if (is_guest_mode(vcpu)) {
>  		kvm_state.hdr.svm.vmcb_pa = svm->nested.vmcb12_gpa;
> +		if (nested_npt_enabled(svm)) {
> +			kvm_state.hdr.svm.flags |= KVM_STATE_SVM_VALID_GPAT;

Bugger.  This isn't going to work.  KVM doesn't reserve any bytes in the header
for SVM, so there's no guarantee/requirement that old userspace won't provide
garbage.  The flag needs to go in kvm_nested_state.flags.  We only reserved space
for 16 flags between VMX and SVM, but that's a future problem as we can always
add e.g. KVM_STATE_NESTED_EXT_FLAGS when we've exausted the current space.

Ugh.  And vmx_set_nested_state() doesn't check for unsupported flags, at all.
But that too is largely a future problem though, i.e. is a non-issue until nVMX
wants to add a new flag.  *sigh*

Anyways, for gPAT, unless I'm missing something, I'm going to squash this:

diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index 664d04d1db3f..0c1f97c9a2d8 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -485,6 +485,7 @@ struct kvm_sync_regs {
 #define KVM_STATE_NESTED_EVMCS         0x00000004
 #define KVM_STATE_NESTED_MTF_PENDING   0x00000008
 #define KVM_STATE_NESTED_GIF_SET       0x00000100
+#define KVM_STATE_NESTED_GPAT_VALID    0x00000200
 
 #define KVM_STATE_NESTED_SMM_GUEST_MODE        0x00000001
 #define KVM_STATE_NESTED_SMM_VMXON     0x00000002
@@ -495,8 +496,6 @@ struct kvm_sync_regs {
 
 #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE        0x00000001
 
-#define KVM_STATE_SVM_VALID_GPAT       0x00000001
-
 /* vendor-independent attributes for system fd (group 0) */
 #define KVM_X86_GRP_SYSTEM             0
 #  define KVM_X86_XCOMP_GUEST_SUPP     0
@@ -533,8 +532,6 @@ struct kvm_svm_nested_state_data {
 
 struct kvm_svm_nested_state_hdr {
        __u64 vmcb_pa;
-       __u32 flags;
-       __u32 reserved;
        __u64 gpat;
 };
 
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index 991ee4c03363..099bf8ac10ee 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1848,7 +1848,7 @@ static int svm_get_nested_state(struct kvm_vcpu *vcpu,
        if (is_guest_mode(vcpu)) {
                kvm_state.hdr.svm.vmcb_pa = svm->nested.vmcb12_gpa;
                if (nested_npt_enabled(svm)) {
-                       kvm_state.hdr.svm.flags |= KVM_STATE_SVM_VALID_GPAT;
+                       kvm_state->flags |= KVM_STATE_NESTED_GPAT_VALID;
                        kvm_state.hdr.svm.gpat = svm->vmcb->save.g_pat;
                }
                kvm_state.size += KVM_STATE_NESTED_SVM_VMCB_SIZE;
@@ -1914,7 +1914,8 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
 
        if (kvm_state->flags & ~(KVM_STATE_NESTED_GUEST_MODE |
                                 KVM_STATE_NESTED_RUN_PENDING |
-                                KVM_STATE_NESTED_GIF_SET))
+                                KVM_STATE_NESTED_GIF_SET |
+                                KVM_STATE_NESTED_GPAT_VALID))
                return -EINVAL;
 
        /*
@@ -1984,7 +1985,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
         * vmcb_save_area_cached validation above, because gPAT is L2
         * state, but the vmcb_save_area_cached is populated with L1 state.
         */
-       if ((kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT) &&
+       if ((kvm_state->flags & KVM_STATE_NESTED_GPAT_VALID) &&
            !kvm_pat_valid(kvm_state->hdr.svm.gpat))
                goto out_free;
 
@@ -2013,7 +2014,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
        svm_switch_vmcb(svm, &svm->nested.vmcb02);
 
        if (nested_npt_enabled(svm)) {
-               if (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)
+               if (kvm_state->flags & KVM_STATE_NESTED_GPAT_VALID)
                        vmcb_set_gpat(svm->vmcb, kvm_state->hdr.svm.gpat);
        }
--

One could argue we should even be more paranoid and do this as well:

	if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) {
		if (kvm_state->flags & KVM_STATE_NESTED_GPAT_VALID)
			return -EINVAL:

		svm_leave_nested(vcpu);
		svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET));
		return 0;
	}

but KVM doesn't enforce GUEST_MODE for KVM_STATE_NESTED_RUN_PENDING, and it's
easy to just ignore gPAT, so I'm inclined to not bother.

  reply	other threads:[~2026-03-04 17:11 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-24  0:54 [PATCH v5 00/10] KVM: x86: nSVM: Improve PAT virtualization Jim Mattson
2026-02-24  0:54 ` [PATCH v5 01/10] KVM: x86: SVM: Remove vmcb_is_dirty() Jim Mattson
2026-02-24  0:54 ` [PATCH v5 02/10] KVM: x86: nSVM: Clear VMCB_NPT clean bit when updating hPAT from guest mode Jim Mattson
2026-02-24  0:54 ` [PATCH v5 03/10] KVM: x86: nSVM: Cache and validate vmcb12 g_pat Jim Mattson
2026-02-24  0:54 ` [PATCH v5 04/10] KVM: x86: nSVM: Set vmcb02.g_pat correctly for nested NPT Jim Mattson
2026-02-24  0:54 ` [PATCH v5 05/10] KVM: x86: nSVM: Redirect IA32_PAT accesses to either hPAT or gPAT Jim Mattson
2026-02-24 17:43   ` Sean Christopherson
2026-02-24 18:18     ` Jim Mattson
2026-02-24 19:04     ` Yosry Ahmed
2026-02-24  0:54 ` [PATCH v5 06/10] KVM: x86: Remove common handling of MSR_IA32_CR_PAT Jim Mattson
2026-02-24  0:54 ` [PATCH v5 07/10] KVM: x86: nSVM: Save gPAT to vmcb12.g_pat on VMEXIT Jim Mattson
2026-02-24  0:54 ` [PATCH v5 08/10] KVM: x86: nSVM: Save/restore gPAT with KVM_{GET,SET}_NESTED_STATE Jim Mattson
2026-03-04 17:11   ` Sean Christopherson [this message]
2026-03-04 18:37     ` Jim Mattson
2026-03-04 19:11       ` Sean Christopherson
2026-03-04 19:35         ` Yosry Ahmed
2026-03-04 19:55           ` Sean Christopherson
2026-03-05 18:49             ` Jim Mattson
2026-02-24  0:54 ` [PATCH v5 09/10] KVM: x86: nSVM: Handle restore of legacy nested state Jim Mattson
2026-03-03 17:32   ` Sean Christopherson
2026-02-24  0:54 ` [PATCH v5 10/10] KVM: selftests: nSVM: Add svm_nested_pat test Jim Mattson
2026-03-05 17:08 ` [PATCH v5 00/10] KVM: x86: nSVM: Improve PAT virtualization Sean Christopherson

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=aahn2ZfDAJTj-Afn@google.com \
    --to=seanjc@google.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=shuah@kernel.org \
    --cc=tglx@kernel.org \
    --cc=x86@kernel.org \
    --cc=yosry.ahmed@linux.dev \
    --cc=yosry@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 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.