@@ -1251,21 +1251,32 @@ static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask)
12511251
12521252static int vmx_restore_vmx_basic (struct vcpu_vmx * vmx , u64 data )
12531253{
1254- const u64 feature_and_reserved =
1255- /* feature (except bit 48; see below) */
1256- BIT_ULL (49 ) | BIT_ULL (54 ) | BIT_ULL (55 ) |
1257- /* reserved */
1258- BIT_ULL (31 ) | GENMASK_ULL (47 , 45 ) | GENMASK_ULL (63 , 56 );
1254+ const u64 feature_bits = VMX_BASIC_DUAL_MONITOR_TREATMENT |
1255+ VMX_BASIC_INOUT |
1256+ VMX_BASIC_TRUE_CTLS ;
1257+
1258+ const u64 reserved_bits = GENMASK_ULL (63 , 56 ) |
1259+ GENMASK_ULL (47 , 45 ) |
1260+ BIT_ULL (31 );
1261+
12591262 u64 vmx_basic = vmcs_config .nested .basic ;
12601263
1261- if (!is_bitwise_subset (vmx_basic , data , feature_and_reserved ))
1264+ BUILD_BUG_ON (feature_bits & reserved_bits );
1265+
1266+ /*
1267+ * Except for 32BIT_PHYS_ADDR_ONLY, which is an anti-feature bit (has
1268+ * inverted polarity), the incoming value must not set feature bits or
1269+ * reserved bits that aren't allowed/supported by KVM. Fields, i.e.
1270+ * multi-bit values, are explicitly checked below.
1271+ */
1272+ if (!is_bitwise_subset (vmx_basic , data , feature_bits | reserved_bits ))
12621273 return - EINVAL ;
12631274
12641275 /*
12651276 * KVM does not emulate a version of VMX that constrains physical
12661277 * addresses of VMX structures (e.g. VMCS) to 32-bits.
12671278 */
1268- if (data & BIT_ULL ( 48 ) )
1279+ if (data & VMX_BASIC_32BIT_PHYS_ADDR_ONLY )
12691280 return - EINVAL ;
12701281
12711282 if (vmx_basic_vmcs_revision_id (vmx_basic ) !=
@@ -1334,16 +1345,29 @@ vmx_restore_control_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data)
13341345
13351346static int vmx_restore_vmx_misc (struct vcpu_vmx * vmx , u64 data )
13361347{
1337- const u64 feature_and_reserved_bits =
1338- /* feature */
1339- BIT_ULL (5 ) | GENMASK_ULL (8 , 6 ) | BIT_ULL (14 ) | BIT_ULL (15 ) |
1340- BIT_ULL (28 ) | BIT_ULL (29 ) | BIT_ULL (30 ) |
1341- /* reserved */
1342- GENMASK_ULL (13 , 9 ) | BIT_ULL (31 );
1348+ const u64 feature_bits = VMX_MISC_SAVE_EFER_LMA |
1349+ VMX_MISC_ACTIVITY_HLT |
1350+ VMX_MISC_ACTIVITY_SHUTDOWN |
1351+ VMX_MISC_ACTIVITY_WAIT_SIPI |
1352+ VMX_MISC_INTEL_PT |
1353+ VMX_MISC_RDMSR_IN_SMM |
1354+ VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
1355+ VMX_MISC_VMXOFF_BLOCK_SMI |
1356+ VMX_MISC_ZERO_LEN_INS ;
1357+
1358+ const u64 reserved_bits = BIT_ULL (31 ) | GENMASK_ULL (13 , 9 );
1359+
13431360 u64 vmx_misc = vmx_control_msr (vmcs_config .nested .misc_low ,
13441361 vmcs_config .nested .misc_high );
13451362
1346- if (!is_bitwise_subset (vmx_misc , data , feature_and_reserved_bits ))
1363+ BUILD_BUG_ON (feature_bits & reserved_bits );
1364+
1365+ /*
1366+ * The incoming value must not set feature bits or reserved bits that
1367+ * aren't allowed/supported by KVM. Fields, i.e. multi-bit values, are
1368+ * explicitly checked below.
1369+ */
1370+ if (!is_bitwise_subset (vmx_misc , data , feature_bits | reserved_bits ))
13471371 return - EINVAL ;
13481372
13491373 if ((vmx -> nested .msrs .pinbased_ctls_high &
@@ -7051,7 +7075,7 @@ static void nested_vmx_setup_misc_data(struct vmcs_config *vmcs_conf,
70517075{
70527076 msrs -> misc_low = (u32 )vmcs_conf -> misc & VMX_MISC_SAVE_EFER_LMA ;
70537077 msrs -> misc_low |=
7054- MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
7078+ VMX_MISC_VMWRITE_SHADOW_RO_FIELDS |
70557079 VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE |
70567080 VMX_MISC_ACTIVITY_HLT |
70577081 VMX_MISC_ACTIVITY_WAIT_SIPI ;
@@ -7066,12 +7090,10 @@ static void nested_vmx_setup_basic(struct nested_vmx_msrs *msrs)
70667090 * guest, and the VMCS structure we give it - not about the
70677091 * VMX support of the underlying hardware.
70687092 */
7069- msrs -> basic =
7070- VMCS12_REVISION |
7071- VMX_BASIC_TRUE_CTLS |
7072- ((u64 )VMCS12_SIZE << VMX_BASIC_VMCS_SIZE_SHIFT ) |
7073- (VMX_BASIC_MEM_TYPE_WB << VMX_BASIC_MEM_TYPE_SHIFT );
7093+ msrs -> basic = vmx_basic_encode_vmcs_info (VMCS12_REVISION , VMCS12_SIZE ,
7094+ X86_MEMTYPE_WB );
70747095
7096+ msrs -> basic |= VMX_BASIC_TRUE_CTLS ;
70757097 if (cpu_has_vmx_basic_inout ())
70767098 msrs -> basic |= VMX_BASIC_INOUT ;
70777099}
0 commit comments