Skip to content

Commit 1389309

Browse files
bonzinirkrcmar
authored andcommitted
KVM: nVMX: expose VMX capabilities for nested hypervisors to userspace
Use the new MSR feature framework to tell userspace which VMX capabilities are available for nested hypervisors. Before, these were only accessible with the KVM_GET_MSR VCPU ioctl, after VCPUs had been created. Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent 6677f3d commit 1389309

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

arch/x86/kvm/vmx.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ static struct vmcs_config {
958958
u32 cpu_based_2nd_exec_ctrl;
959959
u32 vmexit_ctrl;
960960
u32 vmentry_ctrl;
961+
struct nested_vmx_msrs nested;
961962
} vmcs_config;
962963

963964
static struct vmx_capability {
@@ -2689,6 +2690,11 @@ static inline bool nested_vmx_allowed(struct kvm_vcpu *vcpu)
26892690
*/
26902691
static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
26912692
{
2693+
if (!nested) {
2694+
memset(msrs, 0, sizeof(*msrs));
2695+
return;
2696+
}
2697+
26922698
/*
26932699
* Note that as a general rule, the high half of the MSRs (bits in
26942700
* the control fields which may be 1) should be initialized by the
@@ -2713,13 +2719,11 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
27132719
msrs->pinbased_ctls_high &=
27142720
PIN_BASED_EXT_INTR_MASK |
27152721
PIN_BASED_NMI_EXITING |
2716-
PIN_BASED_VIRTUAL_NMIS;
2722+
PIN_BASED_VIRTUAL_NMIS |
2723+
(apicv ? PIN_BASED_POSTED_INTR : 0);
27172724
msrs->pinbased_ctls_high |=
27182725
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
27192726
PIN_BASED_VMX_PREEMPTION_TIMER;
2720-
if (apicv)
2721-
msrs->pinbased_ctls_high |=
2722-
PIN_BASED_POSTED_INTR;
27232727

27242728
/* exit controls */
27252729
rdmsr(MSR_IA32_VMX_EXIT_CTLS,
@@ -3231,7 +3235,16 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
32313235

32323236
static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
32333237
{
3234-
return 1;
3238+
switch (msr->index) {
3239+
case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
3240+
if (!nested)
3241+
return 1;
3242+
return vmx_get_vmx_msr(&vmcs_config.nested, msr->index, &msr->data);
3243+
default:
3244+
return 1;
3245+
}
3246+
3247+
return 0;
32353248
}
32363249

32373250
/*
@@ -3697,6 +3710,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
36973710
u32 _vmexit_control = 0;
36983711
u32 _vmentry_control = 0;
36993712

3713+
memset(vmcs_conf, 0, sizeof(*vmcs_conf));
37003714
min = CPU_BASED_HLT_EXITING |
37013715
#ifdef CONFIG_X86_64
37023716
CPU_BASED_CR8_LOAD_EXITING |
@@ -7091,6 +7105,7 @@ static __init int hardware_setup(void)
70917105
init_vmcs_shadow_fields();
70927106

70937107
kvm_set_posted_intr_wakeup_handler(wakeup_handler);
7108+
nested_vmx_setup_ctls_msrs(&vmcs_config.nested, enable_apicv);
70947109

70957110
kvm_mce_cap_supported |= MCG_LMCE_P;
70967111

@@ -9822,6 +9837,7 @@ static void __init vmx_check_processor_compat(void *rtn)
98229837
*(int *)rtn = 0;
98239838
if (setup_vmcs_config(&vmcs_conf) < 0)
98249839
*(int *)rtn = -EIO;
9840+
nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, enable_apicv);
98259841
if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) {
98269842
printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n",
98279843
smp_processor_id());

arch/x86/kvm/x86.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,25 @@ static unsigned num_emulated_msrs;
10561056
* can be used by a hypervisor to validate requested CPU features.
10571057
*/
10581058
static u32 msr_based_features[] = {
1059+
MSR_IA32_VMX_BASIC,
1060+
MSR_IA32_VMX_TRUE_PINBASED_CTLS,
1061+
MSR_IA32_VMX_PINBASED_CTLS,
1062+
MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
1063+
MSR_IA32_VMX_PROCBASED_CTLS,
1064+
MSR_IA32_VMX_TRUE_EXIT_CTLS,
1065+
MSR_IA32_VMX_EXIT_CTLS,
1066+
MSR_IA32_VMX_TRUE_ENTRY_CTLS,
1067+
MSR_IA32_VMX_ENTRY_CTLS,
1068+
MSR_IA32_VMX_MISC,
1069+
MSR_IA32_VMX_CR0_FIXED0,
1070+
MSR_IA32_VMX_CR0_FIXED1,
1071+
MSR_IA32_VMX_CR4_FIXED0,
1072+
MSR_IA32_VMX_CR4_FIXED1,
1073+
MSR_IA32_VMX_VMCS_ENUM,
1074+
MSR_IA32_VMX_PROCBASED_CTLS2,
1075+
MSR_IA32_VMX_EPT_VPID_CAP,
1076+
MSR_IA32_VMX_VMFUNC,
1077+
10591078
MSR_F10H_DECFG,
10601079
MSR_IA32_UCODE_REV,
10611080
};

0 commit comments

Comments
 (0)