aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-02-08 08:34:38 -0500
committerAvi Kivity <avi@redhat.com>2012-03-08 07:10:26 -0500
commit7f3d35fddd173e52886d03bc34b5b5d6f5bea343 (patch)
tree9561913495a92c398b9b8e372d4e9a5c1d55c7f4 /arch/x86/kvm/vmx.c
parent9cc815e46911486f52bec60517d0f7b40d323bbc (diff)
KVM: x86 emulator: Fix task switch privilege checks
Currently, all task switches check privileges against the DPL of the TSS. This is only correct for jmp/call to a TSS. If a task gate is used, the DPL of this take gate is used for the check instead. Exceptions, external interrupts and iret shouldn't perform any check. [avi: kill kvm-kmod remnants] Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d2bd719925a6..124a0952a040 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4658,9 +4658,10 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
4658 bool has_error_code = false; 4658 bool has_error_code = false;
4659 u32 error_code = 0; 4659 u32 error_code = 0;
4660 u16 tss_selector; 4660 u16 tss_selector;
4661 int reason, type, idt_v; 4661 int reason, type, idt_v, idt_index;
4662 4662
4663 idt_v = (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK); 4663 idt_v = (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
4664 idt_index = (vmx->idt_vectoring_info & VECTORING_INFO_VECTOR_MASK);
4664 type = (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK); 4665 type = (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK);
4665 4666
4666 exit_qualification = vmcs_readl(EXIT_QUALIFICATION); 4667 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
@@ -4698,8 +4699,9 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
4698 type != INTR_TYPE_NMI_INTR)) 4699 type != INTR_TYPE_NMI_INTR))
4699 skip_emulated_instruction(vcpu); 4700 skip_emulated_instruction(vcpu);
4700 4701
4701 if (kvm_task_switch(vcpu, tss_selector, reason, 4702 if (kvm_task_switch(vcpu, tss_selector,
4702 has_error_code, error_code) == EMULATE_FAIL) { 4703 type == INTR_TYPE_SOFT_INTR ? idt_index : -1, reason,
4704 has_error_code, error_code) == EMULATE_FAIL) {
4703 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 4705 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
4704 vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; 4706 vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
4705 vcpu->run->internal.ndata = 0; 4707 vcpu->run->internal.ndata = 0;