From e3d01bc57e471dec972a0a40cf83df746322dda9 Mon Sep 17 00:00:00 2001 From: Huaitong Han Date: Mon, 19 Feb 2018 00:06:41 -0500 Subject: [PATCH] target-i386: Add PKU and and OSPKE support Add PKU and OSPKE CPUID features, including xsave state and migration support. Backports commit f74eefe0b98cd7e13825de8e8d9f32e22aed102c from qemu --- qemu/target-i386/cpu.c | 75 +++++++++++++++++++++++++++++++++++++++++- qemu/target-i386/cpu.h | 7 ++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index 19aa2bcf..5d82eda6 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -230,6 +230,17 @@ static const char *cpuid_7_0_ebx_feature_name[] = { "clwb", NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL, }; +static const char *cpuid_7_0_ecx_feature_name[] = { + NULL, NULL, NULL, "pku", + "ospke", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +}; + static const char *cpuid_apm_edx_feature_name[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -319,6 +330,7 @@ static const char *cpuid_6_feature_name[] = { CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2, CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM, CPUID_7_0_EBX_RDSEED */ +#define TCG_7_0_ECX_FEATURES 0 #define TCG_APM_FEATURES 0 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT @@ -359,6 +371,14 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { R_EBX, TCG_7_0_EBX_FEATURES, }, + // FEAT_7_0_ECX + { + cpuid_7_0_ecx_feature_name, + 7, + true, 0, + R_ECX, + TCG_7_0_ECX_FEATURES, + }, // FEAT_8000_0001_EDX { ext2_feature_name, @@ -446,6 +466,13 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .cpuid_reg = R_EBX, .tcg_features = TCG_7_0_EBX_FEATURES, }, + [FEAT_7_0_ECX] = { + .feat_names = cpuid_7_0_ecx_feature_name, + .cpuid_eax = 7, + .cpuid_needs_ecx = true, .cpuid_ecx = 0, + .cpuid_reg = R_ECX, + .tcg_features = TCG_7_0_ECX_FEATURES, + }, [FEAT_8000_0007_EDX] = { .feat_names = cpuid_apm_edx_feature_name, .cpuid_eax = 0x80000007, @@ -682,6 +709,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3 | CPUID_EXT_CX16, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, // FEAT_8000_0001_ECX @@ -704,6 +733,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_POPCNT, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | @@ -745,6 +776,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_CX16, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, // FEAT_8000_0001_ECX @@ -768,6 +801,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3 | CPUID_EXT_CX16, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, @@ -805,6 +840,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX // FEAT_8000_0001_ECX 0, @@ -828,6 +865,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3 | CPUID_EXT_MONITOR, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_NX, }, @@ -886,6 +925,8 @@ static X86CPUDefinition builtin_x86_defs[] = { 0, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, }, @@ -909,6 +950,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_MOVBE, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_NX, // FEAT_8000_0001_ECX @@ -932,6 +975,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, // FEAT_8000_0001_ECX @@ -956,6 +1001,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, // FEAT_8000_0001_ECX @@ -980,6 +1027,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, // FEAT_8000_0001_ECX @@ -1005,6 +1054,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, // FEAT_8000_0001_ECX @@ -1044,6 +1095,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1085,6 +1138,8 @@ static X86CPUDefinition builtin_x86_defs[] = { // FEAT_7_0_EBX CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_ERMS, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1128,6 +1183,8 @@ static X86CPUDefinition builtin_x86_defs[] = { 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_ERMS | CPUID_7_0_EBX_INVPCID, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1172,6 +1229,8 @@ static X86CPUDefinition builtin_x86_defs[] = { 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, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1217,6 +1276,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1262,6 +1323,8 @@ static X86CPUDefinition builtin_x86_defs[] = { 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, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, @@ -1298,6 +1361,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | @@ -1324,6 +1389,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_CX16 | CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | @@ -1354,6 +1421,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | @@ -1387,6 +1456,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | @@ -1422,6 +1493,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, // FEAT_7_0_EBX 0, + // FEAT_7_0_ECX + 0, // FEAT_8000_0001_EDX CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | @@ -2221,7 +2294,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, if (count == 0) { *eax = 0; /* Maximum ECX value for sub-leaves */ *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */ - *ecx = 0; /* Reserved */ + *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */ *edx = 0; /* Reserved */ } else { *eax = 0; diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index 602a7f10..d73d660e 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -404,6 +404,7 @@ #define XSTATE_OPMASK (1ULL << 5) #define XSTATE_ZMM_Hi256 (1ULL << 6) #define XSTATE_Hi16_ZMM (1ULL << 7) +#define XSTATE_PKRU (1ULL << 9) /* CPUID feature words */ @@ -411,6 +412,7 @@ typedef enum FeatureWord { FEAT_1_EDX, /* CPUID[1].EDX */ FEAT_1_ECX, /* CPUID[1].ECX */ FEAT_7_0_EBX, /* CPUID[EAX=7,ECX=0].EBX */ + FEAT_7_0_ECX, /* CPUID[EAX=7,ECX=0].ECX */ FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */ FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */ FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */ @@ -582,6 +584,9 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */ #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */ +#define CPUID_7_0_ECX_PKU (1U << 3) +#define CPUID_7_0_ECX_OSPKE (1U << 4) + #define CPUID_XSAVE_XSAVEOPT (1U << 0) #define CPUID_XSAVE_XSAVEC (1U << 1) #define CPUID_XSAVE_XGETBV1 (1U << 2) @@ -987,6 +992,8 @@ typedef struct CPUX86State { uint64_t xcr0; uint64_t xss; + uint32_t pkru; + TPRAccess tpr_access_type; // Unicorn engine