For TDX, some CPUID feature bit is configured via TD attributes. They are not covered by tdx_caps.cpuid (which only contians the configurable bits), but they are actually supported when the related attributre bit is supported.
Signed-off-by: Xiaoyao Li <xiaoyao...@intel.com> --- target/i386/cpu.h | 4 +++ target/i386/kvm/tdx.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 115137279a1a..0e984ec42bb6 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -903,6 +903,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); #define CPUID_7_0_ECX_LA57 (1U << 16) /* Read Processor ID */ #define CPUID_7_0_ECX_RDPID (1U << 22) +/* KeyLocker */ +#define CPUID_7_0_ECX_KeyLocker (1U << 23) /* Bus Lock Debug Exception */ #define CPUID_7_0_ECX_BUS_LOCK_DETECT (1U << 24) /* Cache Line Demote Instruction */ @@ -963,6 +965,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) /* AVX512 BFloat16 Instruction */ #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) +/* Linear address space separation */ +#define CPUID_7_1_EAX_LASS (1U << 6) /* CMPCCXADD Instructions */ #define CPUID_7_1_EAX_CMPCCXADD (1U << 7) /* Fast Zero REP MOVS */ diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 49a94d8ffe7d..5d72f1814606 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -458,6 +458,33 @@ KvmCpuidInfo tdx_fixed1_bits = { }, }; +typedef struct TdxAttrsMap { + uint32_t attr_index; + uint32_t cpuid_leaf; + uint32_t cpuid_subleaf; + int cpuid_reg; + uint32_t feat_mask; +} TdxAttrsMap; + +static TdxAttrsMap tdx_attrs_maps[] = { + {.attr_index = 27, + .cpuid_leaf = 7, + .cpuid_subleaf = 1, + .cpuid_reg = R_EAX, + .feat_mask = CPUID_7_1_EAX_LASS}, + {.attr_index = 30, + .cpuid_leaf = 7, + .cpuid_subleaf = 0, + .cpuid_reg = R_ECX, + .feat_mask = CPUID_7_0_ECX_PKS,}, + {.attr_index = 31, + .cpuid_leaf = 7, + .cpuid_subleaf = 0, + .cpuid_reg = R_ECX, + .feat_mask = CPUID_7_0_ECX_KeyLocker, + }, +}; + static struct kvm_cpuid_entry2 *find_in_supported_entry(uint32_t function, uint32_t index) { @@ -494,6 +521,37 @@ static void tdx_add_supported_cpuid_by_fixed1_bits(void) } } +static void tdx_add_supported_cpuid_by_attrs(void) +{ + struct kvm_cpuid_entry2 *e; + TdxAttrsMap *map; + int i; + + for (i = 0; i < ARRAY_SIZE(tdx_attrs_maps); i++) { + map = &tdx_attrs_maps[i]; + if (!((1ULL << map->attr_index) & tdx_caps->supported_attrs)) { + continue; + } + + e = find_in_supported_entry(map->cpuid_leaf, map->cpuid_subleaf); + + switch(map->cpuid_reg) { + case R_EAX: + e->eax |= map->feat_mask; + break; + case R_EBX: + e->ebx |= map->feat_mask; + break; + case R_ECX: + e->ecx |= map->feat_mask; + break; + case R_EDX: + e->edx |= map->feat_mask; + break; + } + } +} + static void tdx_setup_supported_cpuid(void) { if (tdx_supported_cpuid) { @@ -508,6 +566,7 @@ static void tdx_setup_supported_cpuid(void) tdx_supported_cpuid->nent = tdx_caps->cpuid.nent; tdx_add_supported_cpuid_by_fixed1_bits(); + tdx_add_supported_cpuid_by_attrs(); } static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -- 2.34.1