Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146528
b: refs/heads/master
c: 64a7ec0
h: refs/heads/master
v: v3
  • Loading branch information
Gleb Natapov authored and Avi Kivity committed Jun 10, 2009
1 parent 8572f85 commit 18f1f02
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 19 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: b237ac37a149e8b56436fabf093532483bff13b0
refs/heads/master: 64a7ec066813443440bfc9f60a9e76a47cfa6b2b
1 change: 1 addition & 0 deletions trunk/arch/x86/include/asm/svm.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EVTINJ_VALID_ERR (1 << 11)

#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
#define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK

#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
Expand Down
25 changes: 18 additions & 7 deletions trunk/arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1825,17 +1825,28 @@ static int task_switch_interception(struct vcpu_svm *svm,
struct kvm_run *kvm_run)
{
u16 tss_selector;
int reason;
int int_type = svm->vmcb->control.exit_int_info &
SVM_EXITINTINFO_TYPE_MASK;

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);
reason = TASK_SWITCH_IRET;
else if (svm->vmcb->control.exit_info_2 &
(1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP))
reason = TASK_SWITCH_JMP;
else if (svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID)
reason = TASK_SWITCH_GATE;
else
reason = TASK_SWITCH_CALL;


if (reason != TASK_SWITCH_GATE || int_type == SVM_EXITINTINFO_TYPE_SOFT)
skip_emulated_instruction(&svm->vcpu);

return kvm_task_switch(&svm->vcpu, tss_selector, reason);
}

static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
Expand Down
38 changes: 28 additions & 10 deletions trunk/arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3038,22 +3038,40 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long exit_qualification;
u16 tss_selector;
int reason;
int reason, type, idt_v;

idt_v = (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
type = (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK);

exit_qualification = vmcs_readl(EXIT_QUALIFICATION);

reason = (u32)exit_qualification >> 30;
if (reason == TASK_SWITCH_GATE && vmx->vcpu.arch.nmi_injected &&
(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) &&
(vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK)
== INTR_TYPE_NMI_INTR) {
vcpu->arch.nmi_injected = false;
if (cpu_has_virtual_nmis())
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
if (reason == TASK_SWITCH_GATE && idt_v) {
switch (type) {
case INTR_TYPE_NMI_INTR:
vcpu->arch.nmi_injected = false;
if (cpu_has_virtual_nmis())
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
break;
case INTR_TYPE_EXT_INTR:
kvm_clear_interrupt_queue(vcpu);
break;
case INTR_TYPE_HARD_EXCEPTION:
case INTR_TYPE_SOFT_EXCEPTION:
kvm_clear_exception_queue(vcpu);
break;
default:
break;
}
}
tss_selector = exit_qualification;

if (!idt_v || (type != INTR_TYPE_HARD_EXCEPTION &&
type != INTR_TYPE_EXT_INTR &&
type != INTR_TYPE_NMI_INTR))
skip_emulated_instruction(vcpu);

if (!kvm_task_switch(vcpu, tss_selector, reason))
return 0;

Expand Down Expand Up @@ -3306,7 +3324,7 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;

switch(type) {
switch (type) {
case INTR_TYPE_NMI_INTR:
vmx->vcpu.arch.nmi_injected = true;
/*
Expand Down
5 changes: 4 additions & 1 deletion trunk/arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -3935,7 +3935,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
kvm_x86_ops->set_rflags(vcpu, eflags & ~X86_EFLAGS_NT);
}

kvm_x86_ops->skip_emulated_instruction(vcpu);
/* set back link to prev task only if NT bit is set in eflags
note that old_tss_sel is not used afetr this point */
if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
old_tss_sel = 0xffff;

/* set back link to prev task only if NT bit is set in eflags
note that old_tss_sel is not used afetr this point */
Expand Down

0 comments on commit 18f1f02

Please sign in to comment.