Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 93840
b: refs/heads/master
c: 37817f2
h: refs/heads/master
v: v3
  • Loading branch information
Izik Eidus authored and Avi Kivity committed Apr 27, 2008
1 parent 856d9b6 commit c0103bb
Show file tree
Hide file tree
Showing 7 changed files with 508 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2e4d2653497856b102c90153f970c9e344ba96c6
refs/heads/master: 37817f2982d0f559f90cecc66e150dd9d2c2df05
15 changes: 12 additions & 3 deletions trunk/arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1112,9 +1112,18 @@ static int invalid_op_interception(struct vcpu_svm *svm,
static int task_switch_interception(struct vcpu_svm *svm,
struct kvm_run *kvm_run)
{
pr_unimpl(&svm->vcpu, "%s: task switch is unsupported\n", __func__);
kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
return 0;
u16 tss_selector;

tss_selector = (u16)svm->vmcb->control.exit_info_1;
if (svm->vmcb->control.exit_info_2 &
(1ULL << SVM_EXITINFOSHIFT_TS_REASON_IRET))
return kvm_task_switch(&svm->vcpu, tss_selector,
TASK_SWITCH_IRET);
if (svm->vmcb->control.exit_info_2 &
(1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP))
return kvm_task_switch(&svm->vcpu, tss_selector,
TASK_SWITCH_JMP);
return kvm_task_switch(&svm->vcpu, tss_selector, TASK_SWITCH_CALL);
}

static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kvm/svm.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR

#define SVM_EXITINFOSHIFT_TS_REASON_IRET 36
#define SVM_EXITINFOSHIFT_TS_REASON_JMP 38

#define SVM_EXIT_READ_CR0 0x000
#define SVM_EXIT_READ_CR3 0x003
#define SVM_EXIT_READ_CR4 0x004
Expand Down
59 changes: 59 additions & 0 deletions trunk/arch/x86/kvm/tss.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef __TSS_SEGMENT_H
#define __TSS_SEGMENT_H

struct tss_segment_32 {
u32 prev_task_link;
u32 esp0;
u32 ss0;
u32 esp1;
u32 ss1;
u32 esp2;
u32 ss2;
u32 cr3;
u32 eip;
u32 eflags;
u32 eax;
u32 ecx;
u32 edx;
u32 ebx;
u32 esp;
u32 ebp;
u32 esi;
u32 edi;
u32 es;
u32 cs;
u32 ss;
u32 ds;
u32 fs;
u32 gs;
u32 ldt_selector;
u16 t;
u16 io_map;
};

struct tss_segment_16 {
u16 prev_task_link;
u16 sp0;
u16 ss0;
u16 sp1;
u16 ss1;
u16 sp2;
u16 ss2;
u16 ip;
u16 flag;
u16 ax;
u16 cx;
u16 dx;
u16 bx;
u16 sp;
u16 bp;
u16 si;
u16 di;
u16 es;
u16 cs;
u16 ss;
u16 ds;
u16 ldt;
};

#endif
15 changes: 15 additions & 0 deletions trunk/arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2249,6 +2249,20 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}

static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
unsigned long exit_qualification;
u16 tss_selector;
int reason;

exit_qualification = vmcs_readl(EXIT_QUALIFICATION);

reason = (u32)exit_qualification >> 30;
tss_selector = exit_qualification;

return kvm_task_switch(vcpu, tss_selector, reason);
}

/*
* The exit handlers return 1 if the exit was handled fully and guest execution
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
Expand All @@ -2271,6 +2285,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
[EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold,
[EXIT_REASON_APIC_ACCESS] = handle_apic_access,
[EXIT_REASON_WBINVD] = handle_wbinvd,
[EXIT_REASON_TASK_SWITCH] = handle_task_switch,
};

static const int kvm_vmx_max_exit_handlers =
Expand Down
Loading

0 comments on commit c0103bb

Please sign in to comment.