From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Jim Mattson <jmattson@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Joerg Roedel <joro@8bytes.org>, kvm list <kvm@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Jan Kiszka <jan.kiszka@siemens.com>,
Xiaoyao Li <xiaoyao.li@intel.com>
Subject: Re: [PATCH 2/6] KVM: x86: Fix CPUID range check for Centaur and Hypervisor ranges
Date: Mon, 2 Mar 2020 16:57:27 -0800 [thread overview]
Message-ID: <20200303005727.GB27842@linux.intel.com> (raw)
In-Reply-To: <CALMp9eTNY0Wd=Wc=b8xzg0xRYE-ht5m=+cZeEb7nZup6EdYhCg@mail.gmail.com>
On Mon, Mar 02, 2020 at 01:59:10PM -0800, Jim Mattson wrote:
> On Mon, Mar 2, 2020 at 11:57 AM Sean Christopherson
> <sean.j.christopherson@intel.com> wrote:
> >
> > Extend the mask in cpuid_function_in_range() for finding the "class" of
> > the function to 0xfffffff00. While there is no official definition of
> > what constitutes a class, e.g. arguably bits 31:16 should be the class
> > and bits 15:0 the functions within that class, the Hypervisor logic
> > effectively uses bits 31:8 as the class by virtue of checking for
> > different bases in increments of 0x100, e.g. KVM advertises its CPUID
> > functions starting at 0x40000100 when HyperV features are advertised at
> > the default base of 0x40000000.
>
> This convention deserves explicit documentation outside of the commit message.
No argument there.
> > Masking against 0x80000000 only handles basic and extended leafs, which
> > results in Centaur and Hypervisor range checks being performed against
> > the basic CPUID range, e.g. if CPUID.0x40000000.EAX=0x4000000A and there
> > is no entry for CPUID.0x40000006, then function 0x40000006 would be
> > incorrectly reported as out of bounds.
> >
> > The bad range check doesn't cause function problems for any known VMM
> > because out-of-range semantics only come into play if the exact entry
> > isn't found, and VMMs either support a very limited Hypervisor range,
> > e.g. the official KVM range is 0x40000000-0x40000001 (effectively no
> > room for undefined leafs) or explicitly defines gaps to be zero, e.g.
> > Qemu explicitly creates zeroed entries up to the Cenatur and Hypervisor
> > limits (the latter comes into play when providing HyperV features).
>
> Does Centaur implement the bizarre Intel behavior for out-of-bound
> entries? It seems that if there are Centaur leaves defined, the CPUD
> semantics should be those specified by Centaur.
Ah, right, because this code triggers on !=AMD, not ==Intel. Your guess
is as good as mine, I've dug around a few times trying to track down a spec
for Centaur/VIA without success.
I would say that KVM's emulation behavior should probably be all or
nothing, i.e. either due Intel's silly logic for all ranges/classes or do
it for none.
> > The bad behavior can be visually confirmed by dumping CPUID output in
> > the guest when running Qemu with a stable TSC, as Qemu extends the limit
> > of range 0x40000000 to 0x40000010 to advertise VMware's cpuid_freq,
> > without defining zeroed entries for 0x40000002 - 0x4000000f.
> >
> > Fixes: 43561123ab37 ("kvm: x86: Improve emulation of CPUID leaves 0BH and 1FH")
> > Cc: Jim Mattson <jmattson@google.com>
> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> > ---
> > arch/x86/kvm/cpuid.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> > index 6be012937eba..c320126e0118 100644
> > --- a/arch/x86/kvm/cpuid.c
> > +++ b/arch/x86/kvm/cpuid.c
> > @@ -993,7 +993,7 @@ static bool cpuid_function_in_range(struct kvm_vcpu *vcpu, u32 function)
> > {
> > struct kvm_cpuid_entry2 *max;
> >
> > - max = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
> > + max = kvm_find_cpuid_entry(vcpu, function & 0xffffff00u, 0);
>
> This assumes that CPUID.(function & 0xffffff00):EAX always contains
> the maximum input value for the 256-entry range sharing the high 24
> bits. I don't believe that convention has ever been established or
> documented.
Not sure if it's formally documented, but it's well established. The
closest thing I could find to documentation is the lkml thread where what's
implemented today (AFAICT) was proposed.
https://lore.kernel.org/lkml/48E3BBC1.2050607@goop.org/
The relevant linux code in Linux (arch/x86/include/asm/processor.h), where
@leaves contains the kernel's required minimum leaf to enable paravirt
stuff for the hypervisor.
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
{
uint32_t base, eax, signature[3];
for (base = 0x40000000; base < 0x40010000; base += 0x100) {
cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
if (!memcmp(sig, signature, 12) &&
(leaves == 0 || ((eax - base) >= leaves)))
return base;
}
return 0;
}
> > return max && function <= max->eax;
> > }
> >
> > --
> > 2.24.1
> >
next prev parent reply other threads:[~2020-03-03 0:57 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-02 19:57 [PATCH 0/6] KVM: x86: CPUID emulation and tracing fixes Sean Christopherson
2020-03-02 19:57 ` [PATCH 1/6] KVM: x86: Fix tracing of CPUID.function when function is out-of-range Sean Christopherson
2020-03-02 20:26 ` Jan Kiszka
2020-03-02 20:49 ` Sean Christopherson
2020-03-02 20:59 ` Jan Kiszka
2020-03-03 2:27 ` Xiaoyao Li
2020-03-03 3:45 ` Sean Christopherson
2020-03-03 4:02 ` Xiaoyao Li
2020-03-03 4:12 ` Sean Christopherson
2020-03-03 4:30 ` Xiaoyao Li
2020-03-03 2:50 ` Xiaoyao Li
2020-03-03 4:08 ` Sean Christopherson
2020-03-03 4:16 ` Xiaoyao Li
2020-03-02 19:57 ` [PATCH 2/6] KVM: x86: Fix CPUID range check for Centaur and Hypervisor ranges Sean Christopherson
2020-03-02 21:59 ` Jim Mattson
2020-03-03 0:57 ` Sean Christopherson [this message]
2020-03-03 3:25 ` Jim Mattson
2020-03-03 4:25 ` Jim Mattson
2020-03-03 4:58 ` Sean Christopherson
2020-03-03 17:42 ` Jim Mattson
2020-03-03 18:01 ` Sean Christopherson
2020-03-03 18:08 ` Jim Mattson
2020-03-04 11:18 ` Paolo Bonzini
2020-03-02 19:57 ` [PATCH 3/6] KVM: x86: Add dedicated emulator helper for grabbing CPUID.maxphyaddr Sean Christopherson
2020-03-03 8:48 ` Paolo Bonzini
2020-03-03 9:48 ` Jan Kiszka
2020-03-03 10:14 ` Paolo Bonzini
2020-03-04 20:47 ` Sean Christopherson
2020-03-03 16:28 ` Sean Christopherson
2020-03-03 17:21 ` Paolo Bonzini
2020-03-02 19:57 ` [PATCH 4/6] KVM: x86: Drop return value from kvm_cpuid() Sean Christopherson
2020-03-02 19:57 ` [PATCH 5/6] KVM: x86: Rename "found" variable in kvm_cpuid() to "exact_entry_exists" Sean Christopherson
2020-03-02 20:20 ` Jan Kiszka
2020-03-02 20:35 ` Sean Christopherson
2020-03-02 20:48 ` Jan Kiszka
2020-03-02 19:57 ` [PATCH 6/6] KVM: x86: Add requested index to the CPUID tracepoint Sean Christopherson
2020-03-07 9:48 ` Jan Kiszka
2020-03-10 4:00 ` Sean Christopherson
2020-03-03 8:48 ` [PATCH 0/6] KVM: x86: CPUID emulation and tracing fixes Paolo Bonzini
2020-03-03 16:38 ` 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=20200303005727.GB27842@linux.intel.com \
--to=sean.j.christopherson@intel.com \
--cc=jan.kiszka@siemens.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.com \
--cc=xiaoyao.li@intel.com \
/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.