Skip to content

Commit

Permalink
KVM: SVM: Fix schedule-while-atomic on nested exception handling
Browse files Browse the repository at this point in the history
Move the actual vmexit routine out of code that runs with
irqs and preemption disabled.

Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
  • Loading branch information
Joerg Roedel authored and Avi Kivity committed Apr 25, 2010
1 parent 7597f12 commit b8e88bc
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu);
static void svm_complete_interrupts(struct vcpu_svm *svm);

static int nested_svm_exit_handled(struct vcpu_svm *svm);
static int nested_svm_intercept(struct vcpu_svm *svm);
static int nested_svm_vmexit(struct vcpu_svm *svm);
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code);
Expand Down Expand Up @@ -1384,6 +1385,8 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm)
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code)
{
int vmexit;

if (!is_nested(svm))
return 0;

Expand All @@ -1392,7 +1395,11 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
svm->vmcb->control.exit_info_1 = error_code;
svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;

return nested_svm_exit_handled(svm);
vmexit = nested_svm_intercept(svm);
if (vmexit == NESTED_EXIT_DONE)
svm->nested.exit_required = true;

return vmexit;
}

static inline int nested_svm_intr(struct vcpu_svm *svm)
Expand Down Expand Up @@ -1521,7 +1528,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm)
/*
* If this function returns true, this #vmexit was already handled
*/
static int nested_svm_exit_handled(struct vcpu_svm *svm)
static int nested_svm_intercept(struct vcpu_svm *svm)
{
u32 exit_code = svm->vmcb->control.exit_code;
int vmexit = NESTED_EXIT_HOST;
Expand Down Expand Up @@ -1567,9 +1574,17 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm)
}
}

if (vmexit == NESTED_EXIT_DONE) {
return vmexit;
}

static int nested_svm_exit_handled(struct vcpu_svm *svm)
{
int vmexit;

vmexit = nested_svm_intercept(svm);

if (vmexit == NESTED_EXIT_DONE)
nested_svm_vmexit(svm);
}

return vmexit;
}
Expand Down

0 comments on commit b8e88bc

Please sign in to comment.