Skip to content

Commit f6cde92

Browse files
Yu Zhangsean-jc
authored andcommitted
KVM: nVMX: Add helpers to setup VMX control msr configs
nested_vmx_setup_ctls_msrs() is used to set up the various VMX MSR controls for nested VMX. But it is a bit lengthy, just add helpers to setup the configuration of VMX MSRs. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> Link: https://lore.kernel.org/r/20230119141946.585610-2-yu.c.zhang@linux.intel.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent ad36aab commit f6cde92

1 file changed

Lines changed: 74 additions & 33 deletions

File tree

arch/x86/kvm/vmx/nested.c

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6753,36 +6753,9 @@ static u64 nested_vmx_calc_vmcs_enum_msr(void)
67536753
return (u64)max_idx << VMCS_FIELD_INDEX_SHIFT;
67546754
}
67556755

6756-
/*
6757-
* nested_vmx_setup_ctls_msrs() sets up variables containing the values to be
6758-
* returned for the various VMX controls MSRs when nested VMX is enabled.
6759-
* The same values should also be used to verify that vmcs12 control fields are
6760-
* valid during nested entry from L1 to L2.
6761-
* Each of these control msrs has a low and high 32-bit half: A low bit is on
6762-
* if the corresponding bit in the (32-bit) control field *must* be on, and a
6763-
* bit in the high half is on if the corresponding bit in the control field
6764-
* may be on. See also vmx_control_verify().
6765-
*/
6766-
void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
6756+
static void nested_vmx_setup_pinbased_ctls(struct vmcs_config *vmcs_conf,
6757+
struct nested_vmx_msrs *msrs)
67676758
{
6768-
struct nested_vmx_msrs *msrs = &vmcs_conf->nested;
6769-
6770-
/*
6771-
* Note that as a general rule, the high half of the MSRs (bits in
6772-
* the control fields which may be 1) should be initialized by the
6773-
* intersection of the underlying hardware's MSR (i.e., features which
6774-
* can be supported) and the list of features we want to expose -
6775-
* because they are known to be properly supported in our code.
6776-
* Also, usually, the low half of the MSRs (bits which must be 1) can
6777-
* be set to 0, meaning that L1 may turn off any of these bits. The
6778-
* reason is that if one of these bits is necessary, it will appear
6779-
* in vmcs01 and prepare_vmcs02, when it bitwise-or's the control
6780-
* fields of vmcs01 and vmcs02, will turn these bits off - and
6781-
* nested_vmx_l1_wants_exit() will not pass related exits to L1.
6782-
* These rules have exceptions below.
6783-
*/
6784-
6785-
/* pin-based controls */
67866759
msrs->pinbased_ctls_low =
67876760
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR;
67886761

@@ -6795,8 +6768,11 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
67956768
msrs->pinbased_ctls_high |=
67966769
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
67976770
PIN_BASED_VMX_PREEMPTION_TIMER;
6771+
}
67986772

6799-
/* exit controls */
6773+
static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf,
6774+
struct nested_vmx_msrs *msrs)
6775+
{
68006776
msrs->exit_ctls_low =
68016777
VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR;
68026778

@@ -6815,8 +6791,11 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
68156791

68166792
/* We support free control of debug control saving. */
68176793
msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
6794+
}
68186795

6819-
/* entry controls */
6796+
static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf,
6797+
struct nested_vmx_msrs *msrs)
6798+
{
68206799
msrs->entry_ctls_low =
68216800
VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR;
68226801

@@ -6832,8 +6811,11 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
68326811

68336812
/* We support free control of debug control loading. */
68346813
msrs->entry_ctls_low &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
6814+
}
68356815

6836-
/* cpu-based controls */
6816+
static void nested_vmx_setup_cpubased_ctls(struct vmcs_config *vmcs_conf,
6817+
struct nested_vmx_msrs *msrs)
6818+
{
68376819
msrs->procbased_ctls_low =
68386820
CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR;
68396821

@@ -6865,7 +6847,12 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
68656847
/* We support free control of CR3 access interception. */
68666848
msrs->procbased_ctls_low &=
68676849
~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING);
6850+
}
68686851

