On Fri, Feb 13, 2026 at 2:19 PM Sean Christopherson <[email protected]> wrote:
>
> On Fri, Feb 13, 2026, Jim Mattson wrote:
> > On Fri, Feb 13, 2026 at 7:20 AM Sean Christopherson <[email protected]> 
> > wrote:
> > > > > +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?
> >
> > Sigh. legacy_gpat_semantics is supposed to be set only when
> > is_guest_mode() and nested_npt_enabled(). I forgot about back-to-back
> > invocations of KVM_SET_NESTED_STATE. Are there other ways of leaving
> > guest mode or disabling nested NPT before the next KVM_RUN?
>
> KVM_SET_VCPU_EVENTS will do it if userspace forces a change in SMM state:
>
>                 if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
>                         kvm_leave_nested(vcpu);
>                         kvm_smm_changed(vcpu, events->smi.smm);
>                 }
>
> I honestly wasn't even thinking of anything in particular, it just looked 
> weird.

At the very least, then, kvm_leave_nested() has to clear
legacy_gpat_semantics. I will look for other paths.

> > > > > +           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.
> >
> > My intention was that "gpat" and "hpat" were from the perspective of the 
> > vCPU.
> >
> > I dislike svm_set_l1_pat() and svm_set_l2_pat(). As you point out
> > above, there is no independent L2 PAT when nested NPT is disabled. I
> > think that's less obvious than the fact that there is no gPAT from the
> > vCPU's perspective. My preference is to follow the APM terminology
> > when possible. Making up our own terms just leads to confusion.
>
> How about svm_set_pat() and svm_get_gpat()?  Because hPAT doesn't exist when 
> NPT
> is unsupported/disabled, but KVM still needs to set the vCPU's emulated PAT 
> value.

What if we don't break it up this way at all? Instead of distributing
the logic between svm_[gs]set_msr() and a few helper functions, we
could just have svm_[gs]et_msr() call svm_[gs]et_pat(), and all of the
logic can go in these two functions.

Reply via email to