From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Sergio Andres Gomez Del Real <sergio.g.delreal@gmail.com>,
Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com>
Subject: [Qemu-devel] [PULL 05/19] i386: hvf: implement hvf_get_supported_cpuid
Date: Wed, 20 Dec 2017 19:03:44 +0100 [thread overview]
Message-ID: <20171220180358.29316-6-pbonzini@redhat.com> (raw)
In-Reply-To: <20171220180358.29316-1-pbonzini@redhat.com>
From: Sergio Andres Gomez Del Real <sergio.g.delreal@gmail.com>
This patch implements hvf_get_supported_cpuid, which returns the set of
features supported by both the host processor and the hypervisor.
Signed-off-by: Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com>
Message-Id: <20170913090522.4022-11-Sergio.G.DelReal@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf-utils/x86_cpuid.c | 164 ++++++++++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)
create mode 100644 target/i386/hvf-utils/x86_cpuid.c
diff --git a/target/i386/hvf-utils/x86_cpuid.c b/target/i386/hvf-utils/x86_cpuid.c
new file mode 100644
index 0000000000..103223a85d
--- /dev/null
+++ b/target/i386/hvf-utils/x86_cpuid.c
@@ -0,0 +1,164 @@
+/*
+ * i386 CPUID helper functions
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2017 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * cpuid
+ */
+
+#include "qemu/osdep.h"
+#include "x86.h"
+#include "vmx.h"
+#include "sysemu/hvf.h"
+
+static uint64_t xgetbv(uint32_t xcr)
+{
+ uint32_t eax, edx;
+
+ __asm__ volatile ("xgetbv"
+ : "=a" (eax), "=d" (edx)
+ : "c" (xcr));
+
+ return (((uint64_t)edx) << 32) | eax;
+}
+
+static bool vmx_mpx_supported()
+{
+ uint64_t cap_exit, cap_entry;
+
+ hv_vmx_read_capability(HV_VMX_CAP_ENTRY, &cap_entry);
+ hv_vmx_read_capability(HV_VMX_CAP_EXIT, &cap_exit);
+
+ return ((cap_exit & (1 << 23)) && (cap_entry & (1 << 16)));
+}
+
+uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
+ int reg)
+{
+ uint64_t cap;
+ uint32_t eax, ebx, ecx, edx;
+
+ host_cpuid(func, idx, &eax, &ebx, &ecx, &edx);
+
+ switch (func) {
+ case 0:
+ eax = eax < (uint32_t)0xd ? eax : (uint32_t)0xd;
+ break;
+ case 1:
+ edx &= CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX |
+ CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS;
+ ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID |
+ CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE |
+ CPUID_EXT_POPCNT | CPUID_EXT_AES | CPUID_EXT_XSAVE |
+ CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND;
+ ecx |= CPUID_EXT_HYPERVISOR;
+ break;
+ case 6:
+ eax = CPUID_6_EAX_ARAT;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ break;
+ case 7:
+ if (idx == 0) {
+ ebx &= CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+ CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 |
+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 |
+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_RTM |
+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_AVX512IFMA |
+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512PF |
+ CPUID_7_0_EBX_AVX512ER | CPUID_7_0_EBX_AVX512CD |
+ CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB |
+ CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_SHA_NI |
+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL |
+ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_MPX;
+
+ if (!vmx_mpx_supported()) {
+ ebx &= ~CPUID_7_0_EBX_MPX;
+ }
+ hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
+ if (!(cap & CPU_BASED2_INVPCID)) {
+ ebx &= ~CPUID_7_0_EBX_INVPCID;
+ }
+
+ ecx &= CPUID_7_0_ECX_AVX512BMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ;
+ edx &= CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS;
+ } else {
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ }
+ eax = 0;
+ break;
+ case 0xD:
+ if (idx == 0) {
+ uint64_t host_xcr0 = xgetbv(0);
+ uint64_t supp_xcr0 = host_xcr0 & (XSTATE_FP_MASK | XSTATE_SSE_MASK |
+ XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK |
+ XSTATE_BNDCSR_MASK | XSTATE_OPMASK_MASK |
+ XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK);
+ eax &= supp_xcr0;
+ if (!vmx_mpx_supported()) {
+ eax &= ~(XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK);
+ }
+ } else if (idx == 1) {
+ hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
+ eax &= CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1;
+ if (!(cap & CPU_BASED2_XSAVES_XRSTORS)) {
+ eax &= ~CPUID_XSAVE_XSAVES;
+ }
+ }
+ break;
+ case 0x80000001:
+ /* LM only if HVF in 64-bit mode */
+ edx &= CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
+ CPUID_EXT2_SYSCALL | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
+ CPUID_PAT | CPUID_PSE36 | CPUID_EXT2_MMXEXT | CPUID_MMX |
+ CPUID_FXSR | CPUID_EXT2_FXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_3DNOWEXT |
+ CPUID_EXT2_3DNOW | CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX;
+ hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap);
+ if (!(cap & CPU_BASED_TSC_OFFSET)) {
+ edx &= ~CPUID_EXT2_RDTSCP;
+ }
+ ecx &= CPUID_EXT3_LAHF_LM | CPUID_EXT3_CMP_LEG | CPUID_EXT3_CR8LEG |
+ CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | CPUID_EXT3_MISALIGNSSE |
+ CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_OSVW | CPUID_EXT3_XOP |
+ CPUID_EXT3_FMA4 | CPUID_EXT3_TBM;
+ break;
+ default:
+ return 0;
+ }
+
+ switch (reg) {
+ case R_EAX:
+ return eax;
+ case R_EBX:
+ return ebx;
+ case R_ECX:
+ return ecx;
+ case R_EDX:
+ return edx;
+ default:
+ return 0;
+ }
+}
--
2.14.3
next prev parent reply other threads:[~2017-12-20 18:04 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-20 18:03 [Qemu-devel] [PULL 00/19] Initial support for Hypervisor.framework Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 01/19] apic: add function to apic that will be used by hvf Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 02/19] i386: hvf: add code base from Google's QEMU repository Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 03/19] i386: hvf: fix licensing issues; isolate task handling code (GPL v2-only) Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 04/19] i386: hvf: use new helper functions for put/get xsave Paolo Bonzini
2017-12-20 18:03 ` Paolo Bonzini [this message]
2017-12-20 18:03 ` [Qemu-devel] [PULL 06/19] i386: refactor KVM cpuid code so that it applies to hvf as well Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 07/19] i386: hvf: implement vga dirty page tracking Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 08/19] i386: hvf: refactor event injection code for hvf Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 09/19] i386: hvf: inject General Protection Fault when vmexit through vmcall Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 10/19] i386: hvf: move all hvf files in the same directory Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 11/19] i386: hvf: header cleanup Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 12/19] i386: hvf: unify register enums between HVF and the rest Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 13/19] i386: hvf: remove more dead emulator code Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 14/19] i386: hvf: remove ZERO_INIT macro Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 15/19] i386: hvf: abort on decoding error Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 16/19] i386: hvf: simplify flag handling Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 17/19] i386: hvf: remove addr_t Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 18/19] i386: hvf: remove VM_PANIC from "in" Paolo Bonzini
2017-12-20 18:03 ` [Qemu-devel] [PULL 19/19] i386: hvf: cleanup x86_gen.h Paolo Bonzini
2017-12-20 19:15 ` [Qemu-devel] [PULL 00/19] Initial support for Hypervisor.framework no-reply
2017-12-20 19:16 ` no-reply
2017-12-20 20:31 ` Peter Maydell
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=20171220180358.29316-6-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=sergio.g.delreal@gmail.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 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).