From: Isaku Yamahata <isaku.yamahata@intel.com>
Make the access to the tertiary processor-based VM control an error if the
guest VMX true processor-based controls don't report it.
Without this patch, the KVM unit test_vmread_vmwrite() fails because
vmread()/vmwrite() can succeeds with the index beyond
MSR_IA32_VMX_VMCS_ENUM when the tertiary processor-based VM-executing
controls aren't advertised to the guest.
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
arch/x86/kvm/vmx/nested.c | 20 ++++++++++++++++++++
arch/x86/kvm/vmx/nested.h | 5 +++++
2 files changed, 25 insertions(+)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 65f7260d02df..562b5ffc6433 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5768,6 +5768,16 @@ static int handle_vmresume(struct kvm_vcpu *vcpu)
return nested_vmx_run(vcpu, false);
}
+static bool is_vmcs_field_valid(struct kvm_vcpu *vcpu, unsigned long field)
+{
+ if (!nested_cpu_supports_tertiary_ctls(vcpu) &&
+ (field == TERTIARY_VM_EXEC_CONTROL ||
+ field == TERTIARY_VM_EXEC_CONTROL_HIGH))
+ return false;
+
+ return true;
+}
+
static int handle_vmread(struct kvm_vcpu *vcpu)
{
struct vmcs12 *vmcs12 = is_guest_mode(vcpu) ? get_shadow_vmcs12(vcpu)
@@ -5798,6 +5808,9 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA))
return nested_vmx_failInvalid(vcpu);
+ if (!is_vmcs_field_valid(vcpu, field))
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
offset = get_vmcs12_field_offset(field);
if (offset < 0)
return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
@@ -5922,6 +5935,9 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
+ if (!is_vmcs_field_valid(vcpu, field))
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
offset = get_vmcs12_field_offset(field);
if (offset < 0)
return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
@@ -7170,6 +7186,10 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
kvm_state->hdr.vmx.preemption_timer_deadline;
}
+ if (!nested_cpu_supports_tertiary_ctls(vcpu) &&
+ vmcs12->tertiary_vm_exec_control)
+ goto error_guest_mode;
+
if (nested_vmx_check_controls(vcpu, vmcs12) ||
nested_vmx_check_host_state(vcpu, vmcs12) ||
nested_vmx_check_guest_state(vcpu, vmcs12, &ignored))
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index 6df2cfb20d87..1100a8114dd9 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -157,6 +157,11 @@ static inline bool __nested_cpu_supports_tertiary_ctls(struct nested_vmx_msrs *m
return msrs->procbased_ctls_high & CPU_BASED_ACTIVATE_TERTIARY_CONTROLS;
}
+static inline bool nested_cpu_supports_tertiary_ctls(struct kvm_vcpu *vcpu)
+{
+ return __nested_cpu_supports_tertiary_ctls(&to_vmx(vcpu)->nested.msrs);
+}
+
/* APIC TIMER VIRTUALIZATION requires in-kernel lapic. */
static inline bool nested_cpu_can_support_apic_virt_timer(struct kvm_vcpu *vcpu)
{
--
2.45.2