Please trim your replies.  Scrolling through 100+ lines of quoted text to find
the ~12 lines of context that actually matter is annoying.

On Fri, Feb 13, 2026, Yosry Ahmed wrote:
> On Thu, Feb 12, 2026 at 07:58:52AM -0800, Jim Mattson wrote:
> > diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> > index a49c48459e0b..88549705133f 100644
> > --- a/arch/x86/kvm/svm/svm.h
> > +++ b/arch/x86/kvm/svm/svm.h
> > @@ -607,6 +607,22 @@ static inline bool nested_npt_enabled(struct vcpu_svm 
> > *svm)
> >     return svm->nested.ctl.misc_ctl & SVM_MISC_ENABLE_NP;
> >  }
> >  
> > +static inline void svm_set_gpat(struct vcpu_svm *svm, u64 data)
> > +{
> > +   svm->nested.save.g_pat = data;
> > +   vmcb_set_gpat(svm->nested.vmcb02.ptr, data);
> > +}
> > +
> > +static inline void svm_set_hpat(struct vcpu_svm *svm, u64 data)
> > +{
> > +   svm->vcpu.arch.pat = data;
> > +   if (npt_enabled) {

Peeking at the future patches, if we make this:

        if (!npt_enabled)
                return;

then we can end up with this:

        if (npt_enabled)
                return;

        vmcb_set_gpat(svm->vmcb01.ptr, data);
        if (is_guest_mode(&svm->vcpu) && !nested_npt_enabled(svm))
                vmcb_set_gpat(svm->nested.vmcb02.ptr, data);

        if (svm->nested.legacy_gpat_semantics)
                svm_set_l2_pat(svm, data);

Because legacy_gpat_semantics can only be true if npt_enabled is true.  Without
that guard, KVM _looks_ buggy because it's setting gpat in the VMCB even when
it shouldn't exist.

Actually, calling svm_set_l2_pat() when !is_guest_mode() is wrong too, no?  E.g.
shouldn't we end up with this?

  static inline void svm_set_l1_pat(struct vcpu_svm *svm, u64 data)
  {
        svm->vcpu.arch.pat = data;

        if (npt_enabled)
                return;

        vmcb_set_gpat(svm->vmcb01.ptr, data);

        if (is_guest_mode(&svm->vcpu)) {
                if (svm->nested.legacy_gpat_semantics)
                        svm_set_l2_pat(svm, data);
                else if (!nested_npt_enabled(svm))
                        vmcb_set_gpat(svm->nested.vmcb02.ptr, data);
        }
  }


> > +           vmcb_set_gpat(svm->vmcb01.ptr, data);
> > +           if (is_guest_mode(&svm->vcpu) && !nested_npt_enabled(svm))
> > +                   vmcb_set_gpat(svm->nested.vmcb02.ptr, data);
> > +   }
> > +}
> 
> Is it me, or is it a bit confusing that svm_set_gpat() sets L2's gPAT
> not L1's, and svm_set_hpat() calls vmcb_set_gpat()?

It's not just you.  I don't find it confusing per se, more that it's really
subtle.

> "gpat" means different things in the context of the VMCB or otherwise,
> which kinda makes sense but is also not super clear. Maybe
> svm_set_l1_gpat() and svm_set_l2_gpat() is more clear?

I think just svm_set_l1_pat() and svm_set_l2_pat(), because gpat straight up
doesn't exist when NPT is disabled/unsupported.

Reply via email to