Skip to content

Commit

Permalink
target/i386: add VMX features
Browse files Browse the repository at this point in the history
Add code to convert the VMX feature words back into MSR values,
allowing the user to enable/disable VMX features as they wish.  The same
infrastructure enables support for limiting VMX features in named
CPU models.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Oct 4, 2019
1 parent 49d51b8 commit 20a78b0
Show file tree
Hide file tree
Showing 3 changed files with 394 additions and 2 deletions.
225 changes: 225 additions & 0 deletions target/i386/cpu.c
Expand Up @@ -1232,6 +1232,163 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.index = MSR_IA32_CORE_CAPABILITY,
},
},

[FEAT_VMX_PROCBASED_CTLS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
NULL, NULL, "vmx-vintr-pending", "vmx-tsc-offset",
NULL, NULL, NULL, "vmx-hlt-exit",
NULL, "vmx-invlpg-exit", "vmx-mwait-exit", "vmx-rdpmc-exit",
"vmx-rdtsc-exit", NULL, NULL, "vmx-cr3-load-noexit",
"vmx-cr3-store-noexit", NULL, NULL, "vmx-cr8-load-exit",
"vmx-cr8-store-exit", "vmx-flexpriority", "vmx-vnmi-pending", "vmx-movdr-exit",
"vmx-io-exit", "vmx-io-bitmap", NULL, "vmx-mtf",
"vmx-msr-bitmap", "vmx-monitor-exit", "vmx-pause-exit", "vmx-secondary-ctls",
},
.msr = {
.index = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
}
},

[FEAT_VMX_SECONDARY_CTLS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
"vmx-apicv-xapic", "vmx-ept", "vmx-desc-exit", "vmx-rdtscp-exit",
"vmx-apicv-x2apic", "vmx-vpid", "vmx-wbinvd-exit", "vmx-unrestricted-guest",
"vmx-apicv-register", "vmx-apicv-vid", "vmx-ple", "vmx-rdrand-exit",
"vmx-invpcid-exit", "vmx-vmfunc", "vmx-shadow-vmcs", "vmx-encls-exit",
"vmx-rdseed-exit", "vmx-pml", NULL, NULL,
"vmx-xsaves", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_VMX_PROCBASED_CTLS2,
}
},

[FEAT_VMX_PINBASED_CTLS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
"vmx-intr-exit", NULL, NULL, "vmx-nmi-exit",
NULL, "vmx-vnmi", "vmx-preemption-timer", "vmx-posted-intr",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
}
},

[FEAT_VMX_EXIT_CTLS] = {
.type = MSR_FEATURE_WORD,
/*
* VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE is copied from
* the LM CPUID bit.
*/
.feat_names = {
NULL, NULL, "vmx-exit-nosave-debugctl", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL /* vmx-exit-host-addr-space-size */, NULL, NULL,
"vmx-exit-load-perf-global-ctrl", NULL, NULL, "vmx-exit-ack-intr",
NULL, NULL, "vmx-exit-save-pat", "vmx-exit-load-pat",
"vmx-exit-save-efer", "vmx-exit-load-efer",
"vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
}
},

[FEAT_VMX_ENTRY_CTLS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
NULL, NULL, "vmx-entry-noload-debugctl", NULL,
NULL, NULL, NULL, NULL,
NULL, "vmx-entry-ia32e-mode", NULL, NULL,
NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
"vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
}
},

[FEAT_VMX_MISC] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
NULL, NULL, NULL, NULL,
NULL, "vmx-store-lma", "vmx-activity-hlt", "vmx-activity-shutdown",
"vmx-activity-wait-sipi", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, "vmx-vmwrite-vmexit-fields", "vmx-zero-len-inject", NULL,
},
.msr = {
.index = MSR_IA32_VMX_MISC,
}
},

