Skip to content

Commit 81c0e99

Browse files
Sean ChristophersonSomasundaram Krishnasamy
authored andcommitted
KVM: nVMX: Remove non-functional "support" for CR3 target values
Remove all references to cr3_target_value[0-3] and replace the fields in vmcs12 with "dead_space" to preserve the vmcs12 layout. KVM doesn't support emulating CR3-target values, despite a variety of code that implies otherwise, as KVM unconditionally reports '0' for the number of supported CR3-target values. This technically fixes a bug where KVM would incorrectly allow VMREAD and VMWRITE to nonexistent fields, i.e. cr3_target_value[0-3]. Per Intel's SDM, the number of supported CR3-target values reported in VMX_MISC also enumerates the existence of the associated VMCS fields: If a future implementation supports more than 4 CR3-target values, they will be encoded consecutively following the 4 encodings given here. Alternatively, the "bug" could be fixed by actually advertisting support for 4 CR3-target values, but that'd likely just enable kvm-unit-tests given that no one has complained about lack of support for going on ten years, e.g. KVM, Xen and HyperV don't use CR3-target values. Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> (cherry picked from commit b8d295f) Orabug: 31722724 Conflicts: Documentation/virt/kvm/nested-vmx.rst (docs converted later to the ReST format) arch/x86/kvm/vmx/vmx.c (contextual) Signed-off-by: Maciej S. Szmigiero <[email protected]> Reviewed-by: Mihai Carabas <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 40bbc9f commit 81c0e99

File tree

6 files changed

+3
-50
lines changed

6 files changed

+3
-50
lines changed

Documentation/virtual/kvm/nested-vmx.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,7 @@ struct shadow_vmcs is ever changed.
111111
natural_width cr4_guest_host_mask;
112112
natural_width cr0_read_shadow;
113113
natural_width cr4_read_shadow;
114-
natural_width cr3_target_value0;
115-
natural_width cr3_target_value1;
116-
natural_width cr3_target_value2;
117-
natural_width cr3_target_value3;
114+
natural_width dead_space[4]; /* Last remnants of cr3_target_value[0-3]. */
118115
natural_width exit_qualification;
119116
natural_width guest_linear_address;
120117
natural_width guest_cr0;

