[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 03/10] target-i386: Implement CPUID[0xB] (Extended To
From: |
Eduardo Habkost |
Subject: |
[Qemu-devel] [PULL 03/10] target-i386: Implement CPUID[0xB] (Extended Topology Enumeration) |
Date: |
Tue, 14 Jun 2016 17:59:01 -0300 |
From: Radim Krčmář <address@hidden>
I looked at a dozen Intel CPU that have this CPUID and all of them
always had Core offset as 1 (a wasted bit when hyperthreading is
disabled) and Package offset at least 4 (wasted bits at <= 4 cores).
QEMU uses more compact IDs and it doesn't make much sense to change it
now. I keep the SMT and Core sub-leaves even if there is just one
thread/core; it makes the code simpler and there should be no harm.
Signed-off-by: Radim Krčmář <address@hidden>
Reviewed-by: Eduardo Habkost <address@hidden>
Signed-off-by: Eduardo Habkost <address@hidden>
---
include/hw/i386/pc.h | 7 ++++++-
target-i386/cpu.c | 32 ++++++++++++++++++++++++++++++++
target-i386/cpu.h | 8 ++++++++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ca23609..49566c8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -357,7 +357,12 @@ int e820_get_num_entries(void);
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_6 \
- HW_COMPAT_2_6
+ HW_COMPAT_2_6 \
+ {\
+ .driver = TYPE_X86_CPU,\
+ .property = "cpuid-0xb",\
+ .value = "off",\
+ },
#define PC_COMPAT_2_5 \
PC_COMPAT_2_6 \
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9c5aabc..f3f95cd 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -41,6 +41,7 @@
#include "sysemu/sysemu.h"
#include "hw/qdev-properties.h"
+#include "hw/i386/topology.h"
#ifndef CONFIG_USER_ONLY
#include "exec/address-spaces.h"
#include "hw/hw.h"
@@ -2492,6 +2493,36 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
*edx = 0;
}
break;
+ case 0xB:
+ /* Extended Topology Enumeration Leaf */
+ if (!cpu->enable_cpuid_0xb) {
+ *eax = *ebx = *ecx = *edx = 0;
+ break;
+ }
+
+ *ecx = count & 0xff;
+ *edx = cpu->apic_id;
+
+ switch (count) {
+ case 0:
+ *eax = apicid_core_offset(smp_cores, smp_threads);
+ *ebx = smp_threads;
+ *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
+ break;
+ case 1:
+ *eax = apicid_pkg_offset(smp_cores, smp_threads);
+ *ebx = smp_cores * smp_threads;
+ *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
+ break;
+ default:
+ *eax = 0;
+ *ebx = 0;
+ *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
+ }
+
+ assert(!(*eax & ~0x1f));
+ *ebx &= 0xffff; /* The count doesn't need to be reliable. */
+ break;
case 0xD: {
KVMState *s = cs->kvm_state;
uint64_t ena_mask;
@@ -3251,6 +3282,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
+ DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 0426459..d9ab884 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -636,6 +636,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_MWAIT_IBE (1U << 1) /* Interrupts can exit capability */
#define CPUID_MWAIT_EMX (1U << 0) /* enumeration supported */
+/* CPUID[0xB].ECX level types */
+#define CPUID_TOPOLOGY_LEVEL_INVALID (0U << 8)
+#define CPUID_TOPOLOGY_LEVEL_SMT (1U << 8)
+#define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
+
#ifndef HYPERV_SPINLOCK_NEVER_RETRY
#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF
#endif
@@ -1173,6 +1178,9 @@ struct X86CPU {
*/
bool enable_pmu;
+ /* Compatibility bits for old machine types: */
+ bool enable_cpuid_0xb;
+
/* in order to simplify APIC support, we leave this pointer to the
user */
struct DeviceState *apic_state;
--
2.5.5
- [Qemu-devel] [PULL 00/10] X86 queue, 2016-06-14, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 02/10] pc: Add 2.7 machine, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 03/10] target-i386: Implement CPUID[0xB] (Extended Topology Enumeration),
Eduardo Habkost <=
- [Qemu-devel] [PULL 01/10] target-i386: add Skylake-Client cpu model, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 05/10] target-i386: Move features logic that requires CPUState to realize time, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 07/10] target-i386: Move xcc->kvm_required check to realize time, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 04/10] target-i386: Remove xlevel & hv-spinlocks option fixups, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 08/10] target-i386: Use cpu_generic_init() in cpu_x86_init(), Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 06/10] target-i386: Remove assert(kvm_enabled()) from host_x86_cpu_initfn(), Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 09/10] target-i386: Consolidate calls of object_property_parse() in x86_cpu_parse_featurestr, Eduardo Habkost, 2016/06/14
- [Qemu-devel] [PULL 10/10] target-i386: Print obsolete warnings if +-features are used, Eduardo Habkost, 2016/06/14