aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c110
1 files changed, 108 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 263be2debde8..3a727ca02f24 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -144,6 +144,15 @@ struct shared_msr_entry {
144 u64 mask; 144 u64 mask;
145}; 145};
146 146
147/*
148 * The nested_vmx structure is part of vcpu_vmx, and holds information we need
149 * for correct emulation of VMX (i.e., nested VMX) on this vcpu.
150 */
151struct nested_vmx {
152 /* Has the level1 guest done vmxon? */
153 bool vmxon;
154};
155
147struct vcpu_vmx { 156struct vcpu_vmx {
148 struct kvm_vcpu vcpu; 157 struct kvm_vcpu vcpu;
149 unsigned long host_rsp; 158 unsigned long host_rsp;
@@ -203,6 +212,9 @@ struct vcpu_vmx {
203 u32 exit_reason; 212 u32 exit_reason;
204 213
205 bool rdtscp_enabled; 214 bool rdtscp_enabled;
215
216 /* Support for a guest hypervisor (nested VMX) */
217 struct nested_vmx nested;
206}; 218};
207 219
208enum segment_cache_field { 220enum segment_cache_field {
@@ -3934,6 +3946,99 @@ static int handle_invalid_op(struct kvm_vcpu *vcpu)
3934} 3946}
3935 3947
3936/* 3948/*
3949 * Emulate the VMXON instruction.
3950 * Currently, we just remember that VMX is active, and do not save or even
3951 * inspect the argument to VMXON (the so-called "VMXON pointer") because we
3952 * do not currently need to store anything in that guest-allocated memory
3953 * region. Consequently, VMCLEAR and VMPTRLD also do not verify that the their
3954 * argument is different from the VMXON pointer (which the spec says they do).
3955 */
3956static int handle_vmon(struct kvm_vcpu *vcpu)
3957{
3958 struct kvm_segment cs;
3959 struct vcpu_vmx *vmx = to_vmx(vcpu);
3960
3961 /* The Intel VMX Instruction Reference lists a bunch of bits that
3962 * are prerequisite to running VMXON, most notably cr4.VMXE must be
3963 * set to 1 (see vmx_set_cr4() for when we allow the guest to set this).
3964 * Otherwise, we should fail with #UD. We test these now:
3965 */
3966 if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE) ||
3967 !kvm_read_cr0_bits(vcpu, X86_CR0_PE) ||
3968 (vmx_get_rflags(vcpu) & X86_EFLAGS_VM)) {
3969 kvm_queue_exception(vcpu, UD_VECTOR);
3970 return 1;
3971 }
3972
3973 vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
3974 if (is_long_mode(vcpu) && !cs.l) {
3975 kvm_queue_exception(vcpu, UD_VECTOR);
3976 return 1;
3977 }
3978
3979 if (vmx_get_cpl(vcpu)) {
3980 kvm_inject_gp(vcpu, 0);
3981 return 1;
3982 }
3983
3984 vmx->nested.vmxon = true;
3985
3986 skip_emulated_instruction(vcpu);
3987 return 1;
3988}
3989
3990/*
3991 * Intel's VMX Instruction Reference specifies a common set of prerequisites
3992 * for running VMX instructions (except VMXON, whose prerequisites are
3993 * slightly different). It also specifies what exception to inject otherwise.
3994 */
3995static int nested_vmx_check_permission(struct kvm_vcpu *vcpu)
3996{
3997 struct kvm_segment cs;
3998 struct vcpu_vmx *vmx = to_vmx(vcpu);
3999
4000 if (!vmx->nested.vmxon) {
4001 kvm_queue_exception(vcpu, UD_VECTOR);
4002 return 0;
4003 }
4004
4005 vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
4006 if ((vmx_get_rflags(vcpu) & X86_EFLAGS_VM) ||
4007 (is_long_mode(vcpu) && !cs.l)) {
4008 kvm_queue_exception(vcpu, UD_VECTOR);
4009 return 0;
4010 }
4011
4012 if (vmx_get_cpl(vcpu)) {
4013 kvm_inject_gp(vcpu, 0);
4014 return 0;
4015 }
4016
4017 return 1;
4018}
4019
4020/*
4021 * Free whatever needs to be freed from vmx->nested when L1 goes down, or
4022 * just stops using VMX.
4023 */
4024static void free_nested(struct vcpu_vmx *vmx)
4025{
4026 if (!vmx->nested.vmxon)
4027 return;
4028 vmx->nested.vmxon = false;
4029}
4030
4031/* Emulate the VMXOFF instruction */
4032static int handle_vmoff(struct kvm_vcpu *vcpu)
4033{
4034 if (!nested_vmx_check_permission(vcpu))
4035 return 1;
4036 free_nested(to_vmx(vcpu));
4037 skip_emulated_instruction(vcpu);
4038 return 1;
4039}
4040
4041/*
3937 * The exit handlers return 1 if the exit was handled fully and guest execution 4042 * The exit handlers return 1 if the exit was handled fully and guest execution
3938 * may resume. Otherwise they set the kvm_run parameter to indicate what needs 4043 * may resume. Otherwise they set the kvm_run parameter to indicate what needs
3939 * to be done to userspace and return 0. 4044 * to be done to userspace and return 0.
@@ -3961,8 +4066,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
3961 [EXIT_REASON_VMREAD] = handle_vmx_insn, 4066 [EXIT_REASON_VMREAD] = handle_vmx_insn,
3962 [EXIT_REASON_VMRESUME] = handle_vmx_insn, 4067 [EXIT_REASON_VMRESUME] = handle_vmx_insn,
3963 [EXIT_REASON_VMWRITE] = handle_vmx_insn, 4068 [EXIT_REASON_VMWRITE] = handle_vmx_insn,
3964 [EXIT_REASON_VMOFF] = handle_vmx_insn, 4069 [EXIT_REASON_VMOFF] = handle_vmoff,
3965 [EXIT_REASON_VMON] = handle_vmx_insn, 4070 [EXIT_REASON_VMON] = handle_vmon,
3966 [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, 4071 [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold,
3967 [EXIT_REASON_APIC_ACCESS] = handle_apic_access, 4072 [EXIT_REASON_APIC_ACCESS] = handle_apic_access,
3968 [EXIT_REASON_WBINVD] = handle_wbinvd, 4073 [EXIT_REASON_WBINVD] = handle_wbinvd,
@@ -4363,6 +4468,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
4363 struct vcpu_vmx *vmx = to_vmx(vcpu); 4468 struct vcpu_vmx *vmx = to_vmx(vcpu);
4364 4469
4365 free_vpid(vmx); 4470 free_vpid(vmx);
4471 free_nested(vmx);
4366 free_loaded_vmcs(vmx->loaded_vmcs); 4472 free_loaded_vmcs(vmx->loaded_vmcs);
4367 kfree(vmx->guest_msrs); 4473 kfree(vmx->guest_msrs);
4368 kvm_vcpu_uninit(vcpu); 4474 kvm_vcpu_uninit(vcpu);