FRED, i.e., the Intel flexible return and event delivery architecture, defines simple new transitions that change privilege level (ring transitions). The new transitions defined by the FRED architecture are FRED event delivery and, for returning from events, two FRED return instructions. FRED event delivery can effect a transition from ring 3 to ring 0, but it is used also to deliver events incident to ring 0. One FRED instruction (ERETU) effects a return from ring 0 to ring 3, while the other (ERETS) returns while remaining in ring 0. Collectively, FRED event delivery and the FRED return instructions are FRED transitions. In addition to these transitions, the FRED architecture defines a new instruction (LKGS) for managing the state of the GS segment register. The LKGS instruction can be used by 64-bit operating systems that do not use the new FRED transitions. Search for the latest FRED spec in most search engines with this search pattern: site:intel.com FRED (flexible return and event delivery) specification The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS. Add CPUID definitions for FRED/LKGS, and expose them to KVM guests only. Because FRED relies on LKGS, add it to feature dependency map. Tested-by: Shan Kang <shan.kang@xxxxxxxxx> Signed-off-by: Xin Li <xin3.li@xxxxxxxxx> --- target/i386/cpu.c | 6 +++++- target/i386/cpu.h | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ed72883bf3..59fdb2a01a 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -963,7 +963,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", NULL, NULL, "fzrm", "fsrs", "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, "fred", "lkgs", NULL, NULL, "amx-fp16", NULL, "avx-ifma", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1550,6 +1550,10 @@ static FeatureDep feature_dependencies[] = { .from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE }, .to = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG }, }, + { + .from = { FEAT_7_1_EAX, CPUID_7_1_EAX_LKGS }, + .to = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED }, + }, }; typedef struct X86RegisterInfo32 { diff --git a/target/i386/cpu.h b/target/i386/cpu.h index d3f377d48a..e2946f1d6b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -934,6 +934,10 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, #define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8) /* PREFETCHIT0/1 Instructions */ #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) +/* Flexible return and event delivery (FRED) */ +#define CPUID_7_1_EAX_FRED (1U << 17) +/* Load into IA32_KERNEL_GS_BASE (LKGS) */ +#define CPUID_7_1_EAX_LKGS (1U << 18) /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ #define CPUID_7_2_EDX_MCDT_NO (1U << 5) -- 2.34.1