linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Jim Mattson <jmattson@google.com>, Marc Orr <marcorr@google.com>,
	Peter Shier <pshier@google.com>, Jacob Xu <jacobhxu@google.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Sasha Levin <sashal@kernel.org>,
	kvm@vger.kernel.org
Subject: [PATCH AUTOSEL 4.14 06/21] kvm: x86: Improve emulation of CPUID leaves 0BH and 1FH
Date: Wed,  9 Oct 2019 13:05:59 -0400	[thread overview]
Message-ID: <20191009170615.32750-6-sashal@kernel.org> (raw)
In-Reply-To: <20191009170615.32750-1-sashal@kernel.org>

From: Jim Mattson <jmattson@google.com>

[ Upstream commit 43561123ab3759eb6ff47693aec1a307af0aef83 ]

For these CPUID leaves, the EDX output is not dependent on the ECX
input (i.e. the SIGNIFCANT_INDEX flag doesn't apply to
EDX). Furthermore, the low byte of the ECX output is always identical
to the low byte of the ECX input. KVM does not produce the correct ECX
and EDX outputs for any undefined subleaves beyond the first.

Special-case these CPUID leaves in kvm_cpuid, so that the ECX and EDX
outputs are properly generated for all undefined subleaves.

Fixes: 0771671749b59a ("KVM: Enhance guest cpuid management")
Fixes: a87f2d3a6eadab ("KVM: x86: Add Intel CPUID.1F cpuid emulation support")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Marc Orr <marcorr@google.com>
Reviewed-by: Peter Shier <pshier@google.com>
Reviewed-by: Jacob Xu <jacobhxu@google.com>
Cc: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/kvm/cpuid.c | 83 +++++++++++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 5c82b4bc4a68a..f3c49dc423895 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -868,53 +868,64 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
 EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
 
 /*
- * If no match is found, check whether we exceed the vCPU's limit
- * and return the content of the highest valid _standard_ leaf instead.
- * This is to satisfy the CPUID specification.
+ * If the basic or extended CPUID leaf requested is higher than the
+ * maximum supported basic or extended leaf, respectively, then it is
+ * out of range.
  */
-static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
-                                                  u32 function, u32 index)
+static bool cpuid_function_in_range(struct kvm_vcpu *vcpu, u32 function)
 {
-	struct kvm_cpuid_entry2 *maxlevel;
-
-	maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
-	if (!maxlevel || maxlevel->eax >= function)
-		return NULL;
-	if (function & 0x80000000) {
-		maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
-		if (!maxlevel)
-			return NULL;
-	}
-	return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
+	struct kvm_cpuid_entry2 *max;
+
+	max = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
+	return max && function <= max->eax;
 }
 
 bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
 	       u32 *ecx, u32 *edx, bool check_limit)
 {
 	u32 function = *eax, index = *ecx;
-	struct kvm_cpuid_entry2 *best;
-	bool entry_found = true;
-
-	best = kvm_find_cpuid_entry(vcpu, function, index);
-
-	if (!best) {
-		entry_found = false;
-		if (!check_limit)
-			goto out;
+	struct kvm_cpuid_entry2 *entry;
+	struct kvm_cpuid_entry2 *max;
+	bool found;
 
-		best = check_cpuid_limit(vcpu, function, index);
+	entry = kvm_find_cpuid_entry(vcpu, function, index);
+	found = entry;
+	/*
+	 * Intel CPUID semantics treats any query for an out-of-range
+	 * leaf as if the highest basic leaf (i.e. CPUID.0H:EAX) were
+	 * requested.
+	 */
+	if (!entry && check_limit && !cpuid_function_in_range(vcpu, function)) {
+		max = kvm_find_cpuid_entry(vcpu, 0, 0);
+		if (max) {
+			function = max->eax;
+			entry = kvm_find_cpuid_entry(vcpu, function, index);
+		}
 	}
-
-out:
-	if (best) {
-		*eax = best->eax;
-		*ebx = best->ebx;
-		*ecx = best->ecx;
-		*edx = best->edx;
-	} else
+	if (entry) {
+		*eax = entry->eax;
+		*ebx = entry->ebx;
+		*ecx = entry->ecx;
+		*edx = entry->edx;
+	} else {
 		*eax = *ebx = *ecx = *edx = 0;
-	trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found);
-	return entry_found;
+		/*
+		 * When leaf 0BH or 1FH is defined, CL is pass-through
+		 * and EDX is always the x2APIC ID, even for undefined
+		 * subleaves. Index 1 will exist iff the leaf is
+		 * implemented, so we pass through CL iff leaf 1
+		 * exists. EDX can be copied from any existing index.
+		 */
+		if (function == 0xb || function == 0x1f) {
+			entry = kvm_find_cpuid_entry(vcpu, function, 1);
+			if (entry) {
+				*ecx = index & 0xff;
+				*edx = entry->edx;
+			}
+		}
+	}
+	trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, found);
+	return found;
 }
 EXPORT_SYMBOL_GPL(kvm_cpuid);
 
-- 
2.20.1


  parent reply	other threads:[~2019-10-09 17:28 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-09 17:05 [PATCH AUTOSEL 4.14 01/21] KVM: arm/arm64: vgic: Use the appropriate TRACE_INCLUDE_PATH Sasha Levin
2019-10-09 17:05 ` [PATCH AUTOSEL 4.14 02/21] scsi: ufs: skip shutdown if hba is not powered Sasha Levin
2019-10-09 17:05 ` [PATCH AUTOSEL 4.14 03/21] scsi: megaraid: disable device when probe failed after enabled device Sasha Levin
2019-10-09 17:05 ` [PATCH AUTOSEL 4.14 04/21] scsi: qla2xxx: Fix unbound sleep in fcport delete path Sasha Levin
2019-10-09 17:05 ` [PATCH AUTOSEL 4.14 05/21] ARM: OMAP2+: Fix missing reset done flag for am3 and am43 Sasha Levin
2019-10-09 17:05 ` Sasha Levin [this message]
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 07/21] kvm: x86: Use AMD CPUID semantics for AMD vCPUs Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 08/21] ieee802154: ca8210: prevent memory leak Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 09/21] ARM: dts: am4372: Set memory bandwidth limit for DISPC Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 10/21] net: dsa: qca8k: Use up to 7 ports for all operations Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 11/21] MIPS: dts: ar9331: fix interrupt-controller size Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 12/21] xen/efi: Set nonblocking callbacks Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 13/21] kvm: vmx: Limit guest PMCs to those supported on the host Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 14/21] nl80211: fix null pointer dereference Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 15/21] mac80211: fix txq " Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 16/21] mips: Loongson: Fix the link time qualifier of 'serial_exit()' Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 17/21] net: hisilicon: Fix usage of uninitialized variable in function mdio_sc_cfg_reg_write() Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 18/21] vfs: Fix EOVERFLOW testing in put_compat_statfs64 Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 19/21] r8152: Set macpassthru in reset_resume callback Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 20/21] namespace: fix namespace.pl script to support relative paths Sasha Levin
2019-10-09 17:06 ` [PATCH AUTOSEL 4.14 21/21] Make filldir[64]() verify the directory entry filename is valid Sasha Levin

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=20191009170615.32750-6-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=jacobhxu@google.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcorr@google.com \
    --cc=pbonzini@redhat.com \
    --cc=pshier@google.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=stable@vger.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;
as well as URLs for NNTP newsgroup(s).