aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorBandan Das <bsd@redhat.com>2014-05-06 02:19:15 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-05-06 12:59:57 -0400
commit19677e32fe7d6913e07ce80f6f3dc7663ac7fe67 (patch)
tree28e68e063a8e84b22e58e1428fa49ec307834575 /arch/x86/kvm
parent2ce316f0b9b2103e27585180b6aa6f17f0175f0e (diff)
KVM: nVMX: rearrange get_vmx_mem_address
Our common function for vmptr checks (in 2/4) needs to fetch the memory address Signed-off-by: Bandan Das <bsd@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/vmx.c106
1 files changed, 53 insertions, 53 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 72b8012991b9..917a15efc45b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5792,6 +5792,59 @@ static enum hrtimer_restart vmx_preemption_timer_fn(struct hrtimer *timer)
5792} 5792}
5793 5793
5794/* 5794/*
5795 * Decode the memory-address operand of a vmx instruction, as recorded on an
5796 * exit caused by such an instruction (run by a guest hypervisor).
5797 * On success, returns 0. When the operand is invalid, returns 1 and throws
5798 * #UD or #GP.
5799 */
5800static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
5801 unsigned long exit_qualification,
5802 u32 vmx_instruction_info, gva_t *ret)
5803{
5804 /*
5805 * According to Vol. 3B, "Information for VM Exits Due to Instruction
5806 * Execution", on an exit, vmx_instruction_info holds most of the
5807 * addressing components of the operand. Only the displacement part
5808 * is put in exit_qualification (see 3B, "Basic VM-Exit Information").
5809 * For how an actual address is calculated from all these components,
5810 * refer to Vol. 1, "Operand Addressing".
5811 */
5812 int scaling = vmx_instruction_info & 3;
5813 int addr_size = (vmx_instruction_info >> 7) & 7;
5814 bool is_reg = vmx_instruction_info & (1u << 10);
5815 int seg_reg = (vmx_instruction_info >> 15) & 7;
5816 int index_reg = (vmx_instruction_info >> 18) & 0xf;
5817 bool index_is_valid = !(vmx_instruction_info & (1u << 22));
5818 int base_reg = (vmx_instruction_info >> 23) & 0xf;
5819 bool base_is_valid = !(vmx_instruction_info & (1u << 27));
5820
5821 if (is_reg) {
5822 kvm_queue_exception(vcpu, UD_VECTOR);
5823 return 1;
5824 }
5825
5826 /* Addr = segment_base + offset */
5827 /* offset = base + [index * scale] + displacement */
5828 *ret = vmx_get_segment_base(vcpu, seg_reg);
5829 if (base_is_valid)
5830 *ret += kvm_register_read(vcpu, base_reg);
5831 if (index_is_valid)
5832 *ret += kvm_register_read(vcpu, index_reg)<<scaling;
5833 *ret += exit_qualification; /* holds the displacement */
5834
5835 if (addr_size == 1) /* 32 bit */
5836 *ret &= 0xffffffff;
5837
5838 /*
5839 * TODO: throw #GP (and return 1) in various cases that the VM*
5840 * instructions require it - e.g., offset beyond segment limit,
5841 * unusable or unreadable/unwritable segment, non-canonical 64-bit
5842 * address, and so on. Currently these are not checked.
5843 */
5844 return 0;
5845}
5846
5847/*
5795 * Emulate the VMXON instruction. 5848 * Emulate the VMXON instruction.
5796 * Currently, we just remember that VMX is active, and do not save or even 5849 * Currently, we just remember that VMX is active, and do not save or even
5797 * inspect the argument to VMXON (the so-called "VMXON pointer") because we 5850 * inspect the argument to VMXON (the so-called "VMXON pointer") because we
@@ -5951,59 +6004,6 @@ static int handle_vmoff(struct kvm_vcpu *vcpu)
5951 return 1; 6004 return 1;
5952} 6005}
5953 6006
5954/*
5955 * Decode the memory-address operand of a vmx instruction, as recorded on an
5956 * exit caused by such an instruction (run by a guest hypervisor).
5957 * On success, returns 0. When the operand is invalid, returns 1 and throws
5958 * #UD or #GP.
5959 */
5960static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
5961 unsigned long exit_qualification,
5962 u32 vmx_instruction_info, gva_t *ret)
5963{
5964 /*
5965 * According to Vol. 3B, "Information for VM Exits Due to Instruction
5966 * Execution", on an exit, vmx_instruction_info holds most of the
5967 * addressing components of the operand. Only the displacement part
5968 * is put in exit_qualification (see 3B, "Basic VM-Exit Information").
5969 * For how an actual address is calculated from all these components,
5970 * refer to Vol. 1, "Operand Addressing".
5971 */
5972 int scaling = vmx_instruction_info & 3;
5973 int addr_size = (vmx_instruction_info >> 7) & 7;
5974 bool is_reg = vmx_instruction_info & (1u << 10);
5975 int seg_reg = (vmx_instruction_info >> 15) & 7;
5976 int index_reg = (vmx_instruction_info >> 18) & 0xf;
5977 bool index_is_valid = !(vmx_instruction_info & (1u << 22));
5978 int base_reg = (vmx_instruction_info >> 23) & 0xf;
5979 bool base_is_valid = !(vmx_instruction_info & (1u << 27));
5980
5981 if (is_reg) {
5982 kvm_queue_exception(vcpu, UD_VECTOR);
5983 return 1;
5984 }
5985
5986 /* Addr = segment_base + offset */
5987 /* offset = base + [index * scale] + displacement */
5988 *ret = vmx_get_segment_base(vcpu, seg_reg);
5989 if (base_is_valid)
5990 *ret += kvm_register_read(vcpu, base_reg);
5991 if (index_is_valid)
5992 *ret += kvm_register_read(vcpu, index_reg)<<scaling;
5993 *ret += exit_qualification; /* holds the displacement */
5994
5995 if (addr_size == 1) /* 32 bit */
5996 *ret &= 0xffffffff;
5997
5998 /*
5999 * TODO: throw #GP (and return 1) in various cases that the VM*
6000 * instructions require it - e.g., offset beyond segment limit,
6001 * unusable or unreadable/unwritable segment, non-canonical 64-bit
6002 * address, and so on. Currently these are not checked.
6003 */
6004 return 0;
6005}
6006
6007/* Emulate the VMCLEAR instruction */ 6007/* Emulate the VMCLEAR instruction */
6008static int handle_vmclear(struct kvm_vcpu *vcpu) 6008static int handle_vmclear(struct kvm_vcpu *vcpu)
6009{ 6009{