diff options
author | Kevin Wolf <kwolf@redhat.com> | 2012-02-08 08:34:38 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-03-08 07:10:26 -0500 |
commit | 7f3d35fddd173e52886d03bc34b5b5d6f5bea343 (patch) | |
tree | 9561913495a92c398b9b8e372d4e9a5c1d55c7f4 /arch/x86/kvm/vmx.c | |
parent | 9cc815e46911486f52bec60517d0f7b40d323bbc (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.c | 8 |
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; |