6852+
static void nested_vmx_setup_secondary_ctls(u32 ept_caps,
6853+
struct vmcs_config *vmcs_conf,
6854+
struct nested_vmx_msrs *msrs)
6855+
{
68696856
msrs->secondary_ctls_low = 0;
68706857

68716858
msrs->secondary_ctls_high = vmcs_conf->cpu_based_2nd_exec_ctrl;
@@ -6943,16 +6930,22 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
69436930

69446931
if (enable_sgx)
69456932
msrs->secondary_ctls_high |= SECONDARY_EXEC_ENCLS_EXITING;
6933+
}
69466934

6947-
/* miscellaneous data */
6935+
static void nested_vmx_setup_misc_data(struct vmcs_config *vmcs_conf,
6936+
struct nested_vmx_msrs *msrs)
6937+
{
69486938
msrs->misc_low = (u32)vmcs_conf->misc & VMX_MISC_SAVE_EFER_LMA;
69496939
msrs->misc_low |=
69506940
MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
69516941
VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE |
69526942
VMX_MISC_ACTIVITY_HLT |
69536943
VMX_MISC_ACTIVITY_WAIT_SIPI;
69546944
msrs->misc_high = 0;
6945+
}
69556946

6947+
static void nested_vmx_setup_basic(struct nested_vmx_msrs *msrs)
6948+
{
69566949
/*
69576950
* This MSR reports some information about VMX support. We
69586951
* should return information about the VMX we emulate for the
@@ -6967,7 +6960,10 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
69676960

69686961
if (cpu_has_vmx_basic_inout())
69696962
msrs->basic |= VMX_BASIC_INOUT;
6963+
}
69706964

6965+
static void nested_vmx_setup_cr_fixed(struct nested_vmx_msrs *msrs)
6966+
{
69716967
/*
69726968
* These MSRs specify bits which the guest must keep fixed on
69736969
* while L1 is in VMXON mode (in L1's root mode, or running an L2).
@@ -6984,6 +6980,51 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
69846980

69856981
if (vmx_umip_emulated())
69866982
msrs->cr4_fixed1 |= X86_CR4_UMIP;
6983+
}
6984+
6985+
/*
6986+
* nested_vmx_setup_ctls_msrs() sets up variables containing the values to be
6987+
* returned for the various VMX controls MSRs when nested VMX is enabled.
6988+
* The same values should also be used to verify that vmcs12 control fields are
6989+
* valid during nested entry from L1 to L2.
6990+
* Each of these control msrs has a low and high 32-bit half: A low bit is on
6991+
* if the corresponding bit in the (32-bit) control field *must* be on, and a
6992+
* bit in the high half is on if the corresponding bit in the control field
6993+
* may be on. See also vmx_control_verify().
6994+
*/
6995+
void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps)
6996+
{
6997+
struct nested_vmx_msrs *msrs = &vmcs_conf->nested;
6998+
6999+
/*
7000+
* Note that as a general rule, the high half of the MSRs (bits in
7001+
* the control fields which may be 1) should be initialized by the
7002+
* intersection of the underlying hardware's MSR (i.e., features which
7003+
* can be supported) and the list of features we want to expose -
7004+
* because they are known to be properly supported in our code.
7005+
* Also, usually, the low half of the MSRs (bits which must be 1) can
7006+
* be set to 0, meaning that L1 may turn off any of these bits. The
7007+
* reason is that if one of these bits is necessary, it will appear
7008+
* in vmcs01 and prepare_vmcs02, when it bitwise-or's the control
7009+
* fields of vmcs01 and vmcs02, will turn these bits off - and
7010+
* nested_vmx_l1_wants_exit() will not pass related exits to L1.
7011+
* These rules have exceptions below.
7012+
*/
7013+
nested_vmx_setup_pinbased_ctls(vmcs_conf, msrs);
7014+
7015+
nested_vmx_setup_exit_ctls(vmcs_conf, msrs);
7016+
7017+
nested_vmx_setup_entry_ctls(vmcs_conf, msrs);
7018+
7019+
nested_vmx_setup_cpubased_ctls(vmcs_conf, msrs);
7020+
7021+
nested_vmx_setup_secondary_ctls(ept_caps, vmcs_conf, msrs);
7022+
7023+
nested_vmx_setup_misc_data(vmcs_conf, msrs);
7024+
7025+
nested_vmx_setup_basic(msrs);
7026+
7027+
nested_vmx_setup_cr_fixed(msrs);
69877028

69887029
msrs->vmcs_enum = nested_vmx_calc_vmcs_enum_msr();
69897030
}

0 commit comments

Comments
 (0)