diff --git a/i386-cpu-Don-t-add-unavailable_features-to-env-user_.patch b/i386-cpu-Don-t-add-unavailable_features-to-env-user_.patch new file mode 100644 index 0000000000000000000000000000000000000000..3e42e71e5d9e2d038d4540fa0b57b87adcbf92d7 --- /dev/null +++ b/i386-cpu-Don-t-add-unavailable_features-to-env-user_.patch @@ -0,0 +1,33 @@ +From e6f3e08acd55d13cbb154ff8abb1b3c2ed658285 Mon Sep 17 00:00:00 2001 +From: Xiaoyao Li +Date: Tue, 14 Jul 2020 01:44:36 +0800 +Subject: [PATCH] i386/cpu: Don't add unavailable_features to + env->user_features + +Features unavailable due to absent of their dependent features should +not be added to env->user_features. env->user_features only contains the +feature explicity specified with -feature/+feature by user. + +Fixes: 99e24dbdaa68 ("target/i386: introduce generic feature dependency mechanism") +Signed-off-by: Xiaoyao Li +Message-Id: <20200713174436.41070-3-xiaoyao.li@intel.com> +Signed-off-by: Eduardo Habkost +--- + target/i386/cpu.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 6f27a5170a..e0f3a2dd99 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6173,7 +6173,6 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + unavailable_features & env->user_features[d->to.index], + "This feature depends on other features that were not requested"); + +- env->user_features[d->to.index] |= unavailable_features; + env->features[d->to.index] &= ~unavailable_features; + } + } +-- +2.27.0 + diff --git a/migration-Make-sure-that-we-don-t-call-write-in-case.patch b/migration-Make-sure-that-we-don-t-call-write-in-case.patch new file mode 100644 index 0000000000000000000000000000000000000000..73e3fe41d0ee74e22d7e5434ca89b421bbce0708 --- /dev/null +++ b/migration-Make-sure-that-we-don-t-call-write-in-case.patch @@ -0,0 +1,94 @@ +From 2898f8669445d38d4a6a8986c1e6d94381a7e869 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 3 Mar 2020 14:51:35 +0000 +Subject: [PATCH] migration: Make sure that we don't call write() in case of + error + +RH-Author: Juan Quintela +Message-id: <20200303145143.149290-3-quintela@redhat.com> +Patchwork-id: 94113 +O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 02/10] migration: Make sure that we don't call write() in case of error +Bugzilla: 1738451 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Peter Xu +RH-Acked-by: Dr. David Alan Gilbert + +If we are exiting due to an error/finish/.... Just don't try to even +touch the channel with one IO operation. + +Signed-off-by: Juan Quintela +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Juan Quintela +(cherry picked from commit 4d65a6216bfc44891ac298b74a6921d479805131) +Signed-off-by: Danilo C. L. de Paula +--- + migration/ram.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index d4ac696899..27585a4f3e 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1195,6 +1195,12 @@ struct { + uint64_t packet_num; + /* send channels ready */ + QemuSemaphore channels_ready; ++ /* ++ * Have we already run terminate threads. There is a race when it ++ * happens that we got one error while we are exiting. ++ * We will use atomic operations. Only valid values are 0 and 1. ++ */ ++ int exiting; + } *multifd_send_state; + + /* +@@ -1223,6 +1229,10 @@ static int multifd_send_pages(RAMState *rs) + MultiFDPages_t *pages = multifd_send_state->pages; + uint64_t transferred; + ++ if (atomic_read(&multifd_send_state->exiting)) { ++ return -1; ++ } ++ + qemu_sem_wait(&multifd_send_state->channels_ready); + /* + * next_channel can remain from a previous migration that was +@@ -1308,6 +1318,16 @@ static void multifd_send_terminate_threads(Error *err) + } + } + ++ /* ++ * We don't want to exit each threads twice. Depending on where ++ * we get the error, or if there are two independent errors in two ++ * threads at the same time, we can end calling this function ++ * twice. ++ */ ++ if (atomic_xchg(&multifd_send_state->exiting, 1)) { ++ return; ++ } ++ + for (i = 0; i < migrate_multifd_channels(); i++) { + MultiFDSendParams *p = &multifd_send_state->params[i]; + +@@ -1425,6 +1445,10 @@ static void *multifd_send_thread(void *opaque) + + while (true) { + qemu_sem_wait(&p->sem); ++ ++ if (atomic_read(&multifd_send_state->exiting)) { ++ break; ++ } + qemu_mutex_lock(&p->mutex); + + if (p->pending_job) { +@@ -1655,6 +1679,7 @@ int multifd_save_setup(void) + multifd_send_state->params = g_new0(MultiFDSendParams, thread_count); + multifd_send_state->pages = multifd_pages_init(page_count); + qemu_sem_init(&multifd_send_state->channels_ready, 0); ++ atomic_set(&multifd_send_state->exiting, 0); + + for (i = 0; i < thread_count; i++) { + MultiFDSendParams *p = &multifd_send_state->params[i]; +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 709632d7765154adfe528f13fa32869d77d538c8..93457c6aa58a1c56d9565852c9f1e916c27e6faf 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 64 +Release: 65 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -353,6 +353,19 @@ Patch0340: crypto-add-support-for-nettle-s-native-XTS-impl.patch Patch0341: crypto-add-support-for-gcrypt-s-native-XTS-impl.patch Patch0342: tests-benchmark-crypto-with-fixed-data-size-not-time.patch Patch0343: tests-allow-filtering-crypto-cipher-benchmark-tests.patch +Patch0344: target-i386-handle-filtered_features-in-a-new-functi.patch +Patch0345: target-i386-introduce-generic-feature-dependency-mec.patch +Patch0346: target-i386-expand-feature-words-to-64-bits.patch +Patch0347: target-i386-add-VMX-definitions.patch +Patch0348: vmxcap-correct-the-name-of-the-variables.patch +Patch0349: target-i386-add-VMX-features.patch +Patch0350: target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch +Patch0351: target-i386-add-VMX-features-to-named-CPU-models.patch +Patch0352: target-i386-add-two-missing-VMX-features-for-Skylake.patch +Patch0353: target-i386-disable-VMX-features-if-nested-0.patch +Patch0354: i386-cpu-Don-t-add-unavailable_features-to-env-user_.patch +Patch0355: target-i386-do-not-set-unsupported-VMX-secondary-exe.patch +Patch0356: migration-Make-sure-that-we-don-t-call-write-in-case.patch BuildRequires: flex BuildRequires: gcc @@ -747,6 +760,21 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Wed Jul 21 2021 Chen Qun +- target/i386: handle filtered_features in a new function mark_unavailable_features +- target/i386: introduce generic feature dependency mechanism +- target/i386: expand feature words to 64 bits +- target/i386: add VMX definitions +- vmxcap: correct the name of the variables +- target/i386: add VMX features +- target/i386: work around KVM_GET_MSRS bug for secondary execution controls +- target/i386: add VMX features to named CPU models +- target/i386: add two missing VMX features for Skylake and CascadeLake Server +- target/i386: disable VMX features if nested=0 +- i386/cpu: Don't add unavailable_features to env->user_features +- target/i386: do not set unsupported VMX secondary execution controls +- migration: Make sure that we don't call write() in case of error + * Tue Jul 20 2021 Chen Qun - crypto: add support for nettle's native XTS impl - crypto: add support for gcrypt's native XTS impl diff --git a/target-i386-add-VMX-definitions.patch b/target-i386-add-VMX-definitions.patch new file mode 100644 index 0000000000000000000000000000000000000000..4365e3a7a1082abf15b5e9c51a7c3801e27ee806 --- /dev/null +++ b/target-i386-add-VMX-definitions.patch @@ -0,0 +1,164 @@ +From 9fb16fc548fca297086be0efe20345160660f340 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2019 18:24:52 +0200 +Subject: [PATCH] target/i386: add VMX definitions + +These will be used to compile the list of VMX features for named +CPU models, and/or by the code that sets up the VMX MSRs. + +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 130 insertions(+) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 9a105b2251..b4be6ffb1f 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -452,6 +452,25 @@ typedef enum X86Seg { + #define MSR_IA32_BNDCFGS 0x00000d90 + #define MSR_IA32_XSS 0x00000da0 + ++#define MSR_IA32_VMX_BASIC 0x00000480 ++#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 ++#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 ++#define MSR_IA32_VMX_EXIT_CTLS 0x00000483 ++#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 ++#define MSR_IA32_VMX_MISC 0x00000485 ++#define MSR_IA32_VMX_CR0_FIXED0 0x00000486 ++#define MSR_IA32_VMX_CR0_FIXED1 0x00000487 ++#define MSR_IA32_VMX_CR4_FIXED0 0x00000488 ++#define MSR_IA32_VMX_CR4_FIXED1 0x00000489 ++#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a ++#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b ++#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c ++#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048d ++#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e ++#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048f ++#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 ++#define MSR_IA32_VMX_VMFUNC 0x00000491 ++ + #define XSTATE_FP_BIT 0 + #define XSTATE_SSE_BIT 1 + #define XSTATE_YMM_BIT 2 +@@ -757,6 +776,117 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; + + #define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5) + ++/* VMX MSR features */ ++#define MSR_VMX_BASIC_VMCS_REVISION_MASK 0x7FFFFFFFull ++#define MSR_VMX_BASIC_VMXON_REGION_SIZE_MASK (0x00001FFFull << 32) ++#define MSR_VMX_BASIC_VMCS_MEM_TYPE_MASK (0x003C0000ull << 32) ++#define MSR_VMX_BASIC_DUAL_MONITOR (1ULL << 49) ++#define MSR_VMX_BASIC_INS_OUTS (1ULL << 54) ++#define MSR_VMX_BASIC_TRUE_CTLS (1ULL << 55) ++ ++#define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK 0x1Full ++#define MSR_VMX_MISC_STORE_LMA (1ULL << 5) ++#define MSR_VMX_MISC_ACTIVITY_HLT (1ULL << 6) ++#define MSR_VMX_MISC_ACTIVITY_SHUTDOWN (1ULL << 7) ++#define MSR_VMX_MISC_ACTIVITY_WAIT_SIPI (1ULL << 8) ++#define MSR_VMX_MISC_MAX_MSR_LIST_SIZE_MASK 0x0E000000ull ++#define MSR_VMX_MISC_VMWRITE_VMEXIT (1ULL << 29) ++#define MSR_VMX_MISC_ZERO_LEN_INJECT (1ULL << 30) ++ ++#define MSR_VMX_EPT_EXECONLY (1ULL << 0) ++#define MSR_VMX_EPT_PAGE_WALK_LENGTH_4 (1ULL << 6) ++#define MSR_VMX_EPT_PAGE_WALK_LENGTH_5 (1ULL << 7) ++#define MSR_VMX_EPT_UC (1ULL << 8) ++#define MSR_VMX_EPT_WB (1ULL << 14) ++#define MSR_VMX_EPT_2MB (1ULL << 16) ++#define MSR_VMX_EPT_1GB (1ULL << 17) ++#define MSR_VMX_EPT_INVEPT (1ULL << 20) ++#define MSR_VMX_EPT_AD_BITS (1ULL << 21) ++#define MSR_VMX_EPT_ADVANCED_VMEXIT_INFO (1ULL << 22) ++#define MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT (1ULL << 25) ++#define MSR_VMX_EPT_INVEPT_ALL_CONTEXT (1ULL << 26) ++#define MSR_VMX_EPT_INVVPID (1ULL << 32) ++#define MSR_VMX_EPT_INVVPID_SINGLE_ADDR (1ULL << 40) ++#define MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT (1ULL << 41) ++#define MSR_VMX_EPT_INVVPID_ALL_CONTEXT (1ULL << 42) ++#define MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS (1ULL << 43) ++ ++#define MSR_VMX_VMFUNC_EPT_SWITCHING (1ULL << 0) ++ ++ ++/* VMX controls */ ++#define VMX_CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 ++#define VMX_CPU_BASED_USE_TSC_OFFSETING 0x00000008 ++#define VMX_CPU_BASED_HLT_EXITING 0x00000080 ++#define VMX_CPU_BASED_INVLPG_EXITING 0x00000200 ++#define VMX_CPU_BASED_MWAIT_EXITING 0x00000400 ++#define VMX_CPU_BASED_RDPMC_EXITING 0x00000800 ++#define VMX_CPU_BASED_RDTSC_EXITING 0x00001000 ++#define VMX_CPU_BASED_CR3_LOAD_EXITING 0x00008000 ++#define VMX_CPU_BASED_CR3_STORE_EXITING 0x00010000 ++#define VMX_CPU_BASED_CR8_LOAD_EXITING 0x00080000 ++#define VMX_CPU_BASED_CR8_STORE_EXITING 0x00100000 ++#define VMX_CPU_BASED_TPR_SHADOW 0x00200000 ++#define VMX_CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 ++#define VMX_CPU_BASED_MOV_DR_EXITING 0x00800000 ++#define VMX_CPU_BASED_UNCOND_IO_EXITING 0x01000000 ++#define VMX_CPU_BASED_USE_IO_BITMAPS 0x02000000 ++#define VMX_CPU_BASED_MONITOR_TRAP_FLAG 0x08000000 ++#define VMX_CPU_BASED_USE_MSR_BITMAPS 0x10000000 ++#define VMX_CPU_BASED_MONITOR_EXITING 0x20000000 ++#define VMX_CPU_BASED_PAUSE_EXITING 0x40000000 ++#define VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000 ++ ++#define VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 ++#define VMX_SECONDARY_EXEC_ENABLE_EPT 0x00000002 ++#define VMX_SECONDARY_EXEC_DESC 0x00000004 ++#define VMX_SECONDARY_EXEC_RDTSCP 0x00000008 ++#define VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010 ++#define VMX_SECONDARY_EXEC_ENABLE_VPID 0x00000020 ++#define VMX_SECONDARY_EXEC_WBINVD_EXITING 0x00000040 ++#define VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 ++#define VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100 ++#define VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200 ++#define VMX_SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 ++#define VMX_SECONDARY_EXEC_RDRAND_EXITING 0x00000800 ++#define VMX_SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 ++#define VMX_SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000 ++#define VMX_SECONDARY_EXEC_SHADOW_VMCS 0x00004000 ++#define VMX_SECONDARY_EXEC_ENCLS_EXITING 0x00008000 ++#define VMX_SECONDARY_EXEC_RDSEED_EXITING 0x00010000 ++#define VMX_SECONDARY_EXEC_ENABLE_PML 0x00020000 ++#define VMX_SECONDARY_EXEC_XSAVES 0x00100000 ++ ++#define VMX_PIN_BASED_EXT_INTR_MASK 0x00000001 ++#define VMX_PIN_BASED_NMI_EXITING 0x00000008 ++#define VMX_PIN_BASED_VIRTUAL_NMIS 0x00000020 ++#define VMX_PIN_BASED_VMX_PREEMPTION_TIMER 0x00000040 ++#define VMX_PIN_BASED_POSTED_INTR 0x00000080 ++ ++#define VMX_VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000004 ++#define VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200 ++#define VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000 ++#define VMX_VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 ++#define VMX_VM_EXIT_SAVE_IA32_PAT 0x00040000 ++#define VMX_VM_EXIT_LOAD_IA32_PAT 0x00080000 ++#define VMX_VM_EXIT_SAVE_IA32_EFER 0x00100000 ++#define VMX_VM_EXIT_LOAD_IA32_EFER 0x00200000 ++#define VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000 ++#define VMX_VM_EXIT_CLEAR_BNDCFGS 0x00800000 ++#define VMX_VM_EXIT_PT_CONCEAL_PIP 0x01000000 ++#define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 ++ ++#define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004 ++#define VMX_VM_ENTRY_IA32E_MODE 0x00000200 ++#define VMX_VM_ENTRY_SMM 0x00000400 ++#define VMX_VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 ++#define VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000 ++#define VMX_VM_ENTRY_LOAD_IA32_PAT 0x00004000 ++#define VMX_VM_ENTRY_LOAD_IA32_EFER 0x00008000 ++#define VMX_VM_ENTRY_LOAD_BNDCFGS 0x00010000 ++#define VMX_VM_ENTRY_PT_CONCEAL_PIP 0x00020000 ++#define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000 ++ + /* Supported Hyper-V Enlightenments */ + #define HYPERV_FEAT_RELAXED 0 + #define HYPERV_FEAT_VAPIC 1 +-- +2.27.0 + diff --git a/target-i386-add-VMX-features-to-named-CPU-models.patch b/target-i386-add-VMX-features-to-named-CPU-models.patch new file mode 100644 index 0000000000000000000000000000000000000000..ab42b83785e5e5fd463f64415611b98ebe06066b --- /dev/null +++ b/target-i386-add-VMX-features-to-named-CPU-models.patch @@ -0,0 +1,980 @@ +From 5a63a16d709c89b25a0a9c3c7fdf765f26dac312 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 20 Nov 2019 18:37:53 +0100 +Subject: [PATCH] target/i386: add VMX features to named CPU models + +This allows using "-cpu Haswell,+vmx", which we did not really want to +support in QEMU but was produced by Libvirt when using the "host-model" +CPU model. Without this patch, no VMX feature is _actually_ supported +(only the basic instruction set extensions are) and KVM fails to load +in the guest. + +This was produced from the output of scripts/kvm/vmxcap using the following +very ugly Python script: + + bits = { + 'INS/OUTS instruction information': ['FEAT_VMX_BASIC', 'MSR_VMX_BASIC_INS_OUTS'], + 'IA32_VMX_TRUE_*_CTLS support': ['FEAT_VMX_BASIC', 'MSR_VMX_BASIC_TRUE_CTLS'], + 'External interrupt exiting': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_EXT_INTR_MASK'], + 'NMI exiting': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_NMI_EXITING'], + 'Virtual NMIs': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_VIRTUAL_NMIS'], + 'Activate VMX-preemption timer': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_VMX_PREEMPTION_TIMER'], + 'Process posted interrupts': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_POSTED_INTR'], + 'Interrupt window exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_VIRTUAL_INTR_PENDING'], + 'Use TSC offsetting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_TSC_OFFSETING'], + 'HLT exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_HLT_EXITING'], + 'INVLPG exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_INVLPG_EXITING'], + 'MWAIT exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MWAIT_EXITING'], + 'RDPMC exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_RDPMC_EXITING'], + 'RDTSC exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_RDTSC_EXITING'], + 'CR3-load exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR3_LOAD_EXITING'], + 'CR3-store exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR3_STORE_EXITING'], + 'CR8-load exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR8_LOAD_EXITING'], + 'CR8-store exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR8_STORE_EXITING'], + 'Use TPR shadow': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_TPR_SHADOW'], + 'NMI-window exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_VIRTUAL_NMI_PENDING'], + 'MOV-DR exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MOV_DR_EXITING'], + 'Unconditional I/O exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_UNCOND_IO_EXITING'], + 'Use I/O bitmaps': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_IO_BITMAPS'], + 'Monitor trap flag': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MONITOR_TRAP_FLAG'], + 'Use MSR bitmaps': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_MSR_BITMAPS'], + 'MONITOR exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MONITOR_EXITING'], + 'PAUSE exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_PAUSE_EXITING'], + 'Activate secondary control': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS'], + 'Virtualize APIC accesses': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES'], + 'Enable EPT': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_EPT'], + 'Descriptor-table exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_DESC'], + 'Enable RDTSCP': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDTSCP'], + 'Virtualize x2APIC mode': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE'], + 'Enable VPID': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_VPID'], + 'WBINVD exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_WBINVD_EXITING'], + 'Unrestricted guest': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST'], + 'APIC register emulation': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT'], + 'Virtual interrupt delivery': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY'], + 'PAUSE-loop exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_PAUSE_LOOP_EXITING'], + 'RDRAND exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDRAND_EXITING'], + 'Enable INVPCID': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_INVPCID'], + 'Enable VM functions': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_VMFUNC'], + 'VMCS shadowing': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_SHADOW_VMCS'], + 'RDSEED exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDSEED_EXITING'], + 'Enable PML': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_PML'], + 'Enable XSAVES/XRSTORS': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_XSAVES'], + 'Save debug controls': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_DEBUG_CONTROLS'], + 'Load IA32_PERF_GLOBAL_CTRL': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL'], + 'Acknowledge interrupt on exit': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_ACK_INTR_ON_EXIT'], + 'Save IA32_PAT': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_IA32_PAT'], + 'Load IA32_PAT': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_PAT'], + 'Save IA32_EFER': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_IA32_EFER'], + 'Load IA32_EFER': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_EFER'], + 'Save VMX-preemption timer value': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER'], + 'Clear IA32_BNDCFGS': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_CLEAR_BNDCFGS'], + 'Load debug controls': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS'], + 'IA-32e mode guest': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_IA32E_MODE'], + 'Load IA32_PERF_GLOBAL_CTRL': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL'], + 'Load IA32_PAT': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_PAT'], + 'Load IA32_EFER': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_EFER'], + 'Load IA32_BNDCFGS': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_BNDCFGS'], + 'Store EFER.LMA into IA-32e mode guest control': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_STORE_LMA'], + 'HLT activity state': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_ACTIVITY_HLT'], + 'VMWRITE to VM-exit information fields': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_VMWRITE_VMEXIT'], + 'Inject event with insn length=0': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_ZERO_LEN_INJECT'], + 'Execute-only EPT translations': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_EXECONLY'], + 'Page-walk length 4': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_PAGE_WALK_LENGTH_4'], + 'Paging-structure memory type WB': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_WB'], + '2MB EPT pages': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB'], + 'INVEPT supported': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT'], + 'EPT accessed and dirty flags': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_AD_BITS'], + 'Single-context INVEPT': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT'], + 'All-context INVEPT': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT_ALL_CONTEXT'], + 'INVVPID supported': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID'], + 'Individual-address INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_ADDR'], + 'Single-context INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT'], + 'All-context INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_ALL_CONTEXT'], + 'Single-context-retaining-globals INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS'], + 'EPTP Switching': ['FEAT_VMX_VMFUNC', 'MSR_VMX_VMFUNC_EPT_SWITCHING'] + } + + import sys + import textwrap + + out = {} + for l in sys.stdin.readlines(): + l = l.rstrip() + if l.endswith('!!'): + l = l[:-2].rstrip() + if l.startswith(' ') and (l.endswith('default') or l.endswith('yes')): + l = l[4:] + for key, value in bits.items(): + if l.startswith(key): + ctl, bit = value + if ctl in out: + out[ctl] = out[ctl] + ' | ' + else: + out[ctl] = ' [%s] = ' % ctl + out[ctl] = out[ctl] + bit + + for x in sorted(out.keys()): + print("\n ".join(textwrap.wrap(out[x] + ","))) + +Note that the script has a bug in that some keys apply to both VM entry +and VM exit controls ("load IA32_PERF_GLOBAL_CTRL", "load IA32_EFER", +"load IA32_PAT". Those have to be fixed by hand. + +Reviewed-by: Eduardo Habkost +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 705 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 705 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index fd248a78db..2f32d67aa5 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1799,6 +1799,34 @@ static CPUCaches epyc_cache_info = { + }, + }; + ++/* The following VMX features are not supported by KVM and are left out in the ++ * CPU definitions: ++ * ++ * Dual-monitor support (all processors) ++ * Entry to SMM ++ * Deactivate dual-monitor treatment ++ * Number of CR3-target values ++ * Shutdown activity state ++ * Wait-for-SIPI activity state ++ * PAUSE-loop exiting (Westmere and newer) ++ * EPT-violation #VE (Broadwell and newer) ++ * Inject event with insn length=0 (Skylake and newer) ++ * Conceal non-root operation from PT ++ * Conceal VM exits from PT ++ * Conceal VM entries from PT ++ * Enable ENCLS exiting ++ * Mode-based execute control (XS/XU) ++ s TSC scaling (Skylake Server and newer) ++ * GPA translation for PT (IceLake and newer) ++ * User wait and pause ++ * ENCLV exiting ++ * Load IA32_RTIT_CTL ++ * Clear IA32_RTIT_CTL ++ * Advanced VM-exit information for EPT violations ++ * Sub-page write permissions ++ * PT in VMX operation ++ */ ++ + static X86CPUDefinition builtin_x86_defs[] = { + { + .name = "qemu64", +@@ -1873,6 +1901,24 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_LAHF_LM, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES, + .xlevel = 0x80000008, + .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", + }, +@@ -1900,6 +1946,20 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */ + .features[FEAT_8000_0001_ECX] = + 0, ++ /* VMX features from Cedar Mill/Prescott */ ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING, + .xlevel = 0x80000008, + .model_id = "Common KVM processor" + }, +@@ -1931,6 +1991,19 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT_SSE3, + .features[FEAT_8000_0001_ECX] = + 0, ++ /* VMX features from Yonah */ ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | ++ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | ++ VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS, + .xlevel = 0x80000008, + .model_id = "Common 32-bit KVM processor" + }, +@@ -1952,6 +2025,18 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT_SSE3 | CPUID_EXT_MONITOR, + .features[FEAT_8000_0001_EDX] = + CPUID_EXT2_NX, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | ++ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | ++ VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS, + .xlevel = 0x80000008, + .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz", + }, +@@ -2062,6 +2147,24 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_LAHF_LM, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES, + .xlevel = 0x80000008, + .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", + }, +@@ -2085,6 +2188,27 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_LAHF_LM, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL, ++ .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING, + .xlevel = 0x80000008, + .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", + }, +@@ -2108,6 +2232,46 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_LAHF_LM, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID, + .xlevel = 0x80000008, + .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2148,6 +2312,47 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_EXT3_LAHF_LM, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST, + .xlevel = 0x80000008, + .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2193,6 +2398,47 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XSAVEOPT, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST, + .xlevel = 0x80000008, + .model_id = "Intel Xeon E312xx (Sandy Bridge)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2241,6 +2487,50 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XSAVEOPT, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING, + .xlevel = 0x80000008, + .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2292,6 +2582,52 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XSAVEOPT, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Core Processor (Haswell)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2376,6 +2712,53 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XSAVEOPT, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Core Processor (Broadwell)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2460,6 +2843,51 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */ ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Core Processor (Skylake)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2524,6 +2952,52 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */ ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, + .xlevel = 0x80000008, + .model_id = "Intel Xeon Processor (Skylake)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2594,6 +3068,52 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */ ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, + .xlevel = 0x80000008, + .model_id = "Intel Xeon Processor (Cascadelake)", + .versions = (X86CPUVersionDefinition[]) { +@@ -2724,6 +3244,51 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */ ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Core Processor (Icelake)", + }, +@@ -2782,6 +3347,52 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */ ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, + .xlevel = 0x80000008, + .model_id = "Intel Xeon Processor (Icelake)", + }, +@@ -2829,6 +3440,53 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_6_EAX_ARAT, + .features[FEAT_ARCH_CAPABILITIES] = + MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Atom Processor (Denverton)", + }, +@@ -2899,6 +3557,53 @@ static X86CPUDefinition builtin_x86_defs[] = { + CPUID_XSAVE_XGETBV1, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, ++ .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS | ++ MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT | ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | ++ MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER | ++ VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK | ++ VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS | ++ VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING | ++ VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS | ++ VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT | ++ VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, ++ .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, + .xlevel = 0x80000008, + .model_id = "Intel Atom Processor (SnowRidge)", + .versions = (X86CPUVersionDefinition[]) { +-- +2.27.0 + diff --git a/target-i386-add-VMX-features.patch b/target-i386-add-VMX-features.patch new file mode 100644 index 0000000000000000000000000000000000000000..50457d7f2125e4db535a18c4798e6bab48d68393 --- /dev/null +++ b/target-i386-add-VMX-features.patch @@ -0,0 +1,492 @@ +From 290ed17e639a67a9faf4a18b1b5973f9535bace4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2019 18:32:17 +0200 +Subject: [PATCH] target/i386: add VMX features + +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 +--- + target/i386/cpu.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++ + target/i386/cpu.h | 9 ++ + target/i386/kvm.c | 162 ++++++++++++++++++++++++++++++++- + 3 files changed, 394 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 3d6541c4a8..fd248a78db 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -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 { +@@ -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 { +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index b4be6ffb1f..0b57b915af 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -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; + +diff --git a/target/i386/kvm.c b/target/i386/kvm.c +index e9a6293ab2..fafb9fb26d 100644 +--- a/target/i386/kvm.c ++++ b/target/i386/kvm.c +@@ -96,6 +96,7 @@ static bool has_msr_virt_ssbd; + static bool has_msr_smi_count; + static bool has_msr_arch_capabs; + static bool has_msr_core_capabs; ++static bool has_msr_vmx_vmfunc; + + static uint32_t has_architectural_pmu_version; + static uint32_t num_architectural_pmu_gp_counters; +@@ -443,7 +444,8 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) + struct kvm_msrs info; + struct kvm_msr_entry entries[1]; + } msr_data; +- uint32_t ret; ++ uint64_t value; ++ uint32_t ret, can_be_one, must_be_one; + + if (kvm_feature_msrs == NULL) { /* Host doesn't support feature MSRs */ + return 0; +@@ -469,7 +471,25 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) + exit(1); + } + +- return msr_data.entries[0].data; ++ value = msr_data.entries[0].data; ++ switch (index) { ++ case MSR_IA32_VMX_PROCBASED_CTLS2: ++ case MSR_IA32_VMX_TRUE_PINBASED_CTLS: ++ case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: ++ case MSR_IA32_VMX_TRUE_ENTRY_CTLS: ++ case MSR_IA32_VMX_TRUE_EXIT_CTLS: ++ /* ++ * Return true for bits that can be one, but do not have to be one. ++ * The SDM tells us which bits could have a "must be one" setting, ++ * so we can do the opposite transformation in make_vmx_msr_value. ++ */ ++ must_be_one = (uint32_t)value; ++ can_be_one = (uint32_t)(value >> 32); ++ return can_be_one & ~must_be_one; ++ ++ default: ++ return value; ++ } + } + + +@@ -1933,6 +1953,9 @@ static int kvm_get_supported_msrs(KVMState *s) + case MSR_IA32_CORE_CAPABILITY: + has_msr_core_capabs = true; + break; ++ case MSR_IA32_VMX_VMFUNC: ++ has_msr_vmx_vmfunc = true; ++ break; + } + } + } +@@ -2407,6 +2430,132 @@ static int kvm_put_msr_feature_control(X86CPU *cpu) + return 0; + } + ++static uint64_t make_vmx_msr_value(uint32_t index, uint32_t features) ++{ ++ uint32_t default1, can_be_one, can_be_zero; ++ uint32_t must_be_one; ++ ++ switch (index) { ++ case MSR_IA32_VMX_TRUE_PINBASED_CTLS: ++ default1 = 0x00000016; ++ break; ++ case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: ++ default1 = 0x0401e172; ++ break; ++ case MSR_IA32_VMX_TRUE_ENTRY_CTLS: ++ default1 = 0x000011ff; ++ break; ++ case MSR_IA32_VMX_TRUE_EXIT_CTLS: ++ default1 = 0x00036dff; ++ break; ++ case MSR_IA32_VMX_PROCBASED_CTLS2: ++ default1 = 0; ++ break; ++ default: ++ abort(); ++ } ++ ++ /* If a feature bit is set, the control can be either set or clear. ++ * Otherwise the value is limited to either 0 or 1 by default1. ++ */ ++ can_be_one = features | default1; ++ can_be_zero = features | ~default1; ++ must_be_one = ~can_be_zero; ++ ++ /* ++ * Bit 0:31 -> 0 if the control bit can be zero (i.e. 1 if it must be one). ++ * Bit 32:63 -> 1 if the control bit can be one. ++ */ ++ return must_be_one | (((uint64_t)can_be_one) << 32); ++} ++ ++#define VMCS12_MAX_FIELD_INDEX (0x17) ++ ++static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f) ++{ ++ uint64_t kvm_vmx_basic = ++ kvm_arch_get_supported_msr_feature(kvm_state, ++ MSR_IA32_VMX_BASIC); ++ uint64_t kvm_vmx_misc = ++ kvm_arch_get_supported_msr_feature(kvm_state, ++ MSR_IA32_VMX_MISC); ++ uint64_t kvm_vmx_ept_vpid = ++ kvm_arch_get_supported_msr_feature(kvm_state, ++ MSR_IA32_VMX_EPT_VPID_CAP); ++ ++ /* ++ * If the guest is 64-bit, a value of 1 is allowed for the host address ++ * space size vmexit control. ++ */ ++ uint64_t fixed_vmx_exit = f[FEAT_8000_0001_EDX] & CPUID_EXT2_LM ++ ? (uint64_t)VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE << 32 : 0; ++ ++ /* ++ * Bits 0-30, 32-44 and 50-53 come from the host. KVM should ++ * not change them for backwards compatibility. ++ */ ++ uint64_t fixed_vmx_basic = kvm_vmx_basic & ++ (MSR_VMX_BASIC_VMCS_REVISION_MASK | ++ MSR_VMX_BASIC_VMXON_REGION_SIZE_MASK | ++ MSR_VMX_BASIC_VMCS_MEM_TYPE_MASK); ++ ++ /* ++ * Same for bits 0-4 and 25-27. Bits 16-24 (CR3 target count) can ++ * change in the future but are always zero for now, clear them to be ++ * future proof. Bits 32-63 in theory could change, though KVM does ++ * not support dual-monitor treatment and probably never will; mask ++ * them out as well. ++ */ ++ uint64_t fixed_vmx_misc = kvm_vmx_misc & ++ (MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK | ++ MSR_VMX_MISC_MAX_MSR_LIST_SIZE_MASK); ++ ++ /* ++ * EPT memory types should not change either, so we do not bother ++ * adding features for them. ++ */ ++ uint64_t fixed_vmx_ept_mask = ++ (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_ENABLE_EPT ? ++ MSR_VMX_EPT_UC | MSR_VMX_EPT_WB : 0); ++ uint64_t fixed_vmx_ept_vpid = kvm_vmx_ept_vpid & fixed_vmx_ept_mask; ++ ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_PROCBASED_CTLS, ++ make_vmx_msr_value(MSR_IA32_VMX_TRUE_PROCBASED_CTLS, ++ f[FEAT_VMX_PROCBASED_CTLS])); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_PINBASED_CTLS, ++ make_vmx_msr_value(MSR_IA32_VMX_TRUE_PINBASED_CTLS, ++ f[FEAT_VMX_PINBASED_CTLS])); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_EXIT_CTLS, ++ make_vmx_msr_value(MSR_IA32_VMX_TRUE_EXIT_CTLS, ++ f[FEAT_VMX_EXIT_CTLS]) | fixed_vmx_exit); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_ENTRY_CTLS, ++ make_vmx_msr_value(MSR_IA32_VMX_TRUE_ENTRY_CTLS, ++ f[FEAT_VMX_ENTRY_CTLS])); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_PROCBASED_CTLS2, ++ make_vmx_msr_value(MSR_IA32_VMX_PROCBASED_CTLS2, ++ f[FEAT_VMX_SECONDARY_CTLS])); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_EPT_VPID_CAP, ++ f[FEAT_VMX_EPT_VPID_CAPS] | fixed_vmx_ept_vpid); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_BASIC, ++ f[FEAT_VMX_BASIC] | fixed_vmx_basic); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_MISC, ++ f[FEAT_VMX_MISC] | fixed_vmx_misc); ++ if (has_msr_vmx_vmfunc) { ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMFUNC, f[FEAT_VMX_VMFUNC]); ++ } ++ ++ /* ++ * Just to be safe, write these with constant values. The CRn_FIXED1 ++ * MSRs are generated by KVM based on the vCPU's CPUID. ++ */ ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR0_FIXED0, ++ CR0_PE_MASK | CR0_PG_MASK | CR0_NE_MASK); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR4_FIXED0, ++ CR4_VMXE_MASK); ++ kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, ++ VMCS12_MAX_FIELD_INDEX << 1); ++} ++ + static int kvm_put_msrs(X86CPU *cpu, int level) + { + CPUX86State *env = &cpu->env; +@@ -2646,7 +2795,16 @@ static int kvm_put_msrs(X86CPU *cpu, int level) + + /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see + * kvm_put_msr_feature_control. */ ++ ++ /* ++ * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but ++ * all kernels with MSR features should have them. ++ */ ++ if (kvm_feature_msrs && cpu_has_vmx(env)) { ++ kvm_msr_entry_add_vmx(cpu, env->features); ++ } + } ++ + if (env->mcg_cap) { + int i; + +-- +2.27.0 + diff --git a/target-i386-add-two-missing-VMX-features-for-Skylake.patch b/target-i386-add-two-missing-VMX-features-for-Skylake.patch new file mode 100644 index 0000000000000000000000000000000000000000..fa3c6d8f39ad28cb75995e142697bee2bf48e97a --- /dev/null +++ b/target-i386-add-two-missing-VMX-features-for-Skylake.patch @@ -0,0 +1,42 @@ +From 1faa48f4de44c123143d43e67cd5a478628a45a4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 25 Nov 2019 19:12:16 +0100 +Subject: [PATCH] target/i386: add two missing VMX features for Skylake and + CascadeLake Server + +They are present in client (Core) Skylake but pasted wrong into the server +SKUs. + +Reported-by: Dr. David Alan Gilbert +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 2f32d67aa5..6f27a5170a 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2997,7 +2997,8 @@ static X86CPUDefinition builtin_x86_defs[] = { + VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | + VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | + VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | +- VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, + .xlevel = 0x80000008, + .model_id = "Intel Xeon Processor (Skylake)", + .versions = (X86CPUVersionDefinition[]) { +@@ -3113,7 +3114,8 @@ static X86CPUDefinition builtin_x86_defs[] = { + VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | + VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | + VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID | +- VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS, ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML, + .xlevel = 0x80000008, + .model_id = "Intel Xeon Processor (Cascadelake)", + .versions = (X86CPUVersionDefinition[]) { +-- +2.27.0 + diff --git a/target-i386-disable-VMX-features-if-nested-0.patch b/target-i386-disable-VMX-features-if-nested-0.patch new file mode 100644 index 0000000000000000000000000000000000000000..fa7edfdb2a7296a0039a44e2c4c1af9b5b324951 --- /dev/null +++ b/target-i386-disable-VMX-features-if-nested-0.patch @@ -0,0 +1,43 @@ +From 26f01427d155510edcab07e312a72f5bacddafb2 Mon Sep 17 00:00:00 2001 +From: Yang Zhong +Date: Fri, 6 Dec 2019 15:11:11 +0800 +Subject: [PATCH] target/i386: disable VMX features if nested=0 + +If kvm does not support VMX feature by nested=0, the kvm_vmx_basic +can't get the right value from MSR_IA32_VMX_BASIC register, which +make qemu coredump when qemu do KVM_SET_MSRS. + +The coredump info: +error: failed to set MSR 0x480 to 0x0 +kvm_put_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed. + +Signed-off-by: Yang Zhong +Message-Id: <20191206071111.12128-1-yang.zhong@intel.com> +Reported-by: Catherine Ho +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/target/i386/kvm.c b/target/i386/kvm.c +index b97f40df6b..5ee0c50d7c 100644 +--- a/target/i386/kvm.c ++++ b/target/i386/kvm.c +@@ -2493,6 +2493,14 @@ static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f) + uint64_t kvm_vmx_basic = + kvm_arch_get_supported_msr_feature(kvm_state, + MSR_IA32_VMX_BASIC); ++ ++ if (!kvm_vmx_basic) { ++ /* If the kernel doesn't support VMX feature (kvm_intel.nested=0), ++ * then kvm_vmx_basic will be 0 and KVM_SET_MSR will fail. ++ */ ++ return; ++ } ++ + uint64_t kvm_vmx_misc = + kvm_arch_get_supported_msr_feature(kvm_state, + MSR_IA32_VMX_MISC); +-- +2.27.0 + diff --git a/target-i386-do-not-set-unsupported-VMX-secondary-exe.patch b/target-i386-do-not-set-unsupported-VMX-secondary-exe.patch new file mode 100644 index 0000000000000000000000000000000000000000..8eda458156b202ba7c5405bf1e261e56a7aa1771 --- /dev/null +++ b/target-i386-do-not-set-unsupported-VMX-secondary-exe.patch @@ -0,0 +1,102 @@ +From 472ccc3e48cab962ec9acf3f31e4467544b51705 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Tue, 31 Mar 2020 18:27:52 +0200 +Subject: [PATCH] target/i386: do not set unsupported VMX secondary execution + controls + +Commit 048c95163b4 ("target/i386: work around KVM_GET_MSRS bug for +secondary execution controls") added a workaround for KVM pre-dating +commit 6defc591846d ("KVM: nVMX: include conditional controls in /dev/kvm +KVM_GET_MSRS") which wasn't setting certain available controls. The +workaround uses generic CPUID feature bits to set missing VMX controls. + +It was found that in some cases it is possible to observe hosts which +have certain CPUID features but lack the corresponding VMX control. + +In particular, it was reported that Azure VMs have RDSEED but lack +VMX_SECONDARY_EXEC_RDSEED_EXITING; attempts to enable this feature +bit result in QEMU abort. + +Resolve the issue but not applying the workaround when we don't have +to. As there is no good way to find out if KVM has the fix itself, use +95c5c7c77c ("KVM: nVMX: list VMX MSRs in KVM_GET_MSR_INDEX_LIST") instead +as these [are supposed to] come together. + +Fixes: 048c95163b4 ("target/i386: work around KVM_GET_MSRS bug for secondary execution controls") +Suggested-by: Paolo Bonzini +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20200331162752.1209928-1-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm.c | 41 ++++++++++++++++++++++++++--------------- + 1 file changed, 26 insertions(+), 15 deletions(-) + +diff --git a/target/i386/kvm.c b/target/i386/kvm.c +index 5ee0c50d7c..7328746d92 100644 +--- a/target/i386/kvm.c ++++ b/target/i386/kvm.c +@@ -97,6 +97,7 @@ static bool has_msr_smi_count; + static bool has_msr_arch_capabs; + static bool has_msr_core_capabs; + static bool has_msr_vmx_vmfunc; ++static bool has_msr_vmx_procbased_ctls2; + + static uint32_t has_architectural_pmu_version; + static uint32_t num_architectural_pmu_gp_counters; +@@ -474,21 +475,28 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) + value = msr_data.entries[0].data; + switch (index) { + case MSR_IA32_VMX_PROCBASED_CTLS2: +- /* KVM forgot to add these bits for some time, do this ourselves. */ +- if (kvm_arch_get_supported_cpuid(s, 0xD, 1, R_ECX) & CPUID_XSAVE_XSAVES) { +- value |= (uint64_t)VMX_SECONDARY_EXEC_XSAVES << 32; +- } +- if (kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX) & CPUID_EXT_RDRAND) { +- value |= (uint64_t)VMX_SECONDARY_EXEC_RDRAND_EXITING << 32; +- } +- if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_INVPCID) { +- value |= (uint64_t)VMX_SECONDARY_EXEC_ENABLE_INVPCID << 32; +- } +- if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_RDSEED) { +- value |= (uint64_t)VMX_SECONDARY_EXEC_RDSEED_EXITING << 32; +- } +- if (kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX) & CPUID_EXT2_RDTSCP) { +- value |= (uint64_t)VMX_SECONDARY_EXEC_RDTSCP << 32; ++ if (!has_msr_vmx_procbased_ctls2) { ++ /* KVM forgot to add these bits for some time, do this ourselves. */ ++ if (kvm_arch_get_supported_cpuid(s, 0xD, 1, R_ECX) & ++ CPUID_XSAVE_XSAVES) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_XSAVES << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX) & ++ CPUID_EXT_RDRAND) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDRAND_EXITING << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & ++ CPUID_7_0_EBX_INVPCID) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_ENABLE_INVPCID << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & ++ CPUID_7_0_EBX_RDSEED) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDSEED_EXITING << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX) & ++ CPUID_EXT2_RDTSCP) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDTSCP << 32; ++ } + } + /* fall through */ + case MSR_IA32_VMX_TRUE_PINBASED_CTLS: +@@ -1973,6 +1981,9 @@ static int kvm_get_supported_msrs(KVMState *s) + case MSR_IA32_VMX_VMFUNC: + has_msr_vmx_vmfunc = true; + break; ++ case MSR_IA32_VMX_PROCBASED_CTLS2: ++ has_msr_vmx_procbased_ctls2 = true; ++ break; + } + } + } +-- +2.27.0 + diff --git a/target-i386-expand-feature-words-to-64-bits.patch b/target-i386-expand-feature-words-to-64-bits.patch new file mode 100644 index 0000000000000000000000000000000000000000..e4a06e5954aec3ec8d30e29c61234612ed36d0c7 --- /dev/null +++ b/target-i386-expand-feature-words-to-64-bits.patch @@ -0,0 +1,295 @@ +From bec2d75a3d3c6405d0afe59c343d23199b009666 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2019 17:38:54 +0200 +Subject: [PATCH] target/i386: expand feature words to 64 bits + +VMX requires 64-bit feature words for the IA32_VMX_EPT_VPID_CAP +and IA32_VMX_BASIC MSRs. (The VMX control MSRs are 64-bit wide but +actually have only 32 bits of information). + +Signed-off-by: Paolo Bonzini +--- + include/sysemu/kvm.h | 2 +- + target/i386/cpu.c | 71 +++++++++++++++++++++++--------------------- + target/i386/cpu.h | 2 +- + target/i386/kvm.c | 2 +- + 4 files changed, 40 insertions(+), 37 deletions(-) + +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 565adb4e2c..875b2bf10d 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -464,7 +464,7 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension); + + uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function, + uint32_t index, int reg); +-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index); ++uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index); + + + void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len); +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index d4a435ba96..3d6541c4a8 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -789,7 +789,7 @@ typedef struct FeatureWordInfo { + * In cases of disagreement between feature naming conventions, + * aliases may be added. + */ +- const char *feat_names[32]; ++ const char *feat_names[64]; + union { + /* If type==CPUID_FEATURE_WORD */ + struct { +@@ -803,11 +803,11 @@ typedef struct FeatureWordInfo { + uint32_t index; + } msr; + }; +- uint32_t tcg_features; /* Feature flags supported by TCG */ +- uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */ +- uint32_t migratable_flags; /* Feature flags known to be migratable */ ++ uint64_t tcg_features; /* Feature flags supported by TCG */ ++ uint64_t unmigratable_flags; /* Feature flags known to be unmigratable */ ++ uint64_t migratable_flags; /* Feature flags known to be migratable */ + /* Features that shouldn't be auto-enabled by "-cpu host" */ +- uint32_t no_autoenable_flags; ++ uint64_t no_autoenable_flags; + } FeatureWordInfo; + + static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { +@@ -1236,7 +1236,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + + typedef struct FeatureMask { + FeatureWord index; +- uint32_t mask; ++ uint64_t mask; + } FeatureMask; + + typedef struct FeatureDep { +@@ -1246,11 +1246,11 @@ typedef struct FeatureDep { + static FeatureDep feature_dependencies[] = { + { + .from = { FEAT_7_0_EDX, CPUID_7_0_EDX_ARCH_CAPABILITIES }, +- .to = { FEAT_ARCH_CAPABILITIES, ~0u }, ++ .to = { FEAT_ARCH_CAPABILITIES, ~0ull }, + }, + { + .from = { FEAT_7_0_EDX, CPUID_7_0_EDX_CORE_CAPABILITY }, +- .to = { FEAT_CORE_CAPABILITY, ~0u }, ++ .to = { FEAT_CORE_CAPABILITY, ~0ull }, + }, + }; + +@@ -1362,14 +1362,14 @@ const char *get_register_name_32(unsigned int reg) + * Returns the set of feature flags that are supported and migratable by + * QEMU, for a given FeatureWord. + */ +-static uint32_t x86_cpu_get_migratable_flags(FeatureWord w) ++static uint64_t x86_cpu_get_migratable_flags(FeatureWord w) + { + FeatureWordInfo *wi = &feature_word_info[w]; +- uint32_t r = 0; ++ uint64_t r = 0; + int i; + +- for (i = 0; i < 32; i++) { +- uint32_t f = 1U << i; ++ for (i = 0; i < 64; i++) { ++ uint64_t f = 1ULL << i; + + /* If the feature name is known, it is implicitly considered migratable, + * unless it is explicitly set in unmigratable_flags */ +@@ -3051,7 +3051,7 @@ void x86_cpu_change_kvm_default(const char *prop, const char *value) + assert(pv->prop); + } + +-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, ++static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + bool migratable_only); + + static bool lmce_supported(void) +@@ -3237,7 +3237,7 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu) + return false; + } + +-static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask, ++static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, + const char *verbose_prefix) + { + CPUX86State *env = &cpu->env; +@@ -3254,8 +3254,8 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask, + return; + } + +- for (i = 0; i < 32; ++i) { +- if ((1UL << i) & mask) { ++ for (i = 0; i < 64; ++i) { ++ if ((1ULL << i) & mask) { + feat_word_str = feature_word_description(f, i); + warn_report("%s: %s%s%s [bit %d]", + verbose_prefix, +@@ -3498,7 +3498,7 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) + { +- uint32_t *array = (uint32_t *)opaque; ++ uint64_t *array = (uint64_t *)opaque; + FeatureWord w; + X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { }; + X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { }; +@@ -3542,6 +3542,7 @@ static inline void feat2prop(char *s) + /* Return the feature property name for a feature flag bit */ + static const char *x86_cpu_feature_name(FeatureWord w, int bitnr) + { ++ const char *name; + /* XSAVE components are automatically enabled by other features, + * so return the original feature name instead + */ +@@ -3555,9 +3556,11 @@ static const char *x86_cpu_feature_name(FeatureWord w, int bitnr) + } + } + +- assert(bitnr < 32); ++ assert(bitnr < 64); + assert(w < FEATURE_WORDS); +- return feature_word_info[w].feat_names[bitnr]; ++ name = feature_word_info[w].feat_names[bitnr]; ++ assert(bitnr < 32 || !(name && feature_word_info[w].type == CPUID_FEATURE_WORD)); ++ return name; + } + + /* Compatibily hack to maintain legacy +-feat semantic, +@@ -3673,10 +3676,10 @@ static void x86_cpu_list_feature_names(FeatureWordArray features, + strList **next = feat_names; + + for (w = 0; w < FEATURE_WORDS; w++) { +- uint32_t filtered = features[w]; ++ uint64_t filtered = features[w]; + int i; +- for (i = 0; i < 32; i++) { +- if (filtered & (1UL << i)) { ++ for (i = 0; i < 64; i++) { ++ if (filtered & (1ULL << i)) { + strList *new = g_new0(strList, 1); + new->value = g_strdup(x86_cpu_feature_name(w, i)); + *next = new; +@@ -3845,7 +3848,7 @@ void x86_cpu_list(void) + names = NULL; + for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) { + FeatureWordInfo *fw = &feature_word_info[i]; +- for (j = 0; j < 32; j++) { ++ for (j = 0; j < 64; j++) { + if (fw->feat_names[j]) { + names = g_list_append(names, (gpointer)fw->feat_names[j]); + } +@@ -3900,11 +3903,11 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) + return cpu_list; + } + +-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, ++static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + bool migratable_only) + { + FeatureWordInfo *wi = &feature_word_info[w]; +- uint32_t r = 0; ++ uint64_t r = 0; + + if (kvm_enabled()) { + switch (wi->type) { +@@ -4075,7 +4078,7 @@ static QDict *x86_cpu_static_props(void) + for (w = 0; w < FEATURE_WORDS; w++) { + FeatureWordInfo *fi = &feature_word_info[w]; + int bit; +- for (bit = 0; bit < 32; bit++) { ++ for (bit = 0; bit < 64; bit++) { + if (!fi->feat_names[bit]) { + continue; + } +@@ -5231,7 +5234,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) { + FeatureDep *d = &feature_dependencies[i]; + if (!(env->features[d->from.index] & d->from.mask)) { +- uint32_t unavailable_features = env->features[d->to.index] & d->to.mask; ++ uint64_t unavailable_features = env->features[d->to.index] & d->to.mask; + + /* Not an error unless the dependent feature was added explicitly. */ + mark_unavailable_features(cpu, d->to.index, +@@ -5326,10 +5329,10 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) + } + + for (w = 0; w < FEATURE_WORDS; w++) { +- uint32_t host_feat = ++ uint64_t host_feat = + x86_cpu_get_supported_feature_word(w, false); +- uint32_t requested_features = env->features[w]; +- uint32_t unavailable_features = requested_features & ~host_feat; ++ uint64_t requested_features = env->features[w]; ++ uint64_t unavailable_features = requested_features & ~host_feat; + mark_unavailable_features(cpu, w, unavailable_features, prefix); + } + +@@ -5626,7 +5629,7 @@ static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp) + + typedef struct BitProperty { + FeatureWord w; +- uint32_t mask; ++ uint64_t mask; + } BitProperty; + + static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name, +@@ -5634,7 +5637,7 @@ static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name, + { + X86CPU *cpu = X86_CPU(obj); + BitProperty *fp = opaque; +- uint32_t f = cpu->env.features[fp->w]; ++ uint64_t f = cpu->env.features[fp->w]; + bool value = (f & fp->mask) == fp->mask; + visit_type_bool(v, name, &value, errp); + } +@@ -5687,7 +5690,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu, + { + BitProperty *fp; + ObjectProperty *op; +- uint32_t mask = (1UL << bitnr); ++ uint64_t mask = (1ULL << bitnr); + + op = object_property_find(OBJECT(cpu), prop_name, NULL); + if (op) { +@@ -5821,7 +5824,7 @@ static void x86_cpu_initfn(Object *obj) + for (w = 0; w < FEATURE_WORDS; w++) { + int bitnr; + +- for (bitnr = 0; bitnr < 32; bitnr++) { ++ for (bitnr = 0; bitnr < 64; bitnr++) { + x86_cpu_register_feature_bit_props(cpu, w, bitnr); + } + } +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 24d489db0f..9a105b2251 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -502,7 +502,7 @@ typedef enum FeatureWord { + FEATURE_WORDS, + } FeatureWord; + +-typedef uint32_t FeatureWordArray[FEATURE_WORDS]; ++typedef uint64_t FeatureWordArray[FEATURE_WORDS]; + + /* cpuid_features bits */ + #define CPUID_FP87 (1U << 0) +diff --git a/target/i386/kvm.c b/target/i386/kvm.c +index f55d4b4b97..e9a6293ab2 100644 +--- a/target/i386/kvm.c ++++ b/target/i386/kvm.c +@@ -437,7 +437,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, + return ret; + } + +-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) ++uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) + { + struct { + struct kvm_msrs info; +-- +2.27.0 + diff --git a/target-i386-handle-filtered_features-in-a-new-functi.patch b/target-i386-handle-filtered_features-in-a-new-functi.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba35948dd1e1c10f566c327750026c22b626a5f2 --- /dev/null +++ b/target-i386-handle-filtered_features-in-a-new-functi.patch @@ -0,0 +1,176 @@ +From b9d29966103ca671718ef1eb5b68067b05fad340 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 2 Jul 2019 15:32:41 +0200 +Subject: [PATCH] target/i386: handle filtered_features in a new function + mark_unavailable_features + +The next patch will add a different reason for filtering features, unrelated +to host feature support. Extract a new function that takes care of disabling +the features and optionally reporting them. + +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 87 ++++++++++++++++++++++++++--------------------- + 1 file changed, 48 insertions(+), 39 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index e65f372f25..8798cafc7a 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3216,17 +3216,41 @@ static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) + return NULL; + } + +-static void report_unavailable_features(FeatureWord w, uint32_t mask) ++static bool x86_cpu_have_filtered_features(X86CPU *cpu) + { ++ FeatureWord w; ++ ++ for (w = 0; w < FEATURE_WORDS; w++) { ++ if (cpu->filtered_features[w]) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask, ++ const char *verbose_prefix) ++{ ++ CPUX86State *env = &cpu->env; + FeatureWordInfo *f = &feature_word_info[w]; + int i; + char *feat_word_str; + ++ if (!cpu->force_features) { ++ env->features[w] &= ~mask; ++ } ++ cpu->filtered_features[w] |= mask; ++ ++ if (!verbose_prefix) { ++ return; ++ } ++ + for (i = 0; i < 32; ++i) { + if ((1UL << i) & mask) { + feat_word_str = feature_word_description(f, i); +- warn_report("%s doesn't support requested feature: %s%s%s [bit %d]", +- accel_uses_host_cpuid() ? "host" : "TCG", ++ warn_report("%s: %s%s%s [bit %d]", ++ verbose_prefix, + feat_word_str, + f->feat_names[i] ? "." : "", + f->feat_names[i] ? f->feat_names[i] : "", i); +@@ -3631,7 +3655,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features, + } + + static void x86_cpu_expand_features(X86CPU *cpu, Error **errp); +-static int x86_cpu_filter_features(X86CPU *cpu); ++static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); + + /* Build a list with the name of all features on a feature word array */ + static void x86_cpu_list_feature_names(FeatureWordArray features, +@@ -3696,7 +3720,7 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, + next = &new->next; + } + +- x86_cpu_filter_features(xc); ++ x86_cpu_filter_features(xc, false); + + x86_cpu_list_feature_names(xc->filtered_features, next); + +@@ -3904,15 +3928,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, + return r; + } + +-static void x86_cpu_report_filtered_features(X86CPU *cpu) +-{ +- FeatureWord w; +- +- for (w = 0; w < FEATURE_WORDS; w++) { +- report_unavailable_features(w, cpu->filtered_features[w]); +- } +-} +- + static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) + { + PropValue *pv; +@@ -5274,24 +5289,24 @@ out: + * + * Returns: 0 if all flags are supported by the host, non-zero otherwise. + */ +-static int x86_cpu_filter_features(X86CPU *cpu) ++static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) + { + CPUX86State *env = &cpu->env; + FeatureWord w; +- int rv = 0; ++ const char *prefix = NULL; ++ ++ if (verbose) { ++ prefix = accel_uses_host_cpuid() ++ ? "host doesn't support requested feature" ++ : "TCG doesn't support requested feature"; ++ } + + for (w = 0; w < FEATURE_WORDS; w++) { + uint32_t host_feat = + x86_cpu_get_supported_feature_word(w, false); + uint32_t requested_features = env->features[w]; +- uint32_t available_features = requested_features & host_feat; +- if (!cpu->force_features) { +- env->features[w] = available_features; +- } +- cpu->filtered_features[w] = requested_features & ~available_features; +- if (cpu->filtered_features[w]) { +- rv = 1; +- } ++ uint32_t unavailable_features = requested_features & ~host_feat; ++ mark_unavailable_features(cpu, w, unavailable_features, prefix); + } + + if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) && +@@ -5317,13 +5332,9 @@ static int x86_cpu_filter_features(X86CPU *cpu) + * host can't emulate the capabilities we report on + * cpu_x86_cpuid(), intel-pt can't be enabled on the current host. + */ +- env->features[FEAT_7_0_EBX] &= ~CPUID_7_0_EBX_INTEL_PT; +- cpu->filtered_features[FEAT_7_0_EBX] |= CPUID_7_0_EBX_INTEL_PT; +- rv = 1; ++ mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix); + } + } +- +- return rv; + } + + static void x86_cpu_realizefn(DeviceState *dev, Error **errp) +@@ -5364,16 +5375,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) + goto out; + } + +- if (x86_cpu_filter_features(cpu) && +- (cpu->check_cpuid || cpu->enforce_cpuid)) { +- x86_cpu_report_filtered_features(cpu); +- if (cpu->enforce_cpuid) { +- error_setg(&local_err, +- accel_uses_host_cpuid() ? +- "Host doesn't support requested features" : +- "TCG doesn't support requested features"); +- goto out; +- } ++ x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid); ++ ++ if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) { ++ error_setg(&local_err, ++ accel_uses_host_cpuid() ? ++ "Host doesn't support requested features" : ++ "TCG doesn't support requested features"); ++ goto out; + } + + /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on +-- +2.27.0 + diff --git a/target-i386-introduce-generic-feature-dependency-mec.patch b/target-i386-introduce-generic-feature-dependency-mec.patch new file mode 100644 index 0000000000000000000000000000000000000000..da374c58652d5559993c9a584d7c83377d6669cd --- /dev/null +++ b/target-i386-introduce-generic-feature-dependency-mec.patch @@ -0,0 +1,146 @@ +From ed8fa9d895a0e06434b4163405aeaacbe65bcf44 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2019 17:26:45 +0200 +Subject: [PATCH] target/i386: introduce generic feature dependency mechanism + +Sometimes a CPU feature does not make sense unless another is +present. In the case of VMX features, KVM does not even allow +setting the VMX controls to some invalid combinations. + +Therefore, this patch adds a generic mechanism that looks for bits +that the user explicitly cleared, and uses them to remove other bits +from the expanded CPU definition. If these dependent bits were also +explicitly *set* by the user, this will be a warning for "-cpu check" +and an error for "-cpu enforce". If not, then the dependent bits are +cleared silently, for convenience. + +With VMX features, this will be used so that for example +"-cpu host,-rdrand" will also hide support for RDRAND exiting. + +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 72 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 48 insertions(+), 24 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 8798cafc7a..d4a435ba96 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -801,10 +801,6 @@ typedef struct FeatureWordInfo { + /* If type==MSR_FEATURE_WORD */ + struct { + uint32_t index; +- struct { /*CPUID that enumerate this MSR*/ +- FeatureWord cpuid_class; +- uint32_t cpuid_flag; +- } cpuid_dep; + } msr; + }; + uint32_t tcg_features; /* Feature flags supported by TCG */ +@@ -1218,10 +1214,6 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + .msr = { + .index = MSR_IA32_ARCH_CAPABILITIES, +- .cpuid_dep = { +- FEAT_7_0_EDX, +- CPUID_7_0_EDX_ARCH_CAPABILITIES +- } + }, + }, + [FEAT_CORE_CAPABILITY] = { +@@ -1238,14 +1230,30 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + .msr = { + .index = MSR_IA32_CORE_CAPABILITY, +- .cpuid_dep = { +- FEAT_7_0_EDX, +- CPUID_7_0_EDX_CORE_CAPABILITY, +- }, + }, + }, + }; + ++typedef struct FeatureMask { ++ FeatureWord index; ++ uint32_t mask; ++} FeatureMask; ++ ++typedef struct FeatureDep { ++ FeatureMask from, to; ++} FeatureDep; ++ ++static FeatureDep feature_dependencies[] = { ++ { ++ .from = { FEAT_7_0_EDX, CPUID_7_0_EDX_ARCH_CAPABILITIES }, ++ .to = { FEAT_ARCH_CAPABILITIES, ~0u }, ++ }, ++ { ++ .from = { FEAT_7_0_EDX, CPUID_7_0_EDX_CORE_CAPABILITY }, ++ .to = { FEAT_CORE_CAPABILITY, ~0u }, ++ }, ++}; ++ + typedef struct X86RegisterInfo32 { + /* Name of register */ + const char *name; +@@ -5183,9 +5191,26 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + { + CPUX86State *env = &cpu->env; + FeatureWord w; ++ int i; + GList *l; + Error *local_err = NULL; + ++ for (l = plus_features; l; l = l->next) { ++ const char *prop = l->data; ++ object_property_set_bool(OBJECT(cpu), true, prop, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ } ++ ++ for (l = minus_features; l; l = l->next) { ++ const char *prop = l->data; ++ object_property_set_bool(OBJECT(cpu), false, prop, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ } ++ + /*TODO: Now cpu->max_features doesn't overwrite features + * set using QOM properties, and we can convert + * plus_features & minus_features to global properties +@@ -5203,19 +5228,18 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + } + } + +- for (l = plus_features; l; l = l->next) { +- const char *prop = l->data; +- object_property_set_bool(OBJECT(cpu), true, prop, &local_err); +- if (local_err) { +- goto out; +- } +- } ++ for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) { ++ FeatureDep *d = &feature_dependencies[i]; ++ if (!(env->features[d->from.index] & d->from.mask)) { ++ uint32_t unavailable_features = env->features[d->to.index] & d->to.mask; + +- for (l = minus_features; l; l = l->next) { +- const char *prop = l->data; +- object_property_set_bool(OBJECT(cpu), false, prop, &local_err); +- if (local_err) { +- goto out; ++ /* Not an error unless the dependent feature was added explicitly. */ ++ mark_unavailable_features(cpu, d->to.index, ++ unavailable_features & env->user_features[d->to.index], ++ "This feature depends on other features that were not requested"); ++ ++ env->user_features[d->to.index] |= unavailable_features; ++ env->features[d->to.index] &= ~unavailable_features; + } + } + +-- +2.27.0 + diff --git a/target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch b/target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch new file mode 100644 index 0000000000000000000000000000000000000000..b4156952cf7fca7359fb38c8db086837b8ba3651 --- /dev/null +++ b/target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch @@ -0,0 +1,49 @@ +From 70e4d278b89e04d7f9397ea25163feb6a7dbaa2d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 2 Jul 2019 14:58:48 +0200 +Subject: [PATCH] target/i386: work around KVM_GET_MSRS bug for secondary + execution controls + +Some secondary controls are automatically enabled/disabled based on the CPUID +values that are set for the guest. However, they are still available at a +global level and therefore should be present when KVM_GET_MSRS is sent to +/dev/kvm. + +Unfortunately KVM forgot to include those, so fix that. + +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/target/i386/kvm.c b/target/i386/kvm.c +index fafb9fb26d..b97f40df6b 100644 +--- a/target/i386/kvm.c ++++ b/target/i386/kvm.c +@@ -474,6 +474,23 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index) + value = msr_data.entries[0].data; + switch (index) { + case MSR_IA32_VMX_PROCBASED_CTLS2: ++ /* KVM forgot to add these bits for some time, do this ourselves. */ ++ if (kvm_arch_get_supported_cpuid(s, 0xD, 1, R_ECX) & CPUID_XSAVE_XSAVES) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_XSAVES << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX) & CPUID_EXT_RDRAND) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDRAND_EXITING << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_INVPCID) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_ENABLE_INVPCID << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_RDSEED) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDSEED_EXITING << 32; ++ } ++ if (kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX) & CPUID_EXT2_RDTSCP) { ++ value |= (uint64_t)VMX_SECONDARY_EXEC_RDTSCP << 32; ++ } ++ /* fall through */ + case MSR_IA32_VMX_TRUE_PINBASED_CTLS: + case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: + case MSR_IA32_VMX_TRUE_ENTRY_CTLS: +-- +2.27.0 + diff --git a/vmxcap-correct-the-name-of-the-variables.patch b/vmxcap-correct-the-name-of-the-variables.patch new file mode 100644 index 0000000000000000000000000000000000000000..3a402dfa1e6908d301ff51e2499af5b3443e3014 --- /dev/null +++ b/vmxcap-correct-the-name-of-the-variables.patch @@ -0,0 +1,44 @@ +From de8779d10794312d1eb56dda5936df7ad6e3c87f Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2019 16:51:24 +0200 +Subject: [PATCH] vmxcap: correct the name of the variables + +The low bits are 1 if the control must be one, the high bits +are 1 if the control can be one. Correct the variable names +as they are very confusing. + +Signed-off-by: Paolo Bonzini +--- + scripts/kvm/vmxcap | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap +index 99a8146aaa..2db683215d 100755 +--- a/scripts/kvm/vmxcap ++++ b/scripts/kvm/vmxcap +@@ -51,15 +51,15 @@ class Control(object): + return (val & 0xffffffff, val >> 32) + def show(self): + print(self.name) +- mbz, mb1 = self.read2(self.cap_msr) +- tmbz, tmb1 = 0, 0 ++ mb1, cb1 = self.read2(self.cap_msr) ++ tmb1, tcb1 = 0, 0 + if self.true_cap_msr: +- tmbz, tmb1 = self.read2(self.true_cap_msr) ++ tmb1, tcb1 = self.read2(self.true_cap_msr) + for bit in sorted(self.bits.keys()): +- zero = not (mbz & (1 << bit)) +- one = mb1 & (1 << bit) +- true_zero = not (tmbz & (1 << bit)) +- true_one = tmb1 & (1 << bit) ++ zero = not (mb1 & (1 << bit)) ++ one = cb1 & (1 << bit) ++ true_zero = not (tmb1 & (1 << bit)) ++ true_one = tcb1 & (1 << bit) + s= '?' + if (self.true_cap_msr and true_zero and true_one + and one and not zero): +-- +2.27.0 +