[FEAT_VMX_EPT_VPID_CAPS] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
"vmx-ept-execonly", NULL, NULL, NULL,
NULL, NULL, "vmx-page-walk-4", "vmx-page-walk-5",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"vmx-ept-2mb", "vmx-ept-1gb", NULL, NULL,
"vmx-invept", "vmx-eptad", "vmx-ept-advanced-exitinfo", NULL,
NULL, "vmx-invept-single-context", "vmx-invept-all-context", NULL,
NULL, NULL, NULL, NULL,
"vmx-invvpid", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"vmx-invvpid-single-addr", "vmx-invept-single-context",
"vmx-invvpid-all-context", "vmx-invept-single-context-noglobals",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_VMX_EPT_VPID_CAP,
}
},

[FEAT_VMX_BASIC] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
[54] = "vmx-ins-outs",
[55] = "vmx-true-ctls",
},
.msr = {
.index = MSR_IA32_VMX_BASIC,
},
/* Just to be safe - we don't support setting the MSEG version field. */
.no_autoenable_flags = MSR_VMX_BASIC_DUAL_MONITOR,
},

[FEAT_VMX_VMFUNC] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
[0] = "vmx-eptp-switching",
},
.msr = {
.index = MSR_IA32_VMX_VMFUNC,
}
},

};

typedef struct FeatureMask {
Expand All @@ -1252,6 +1409,74 @@ static FeatureDep feature_dependencies[] = {
.from = { FEAT_7_0_EDX, CPUID_7_0_EDX_CORE_CAPABILITY },
.to = { FEAT_CORE_CAPABILITY, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_PROCBASED_CTLS, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_PINBASED_CTLS, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_EXIT_CTLS, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_ENTRY_CTLS, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_MISC, ~0ull },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_VMX },
.to = { FEAT_VMX_BASIC, ~0ull },
},
{
.from = { FEAT_8000_0001_EDX, CPUID_EXT2_LM },
.to = { FEAT_VMX_ENTRY_CTLS, VMX_VM_ENTRY_IA32E_MODE },
},
{
.from = { FEAT_VMX_PROCBASED_CTLS, VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS },
.to = { FEAT_VMX_SECONDARY_CTLS, ~0ull },
},
{
.from = { FEAT_XSAVE, CPUID_XSAVE_XSAVES },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_XSAVES },
},
{
.from = { FEAT_1_ECX, CPUID_EXT_RDRAND },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_RDRAND_EXITING },
},
{
.from = { FEAT_7_0_EBX, CPUID_7_0_EBX_INVPCID },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_INVPCID },
},
{
.from = { FEAT_7_0_EBX, CPUID_7_0_EBX_RDSEED },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_RDSEED_EXITING },
},
{
.from = { FEAT_8000_0001_EDX, CPUID_EXT2_RDTSCP },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_RDTSCP },
},
{
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_EPT },
.to = { FEAT_VMX_EPT_VPID_CAPS, 0xffffffffull },
},
{
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_EPT },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST },
},
{
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_VPID },
.to = { FEAT_VMX_EPT_VPID_CAPS, 0xffffffffull << 32 },
},
{
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_VMFUNC },
.to = { FEAT_VMX_VMFUNC, ~0ull },
},
};

typedef struct X86RegisterInfo32 {
Expand Down
9 changes: 9 additions & 0 deletions target/i386/cpu.h
Expand Up @@ -518,6 +518,15 @@ typedef enum FeatureWord {
FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
FEAT_ARCH_CAPABILITIES,
FEAT_CORE_CAPABILITY,
FEAT_VMX_PROCBASED_CTLS,
FEAT_VMX_SECONDARY_CTLS,
FEAT_VMX_PINBASED_CTLS,
FEAT_VMX_EXIT_CTLS,
FEAT_VMX_ENTRY_CTLS,
FEAT_VMX_MISC,
FEAT_VMX_EPT_VPID_CAPS,
FEAT_VMX_BASIC,
FEAT_VMX_VMFUNC,
FEATURE_WORDS,
} FeatureWord;

Expand Down

0 comments on commit 20a78b0

Please sign in to comment.