Skip to content

Commit a98113b

Browse files
gzhai7lijinxia
authored andcommitted
HV: fully check VMCS control settings
Reshuffle VMX init code, and check both allowed 0-settings and 1-settings of related MSR to make the final VMCS control value. Signed-off-by: Edwin Zhai <edwin.zhai@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent ae8836d commit a98113b

File tree

1 file changed

+49
-22
lines changed

1 file changed

+49
-22
lines changed

hypervisor/arch/x86/vmx.c

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,34 @@ static void init_host_state(__unused struct vcpu *vcpu)
12451245
pr_dbg("VMX_HOST_IA32_SYSENTER_EIP: 0x%016llx ", value);
12461246
}
12471247

1248+
static uint32_t check_vmx_ctrl(uint32_t msr, uint32_t ctrl_req)
1249+
{
1250+
uint64_t vmx_msr;
1251+
uint32_t vmx_msr_low, vmx_msr_high;
1252+
uint32_t ctrl = ctrl_req;
1253+
1254+
vmx_msr = msr_read(msr);
1255+
vmx_msr_low = (uint32_t)vmx_msr;
1256+
vmx_msr_high = (uint32_t)(vmx_msr >> 32);
1257+
pr_dbg("VMX_PIN_VM_EXEC_CONTROLS:low=0x%x, high=0x%x\n",
1258+
vmx_msr_low, vmx_msr_high);
1259+
1260+
/* high 32b: must 0 setting
1261+
* low 32b: must 1 setting
1262+
*/
1263+
ctrl &= vmx_msr_high;
1264+
ctrl |= vmx_msr_low;
1265+
1266+
if (ctrl_req & ~ctrl) {
1267+
pr_err("VMX ctrl 0x%x not fully enabled: "
1268+
"request 0x%x but get 0x%x\n",
1269+
msr, ctrl_req, ctrl);
1270+
}
1271+
1272+
return ctrl;
1273+
1274+
}
1275+
12481276
static void init_exec_ctrl(struct vcpu *vcpu)
12491277
{
12501278
uint32_t value32;
@@ -1259,11 +1287,9 @@ static void init_exec_ctrl(struct vcpu *vcpu)
12591287
/* Set up VM Execution control to enable Set VM-exits on external
12601288
* interrupts preemption timer - pg 2899 24.6.1
12611289
*/
1262-
value32 = (uint32_t)msr_read(MSR_IA32_VMX_PINBASED_CTLS);
1263-
1264-
12651290
/* enable external interrupt VM Exit */
1266-
value32 |= VMX_PINBASED_CTLS_IRQ_EXIT;
1291+
value32 = check_vmx_ctrl(MSR_IA32_VMX_PINBASED_CTLS,
1292+
VMX_PINBASED_CTLS_IRQ_EXIT);
12671293

12681294
exec_vmwrite32(VMX_PIN_VM_EXEC_CONTROLS, value32);
12691295
pr_dbg("VMX_PIN_VM_EXEC_CONTROLS: 0x%x ", value32);
@@ -1279,12 +1305,12 @@ static void init_exec_ctrl(struct vcpu *vcpu)
12791305
/* These are bits 1,4-6,8,13-16, and 26, the corresponding bits of
12801306
* the IA32_VMX_PROCBASED_CTRLS MSR are always read as 1 --- A.3.2
12811307
*/
1282-
value32 = (uint32_t)msr_read(MSR_IA32_VMX_PROCBASED_CTLS);
1283-
value32 |= (VMX_PROCBASED_CTLS_TSC_OFF |
1284-
/* VMX_PROCBASED_CTLS_RDTSC | */
1285-
VMX_PROCBASED_CTLS_IO_BITMAP |
1286-
VMX_PROCBASED_CTLS_MSR_BITMAP |
1287-
VMX_PROCBASED_CTLS_SECONDARY);
1308+
value32 = check_vmx_ctrl(MSR_IA32_VMX_PROCBASED_CTLS,
1309+
VMX_PROCBASED_CTLS_TSC_OFF |
1310+
/* VMX_PROCBASED_CTLS_RDTSC | */
1311+
VMX_PROCBASED_CTLS_IO_BITMAP |
1312+
VMX_PROCBASED_CTLS_MSR_BITMAP |
1313+
VMX_PROCBASED_CTLS_SECONDARY);
12881314

12891315
/*Disable VM_EXIT for CR3 access*/
12901316
value32 &= ~(VMX_PROCBASED_CTLS_CR3_LOAD |
@@ -1311,8 +1337,8 @@ static void init_exec_ctrl(struct vcpu *vcpu)
13111337
* 24.6.2. Set up for: * Enable EPT * Enable RDTSCP * Unrestricted
13121338
* guest (optional)
13131339
*/
1314-
value32 = (uint32_t)msr_read(MSR_IA32_VMX_PROCBASED_CTLS2);
1315-
value32 |= (VMX_PROCBASED_CTLS2_EPT |
1340+
value32 = check_vmx_ctrl(MSR_IA32_VMX_PROCBASED_CTLS2,
1341+
VMX_PROCBASED_CTLS2_EPT |
13161342
VMX_PROCBASED_CTLS2_RDTSCP |
13171343
VMX_PROCBASED_CTLS2_UNRESTRICT);
13181344

@@ -1466,13 +1492,14 @@ static void init_entry_ctrl(__unused struct vcpu *vcpu)
14661492
* on VM entry processor is in IA32e 64 bitmode * Start guest with host
14671493
* IA32_PAT and IA32_EFER
14681494
*/
1469-
value32 = (uint32_t)msr_read(MSR_IA32_VMX_ENTRY_CTLS);
1495+
value32 = (VMX_ENTRY_CTLS_LOAD_EFER |
1496+
VMX_ENTRY_CTLS_LOAD_PAT);
1497+
14701498
if (get_vcpu_mode(vcpu) == CPU_MODE_64BIT) {
14711499
value32 |= (VMX_ENTRY_CTLS_IA32E_MODE);
14721500
}
14731501

1474-
value32 |= (VMX_ENTRY_CTLS_LOAD_EFER |
1475-
VMX_ENTRY_CTLS_LOAD_PAT);
1502+
value32 = check_vmx_ctrl(MSR_IA32_VMX_ENTRY_CTLS, value32);
14761503

14771504
exec_vmwrite32(VMX_ENTRY_CONTROLS, value32);
14781505
pr_dbg("VMX_ENTRY_CONTROLS: 0x%x ", value32);
@@ -1509,13 +1536,13 @@ static void init_exit_ctrl(__unused struct vcpu *vcpu)
15091536
* Enable saving and loading of IA32_PAT and IA32_EFER on VMEXIT Enable
15101537
* saving of pre-emption timer on VMEXIT
15111538
*/
1512-
value32 = (uint32_t)msr_read(MSR_IA32_VMX_EXIT_CTLS);
1513-
value32 |= (VMX_EXIT_CTLS_ACK_IRQ |
1514-
VMX_EXIT_CTLS_SAVE_PAT |
1515-
VMX_EXIT_CTLS_LOAD_PAT |
1516-
VMX_EXIT_CTLS_LOAD_EFER |
1517-
VMX_EXIT_CTLS_SAVE_EFER |
1518-
VMX_EXIT_CTLS_HOST_ADDR64);
1539+
value32 = check_vmx_ctrl(MSR_IA32_VMX_EXIT_CTLS,
1540+
VMX_EXIT_CTLS_ACK_IRQ |
1541+
VMX_EXIT_CTLS_SAVE_PAT |
1542+
VMX_EXIT_CTLS_LOAD_PAT |
1543+
VMX_EXIT_CTLS_LOAD_EFER |
1544+
VMX_EXIT_CTLS_SAVE_EFER |
1545+
VMX_EXIT_CTLS_HOST_ADDR64);
15191546

15201547
exec_vmwrite32(VMX_EXIT_CONTROLS, value32);
15211548
pr_dbg("VMX_EXIT_CONTROL: 0x%x ", value32);

0 commit comments

Comments
 (0)