*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "qemu/cutils.h"
+#include "qemu/bitops.h"
#include "cpu.h"
#include "exec/exec-all.h"
int associativity;
};
-#define KiB 1024
-#define MiB (1024 * 1024)
-
/*
* Known CPUID 2 cache descriptors.
* From Intel SDM Volume 2A, CPUID instruction
*/
struct CPUID2CacheDescriptorInfo cpuid2_cache_descriptors[] = {
- [0x06] = { .level = 1, .type = ICACHE, .size = 8 * KiB,
+ [0x06] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 8 * KiB,
.associativity = 4, .line_size = 32, },
- [0x08] = { .level = 1, .type = ICACHE, .size = 16 * KiB,
+ [0x08] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 16 * KiB,
.associativity = 4, .line_size = 32, },
- [0x09] = { .level = 1, .type = ICACHE, .size = 32 * KiB,
+ [0x09] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 32 * KiB,
.associativity = 4, .line_size = 64, },
- [0x0A] = { .level = 1, .type = DCACHE, .size = 8 * KiB,
+ [0x0A] = { .level = 1, .type = DATA_CACHE, .size = 8 * KiB,
.associativity = 2, .line_size = 32, },
- [0x0C] = { .level = 1, .type = DCACHE, .size = 16 * KiB,
+ [0x0C] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
.associativity = 4, .line_size = 32, },
- [0x0D] = { .level = 1, .type = DCACHE, .size = 16 * KiB,
+ [0x0D] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
.associativity = 4, .line_size = 64, },
- [0x0E] = { .level = 1, .type = DCACHE, .size = 24 * KiB,
+ [0x0E] = { .level = 1, .type = DATA_CACHE, .size = 24 * KiB,
.associativity = 6, .line_size = 64, },
- [0x1D] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+ [0x1D] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
.associativity = 2, .line_size = 64, },
- [0x21] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+ [0x21] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
.associativity = 8, .line_size = 64, },
/* lines per sector is not supported cpuid2_cache_descriptor(),
* so descriptors 0x22, 0x23 are not included
*/
- [0x24] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0x24] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 16, .line_size = 64, },
/* lines per sector is not supported cpuid2_cache_descriptor(),
* so descriptors 0x25, 0x20 are not included
*/
- [0x2C] = { .level = 1, .type = DCACHE, .size = 32 * KiB,
+ [0x2C] = { .level = 1, .type = DATA_CACHE, .size = 32 * KiB,
.associativity = 8, .line_size = 64, },
- [0x30] = { .level = 1, .type = ICACHE, .size = 32 * KiB,
+ [0x30] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 32 * KiB,
.associativity = 8, .line_size = 64, },
- [0x41] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+ [0x41] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
.associativity = 4, .line_size = 32, },
- [0x42] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+ [0x42] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
.associativity = 4, .line_size = 32, },
- [0x43] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0x43] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 4, .line_size = 32, },
- [0x44] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0x44] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 4, .line_size = 32, },
- [0x45] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0x45] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 4, .line_size = 32, },
- [0x46] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
+ [0x46] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
.associativity = 4, .line_size = 64, },
- [0x47] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
+ [0x47] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
.associativity = 8, .line_size = 64, },
- [0x48] = { .level = 2, .type = UNIFIED_CACHE, .size = 3 * MiB,
+ [0x48] = { .level = 2, .type = UNIFIED_CACHE, .size = 3 * MiB,
.associativity = 12, .line_size = 64, },
/* Descriptor 0x49 depends on CPU family/model, so it is not included */
- [0x4A] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
+ [0x4A] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
.associativity = 12, .line_size = 64, },
- [0x4B] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
+ [0x4B] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
.associativity = 16, .line_size = 64, },
- [0x4C] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
+ [0x4C] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
.associativity = 12, .line_size = 64, },
- [0x4D] = { .level = 3, .type = UNIFIED_CACHE, .size = 16 * MiB,
+ [0x4D] = { .level = 3, .type = UNIFIED_CACHE, .size = 16 * MiB,
.associativity = 16, .line_size = 64, },
- [0x4E] = { .level = 2, .type = UNIFIED_CACHE, .size = 6 * MiB,
+ [0x4E] = { .level = 2, .type = UNIFIED_CACHE, .size = 6 * MiB,
.associativity = 24, .line_size = 64, },
- [0x60] = { .level = 1, .type = DCACHE, .size = 16 * KiB,
+ [0x60] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
.associativity = 8, .line_size = 64, },
- [0x66] = { .level = 1, .type = DCACHE, .size = 8 * KiB,
+ [0x66] = { .level = 1, .type = DATA_CACHE, .size = 8 * KiB,
.associativity = 4, .line_size = 64, },
- [0x67] = { .level = 1, .type = DCACHE, .size = 16 * KiB,
+ [0x67] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
.associativity = 4, .line_size = 64, },
- [0x68] = { .level = 1, .type = DCACHE, .size = 32 * KiB,
+ [0x68] = { .level = 1, .type = DATA_CACHE, .size = 32 * KiB,
.associativity = 4, .line_size = 64, },
- [0x78] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0x78] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 4, .line_size = 64, },
/* lines per sector is not supported cpuid2_cache_descriptor(),
* so descriptors 0x79, 0x7A, 0x7B, 0x7C are not included.
*/
- [0x7D] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0x7D] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 8, .line_size = 64, },
- [0x7F] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0x7F] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 2, .line_size = 64, },
- [0x80] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0x80] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 8, .line_size = 64, },
- [0x82] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+ [0x82] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
.associativity = 8, .line_size = 32, },
- [0x83] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0x83] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 8, .line_size = 32, },
- [0x84] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0x84] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 8, .line_size = 32, },
- [0x85] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0x85] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 8, .line_size = 32, },
- [0x86] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0x86] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 4, .line_size = 64, },
- [0x87] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0x87] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 8, .line_size = 64, },
- [0xD0] = { .level = 3, .type = UNIFIED_CACHE, .size = 512 * KiB,
+ [0xD0] = { .level = 3, .type = UNIFIED_CACHE, .size = 512 * KiB,
.associativity = 4, .line_size = 64, },
- [0xD1] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0xD1] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 4, .line_size = 64, },
- [0xD2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0xD2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 4, .line_size = 64, },
- [0xD6] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
+ [0xD6] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
.associativity = 8, .line_size = 64, },
- [0xD7] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0xD7] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 8, .line_size = 64, },
- [0xD8] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
+ [0xD8] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
.associativity = 8, .line_size = 64, },
- [0xDC] = { .level = 3, .type = UNIFIED_CACHE, .size = 1.5 * MiB,
+ [0xDC] = { .level = 3, .type = UNIFIED_CACHE, .size = 1.5 * MiB,
.associativity = 12, .line_size = 64, },
- [0xDD] = { .level = 3, .type = UNIFIED_CACHE, .size = 3 * MiB,
+ [0xDD] = { .level = 3, .type = UNIFIED_CACHE, .size = 3 * MiB,
.associativity = 12, .line_size = 64, },
- [0xDE] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
+ [0xDE] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
.associativity = 12, .line_size = 64, },
- [0xE2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
+ [0xE2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
.associativity = 16, .line_size = 64, },
- [0xE3] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
+ [0xE3] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
.associativity = 16, .line_size = 64, },
- [0xE4] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
+ [0xE4] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
.associativity = 16, .line_size = 64, },
- [0xEA] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
+ [0xEA] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
.associativity = 24, .line_size = 64, },
- [0xEB] = { .level = 3, .type = UNIFIED_CACHE, .size = 18 * MiB,
+ [0xEB] = { .level = 3, .type = UNIFIED_CACHE, .size = 18 * MiB,
.associativity = 24, .line_size = 64, },
- [0xEC] = { .level = 3, .type = UNIFIED_CACHE, .size = 24 * MiB,
+ [0xEC] = { .level = 3, .type = UNIFIED_CACHE, .size = 24 * MiB,
.associativity = 24, .line_size = 64, },
};
#define CACHE_COMPLEX_IDX (1 << 2)
/* Encode CacheType for CPUID[4].EAX */
-#define CACHE_TYPE(t) (((t) == DCACHE) ? CACHE_TYPE_D : \
- ((t) == ICACHE) ? CACHE_TYPE_I : \
- ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
- 0 /* Invalid value */)
+#define CACHE_TYPE(t) (((t) == DATA_CACHE) ? CACHE_TYPE_D : \
+ ((t) == INSTRUCTION_CACHE) ? CACHE_TYPE_I : \
+ ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
+ 0 /* Invalid value */)
/* Encode cache info for CPUID[4] */
uint32_t *ecx, uint32_t *edx)
{
struct core_topology topo = {0};
+ unsigned long nodes;
+ int shift;
build_core_topology(cs->nr_cores, cpu->core_id, &topo);
*eax = cpu->apic_id;
* 2 Socket id
* 1:0 Node id
*/
- *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << 2) | topo.node_id;
+ if (topo.num_nodes <= 4) {
+ *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << 2) |
+ topo.node_id;
+ } else {
+ /*
+ * Node id fix up. Actual hardware supports up to 4 nodes. But with
+ * more than 32 cores, we may end up with more than 4 nodes.
+ * Node id is a combination of socket id and node id. Only requirement
+ * here is that this number should be unique accross the system.
+ * Shift the socket id to accommodate more nodes. We dont expect both
+ * socket id and node id to be big number at the same time. This is not
+ * an ideal config but we need to to support it. Max nodes we can have
+ * is 32 (255/8) with 8 cores per node and 255 max cores. We only need
+ * 5 bits for nodes. Find the left most set bit to represent the total
+ * number of nodes. find_last_bit returns last set bit(0 based). Left
+ * shift(+1) the socket id to represent all the nodes.
+ */
+ nodes = topo.num_nodes - 1;
+ shift = find_last_bit(&nodes, 8);
+ *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << (shift + 1)) |
+ topo.node_id;
+ }
*edx = 0;
}
/* L1 data cache: */
static CPUCacheInfo legacy_l1d_cache = {
- .type = DCACHE,
+ .type = DATA_CACHE,
.level = 1,
.size = 32 * KiB,
.self_init = 1,
/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
static CPUCacheInfo legacy_l1d_cache_amd = {
- .type = DCACHE,
+ .type = DATA_CACHE,
.level = 1,
.size = 64 * KiB,
.self_init = 1,
/* L1 instruction cache: */
static CPUCacheInfo legacy_l1i_cache = {
- .type = ICACHE,
+ .type = INSTRUCTION_CACHE,
.level = 1,
.size = 32 * KiB,
.self_init = 1,
/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
static CPUCacheInfo legacy_l1i_cache_amd = {
- .type = ICACHE,
+ .type = INSTRUCTION_CACHE,
.level = 1,
.size = 64 * KiB,
.self_init = 1,
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
#define TCG_EXT4_FEATURES 0
-#define TCG_SVM_FEATURES 0
+#define TCG_SVM_FEATURES CPUID_SVM_NPT
#define TCG_KVM_FEATURES 0
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
CPUID_7_0_EBX_RDSEED */
-#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | \
+#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
+ /* CPUID_7_0_ECX_OSPKE is dynamic */ \
CPUID_7_0_ECX_LA57)
#define TCG_7_0_EDX_FEATURES 0
#define TCG_APM_FEATURES 0
[FEAT_7_0_ECX] = {
.feat_names = {
NULL, "avx512vbmi", "umip", "pku",
- "ospke", NULL, "avx512vbmi2", NULL,
+ NULL /* ospke */, NULL, "avx512vbmi2", NULL,
"gfni", "vaes", "vpclmulqdq", "avx512vnni",
"avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
"la57", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, NULL, "pconfig", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "spec-ctrl", NULL,
- NULL, NULL, NULL, "ssbd",
+ NULL, "arch-capabilities", NULL, "ssbd",
},
.cpuid_eax = 7,
.cpuid_needs_ecx = true, .cpuid_ecx = 0,
.cpuid_reg = R_EDX,
.tcg_features = TCG_7_0_EDX_FEATURES,
+ .unmigratable_flags = CPUID_7_0_EDX_ARCH_CAPABILITIES,
},
[FEAT_8000_0007_EDX] = {
.feat_names = {
.feat_names = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, "wbnoinvd", NULL, NULL,
"ibpb", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, "virt-ssbd", NULL, NULL,
+ "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
NULL, NULL, NULL, NULL,
},
.cpuid_eax = 0x80000008,
static CPUCaches epyc_cache_info = {
.l1d_cache = &(CPUCacheInfo) {
- .type = DCACHE,
+ .type = DATA_CACHE,
.level = 1,
.size = 32 * KiB,
.line_size = 64,
.no_invd_sharing = true,
},
.l1i_cache = &(CPUCacheInfo) {
- .type = ICACHE,
+ .type = INSTRUCTION_CACHE,
.level = 1,
.size = 64 * KiB,
.line_size = 64,
.xlevel = 0x80000008,
.model_id = "Intel Xeon Processor (Skylake, IBRS)",
},
+ {
+ .name = "Icelake-Client",
+ .level = 0xd,
+ .vendor = CPUID_VENDOR_INTEL,
+ .family = 6,
+ .model = 126,
+ .stepping = 0,
+ .features[FEAT_1_EDX] =
+ CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+ CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+ CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+ CPUID_DE | CPUID_FP87,
+ .features[FEAT_1_ECX] =
+ CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+ CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+ CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+ CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+ CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+ CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+ .features[FEAT_8000_0001_EDX] =
+ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+ CPUID_EXT2_SYSCALL,
+ .features[FEAT_8000_0001_ECX] =
+ CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_WBNOINVD,
+ .features[FEAT_7_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_INVPCID |
+ CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
+ .features[FEAT_7_0_ECX] =
+ CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+ CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
+ .features[FEAT_7_0_EDX] =
+ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+ /* Missing: XSAVES (not supported by some Linux versions,
+ * including v4.1 to v4.12).
+ * KVM doesn't yet expose any XSAVES state save component,
+ * and the only one defined in Skylake (processor tracing)
+ * probably will block migration anyway.
+ */
+ .features[FEAT_XSAVE] =
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+ CPUID_XSAVE_XGETBV1,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
+ .xlevel = 0x80000008,
+ .model_id = "Intel Core Processor (Icelake)",
+ },
+ {
+ .name = "Icelake-Server",
+ .level = 0xd,
+ .vendor = CPUID_VENDOR_INTEL,
+ .family = 6,
+ .model = 134,
+ .stepping = 0,
+ .features[FEAT_1_EDX] =
+ CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+ CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+ CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+ CPUID_DE | CPUID_FP87,
+ .features[FEAT_1_ECX] =
+ CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+ CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+ CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+ CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+ CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+ CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+ .features[FEAT_8000_0001_EDX] =
+ CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
+ CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+ .features[FEAT_8000_0001_ECX] =
+ CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_WBNOINVD,
+ .features[FEAT_7_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_INVPCID |
+ CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
+ CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
+ CPUID_7_0_EBX_INTEL_PT,
+ .features[FEAT_7_0_ECX] =
+ CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+ CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
+ .features[FEAT_7_0_EDX] =
+ CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
+ CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+ /* Missing: XSAVES (not supported by some Linux versions,
+ * including v4.1 to v4.12).
+ * KVM doesn't yet expose any XSAVES state save component,
+ * and the only one defined in Skylake (processor tracing)
+ * probably will block migration anyway.
+ */
+ .features[FEAT_XSAVE] =
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+ CPUID_XSAVE_XGETBV1,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
+ .xlevel = 0x80000008,
+ .model_id = "Intel Xeon Processor (Icelake)",
+ },
{
.name = "KnightsMill",
.level = 0xd,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
- CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
+ CPUID_EXT3_TOPOEXT,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
- .xlevel = 0x8000000A,
+ .xlevel = 0x8000001E,
.model_id = "AMD EPYC Processor",
.cache_info = &epyc_cache_info,
},
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
- CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
+ CPUID_EXT3_TOPOEXT,
.features[FEAT_8000_0008_EBX] =
CPUID_8000_0008_EBX_IBPB,
.features[FEAT_7_0_EBX] =
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
- .xlevel = 0x8000000A,
+ .xlevel = 0x8000001E,
.model_id = "AMD EPYC Processor (with IBPB)",
.cache_info = &epyc_cache_info,
},
xcc->host_cpuid_required = true;
xcc->ordering = 8;
- if (kvm_enabled()) {
- xcc->model_description =
- "KVM processor with all supported host features ";
- } else if (hvf_enabled()) {
- xcc->model_description =
- "HVF processor with all supported host features ";
- }
+#if defined(CONFIG_KVM)
+ xcc->model_description =
+ "KVM processor with all supported host features ";
+#elif defined(CONFIG_HVF)
+ xcc->model_description =
+ "HVF processor with all supported host features ";
+#endif
}
static const TypeInfo host_x86_cpu_type_info = {
}
break;
case 5:
- /* mwait info: needed for Core compatibility */
- *eax = 0; /* Smallest monitor-line size in bytes */
- *ebx = 0; /* Largest monitor-line size in bytes */
- *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
- *edx = 0;
+ /* MONITOR/MWAIT Leaf */
+ *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */
+ *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */
+ *ecx = cpu->mwait.ecx; /* flags */
+ *edx = cpu->mwait.edx; /* mwait substates */
break;
case 6:
/* Thermal and Power Leaf */
Error *local_err = NULL;
static bool ht_warned;
- if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
- char *name = x86_cpu_class_get_model_name(xcc);
- error_setg(&local_err, "CPU model '%s' requires KVM", name);
- g_free(name);
- goto out;
+ if (xcc->host_cpuid_required) {
+ if (!accel_uses_host_cpuid()) {
+ char *name = x86_cpu_class_get_model_name(xcc);
+ error_setg(&local_err, "CPU model '%s' requires KVM", name);
+ g_free(name);
+ goto out;
+ }
+
+ if (enable_cpu_pm) {
+ host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
+ &cpu->mwait.ecx, &cpu->mwait.edx);
+ env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
+ }
}
+ /* mwait extended info: needed for Core compatibility */
+ /* We always wake on interrupt even if host does not have the capability */
+ cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
error_setg(errp, "apic-id property was not initialized properly");
return;
qemu_init_vcpu(cs);
- /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
- * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
- * based on inputs (sockets,cores,threads), it is still better to gives
+ /*
+ * Most Intel and certain AMD CPUs support hyperthreading. Even though QEMU
+ * fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
+ * based on inputs (sockets,cores,threads), it is still better to give
* users a warning.
*
* NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
* cs->nr_threads hasn't be populated yet and the checking is incorrect.
*/
- if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
- error_report("AMD CPU doesn't support hyperthreading. Please configure"
- " -smp options properly.");
+ if (IS_AMD_CPU(env) &&
+ !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
+ cs->nr_threads > 1 && !ht_warned) {
+ error_report("This family of AMD CPU doesn't support "
+ "hyperthreading(%d). Please configure -smp "
+ "options properly or try enabling topoext feature.",
+ cs->nr_threads);
ht_warned = true;
}
DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
+ DEFINE_PROP_BOOL("hv-tlbflush", X86CPU, hyperv_tlbflush, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
false),
DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
+ DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
+ true),
/*
* lecacy_cache defaults to true unless the CPU model provides its
* own cache information (see x86_cpu_load_def()).