arch/x86/kvm/vmx/evmcs.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,6 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] = {
158158
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
159159
EVMCS1_FIELD(VM_ENTRY_MSR_LOAD_ADDR, vm_entry_msr_load_addr,
160160
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
161-
EVMCS1_FIELD(CR3_TARGET_VALUE0, cr3_target_value0,
162-
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
163-
EVMCS1_FIELD(CR3_TARGET_VALUE1, cr3_target_value1,
164-
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
165-
EVMCS1_FIELD(CR3_TARGET_VALUE2, cr3_target_value2,
166-
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
167-
EVMCS1_FIELD(CR3_TARGET_VALUE3, cr3_target_value3,
168-
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL),
169161

170162
/* 32 bit rw */
171163
EVMCS1_FIELD(TPR_THRESHOLD, tpr_threshold,

arch/x86/kvm/vmx/nested.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,10 +1569,6 @@ static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx)
15691569
* vmcs12->vm_exit_msr_store_addr = evmcs->vm_exit_msr_store_addr;
15701570
* vmcs12->vm_exit_msr_load_addr = evmcs->vm_exit_msr_load_addr;
15711571
* vmcs12->vm_entry_msr_load_addr = evmcs->vm_entry_msr_load_addr;
1572-
* vmcs12->cr3_target_value0 = evmcs->cr3_target_value0;
1573-
* vmcs12->cr3_target_value1 = evmcs->cr3_target_value1;
1574-
* vmcs12->cr3_target_value2 = evmcs->cr3_target_value2;
1575-
* vmcs12->cr3_target_value3 = evmcs->cr3_target_value3;
15761572
* vmcs12->page_fault_error_code_mask =
15771573
* evmcs->page_fault_error_code_mask;
15781574
* vmcs12->page_fault_error_code_match =
@@ -1646,10 +1642,6 @@ static int copy_vmcs12_to_enlightened(struct vcpu_vmx *vmx)
16461642
* evmcs->vm_exit_msr_store_addr = vmcs12->vm_exit_msr_store_addr;
16471643
* evmcs->vm_exit_msr_load_addr = vmcs12->vm_exit_msr_load_addr;
16481644
* evmcs->vm_entry_msr_load_addr = vmcs12->vm_entry_msr_load_addr;
1649-
* evmcs->cr3_target_value0 = vmcs12->cr3_target_value0;
1650-
* evmcs->cr3_target_value1 = vmcs12->cr3_target_value1;
1651-
* evmcs->cr3_target_value2 = vmcs12->cr3_target_value2;
1652-
* evmcs->cr3_target_value3 = vmcs12->cr3_target_value3;
16531645
* evmcs->tpr_threshold = vmcs12->tpr_threshold;
16541646
* evmcs->virtual_processor_id = vmcs12->virtual_processor_id;
16551647
* evmcs->exception_bitmap = vmcs12->exception_bitmap;
@@ -5079,15 +5071,6 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
50795071
return true;
50805072
break;
50815073
case 3:
5082-
if ((vmcs12->cr3_target_count >= 1 &&
5083-
vmcs12->cr3_target_value0 == val) ||
5084-
(vmcs12->cr3_target_count >= 2 &&
5085-
vmcs12->cr3_target_value1 == val) ||
5086-
(vmcs12->cr3_target_count >= 3 &&
5087-
vmcs12->cr3_target_value2 == val) ||
5088-
(vmcs12->cr3_target_count >= 4 &&
5089-
vmcs12->cr3_target_value3 == val))
5090-
return false;
50915074
if (nested_cpu_has(vmcs12, CPU_BASED_CR3_LOAD_EXITING))
50925075
return true;
50935076
break;

arch/x86/kvm/vmx/vmcs12.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@ const unsigned short vmcs_field_to_offset_table[] = {
115115
FIELD(CR4_GUEST_HOST_MASK, cr4_guest_host_mask),
116116
FIELD(CR0_READ_SHADOW, cr0_read_shadow),
117117
FIELD(CR4_READ_SHADOW, cr4_read_shadow),
118-
FIELD(CR3_TARGET_VALUE0, cr3_target_value0),
119-
FIELD(CR3_TARGET_VALUE1, cr3_target_value1),
120-
FIELD(CR3_TARGET_VALUE2, cr3_target_value2),
121-
FIELD(CR3_TARGET_VALUE3, cr3_target_value3),
122118
FIELD(EXIT_QUALIFICATION, exit_qualification),
123119
FIELD(GUEST_LINEAR_ADDRESS, guest_linear_address),
124120
FIELD(GUEST_CR0, guest_cr0),

arch/x86/kvm/vmx/vmcs12.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ struct __packed vmcs12 {
8080
natural_width cr4_guest_host_mask;
8181
natural_width cr0_read_shadow;
8282
natural_width cr4_read_shadow;
83-
natural_width cr3_target_value0;
84-
natural_width cr3_target_value1;
85-
natural_width cr3_target_value2;
86-
natural_width cr3_target_value3;
83+
natural_width dead_space[4]; /* Last remnants of cr3_target_value[0-3]. */
8784
natural_width exit_qualification;
8885
natural_width guest_linear_address;
8986
natural_width guest_cr0;
@@ -262,10 +259,7 @@ static inline void vmx_check_vmcs12_offsets(void)
262259
CHECK_OFFSET(cr4_guest_host_mask, 352);
263260
CHECK_OFFSET(cr0_read_shadow, 360);
264261
CHECK_OFFSET(cr4_read_shadow, 368);
265-
CHECK_OFFSET(cr3_target_value0, 376);
266-
CHECK_OFFSET(cr3_target_value1, 384);
267-
CHECK_OFFSET(cr3_target_value2, 392);
268-
CHECK_OFFSET(cr3_target_value3, 400);
262+
CHECK_OFFSET(dead_space, 376);
269263
CHECK_OFFSET(exit_qualification, 408);
270264
CHECK_OFFSET(guest_linear_address, 416);
271265
CHECK_OFFSET(guest_cr0, 424);

arch/x86/kvm/vmx/vmx.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5641,7 +5641,6 @@ void dump_vmcs(void)
56415641
u32 secondary_exec_control = 0;
56425642
unsigned long cr4 = vmcs_readl(GUEST_CR4);
56435643
u64 efer = vmcs_read64(GUEST_IA32_EFER);
5644-
int i, n;
56455644

56465645
if (cpu_has_secondary_exec_ctrls())
56475646
secondary_exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
@@ -5758,14 +5757,6 @@ void dump_vmcs(void)
57585757
pr_err("PostedIntrVec = 0x%02x\n", vmcs_read16(POSTED_INTR_NV));
57595758
if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT))
57605759
pr_err("EPT pointer = 0x%016llx\n", vmcs_read64(EPT_POINTER));
5761-
n = vmcs_read32(CR3_TARGET_COUNT);
5762-
for (i = 0; i + 1 < n; i += 4)
5763-
pr_err("CR3 target%u=%016lx target%u=%016lx\n",
5764-
i, vmcs_readl(CR3_TARGET_VALUE0 + i * 2),
5765-
i + 1, vmcs_readl(CR3_TARGET_VALUE0 + i * 2 + 2));
5766-
if (i < n)
5767-
pr_err("CR3 target%u=%016lx\n",
5768-
i, vmcs_readl(CR3_TARGET_VALUE0 + i * 2));
57695760
if (secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
57705761
pr_err("PLE Gap=%08x Window=%08x\n",
57715762
vmcs_read32(PLE_GAP), vmcs_read32(PLE_WINDOW));

0 commit comments

Comments
 (0)