diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-02-19 10:23:02 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-04-25 05:34:10 -0400 |
commit | b8e88bc8ffba5fe53fb8d8a0a4be3bbcffeebe56 (patch) | |
tree | 609785cf43eabd9308a1435fb5ffd50f77f6a5fd /arch/x86/kvm/svm.c | |
parent | 7597f129d8b6799da7a264e6d6f7401668d3a36d (diff) |
KVM: SVM: Fix schedule-while-atomic on nested exception handling
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>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f9da35b06ec7..c27da0ad040c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -129,6 +129,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu); | |||
129 | static void svm_complete_interrupts(struct vcpu_svm *svm); | 129 | static void svm_complete_interrupts(struct vcpu_svm *svm); |
130 | 130 | ||
131 | static int nested_svm_exit_handled(struct vcpu_svm *svm); | 131 | static int nested_svm_exit_handled(struct vcpu_svm *svm); |
132 | static int nested_svm_intercept(struct vcpu_svm *svm); | ||
132 | static int nested_svm_vmexit(struct vcpu_svm *svm); | 133 | static int nested_svm_vmexit(struct vcpu_svm *svm); |
133 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 134 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
134 | bool has_error_code, u32 error_code); | 135 | bool has_error_code, u32 error_code); |
@@ -1384,6 +1385,8 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm) | |||
1384 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 1385 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
1385 | bool has_error_code, u32 error_code) | 1386 | bool has_error_code, u32 error_code) |
1386 | { | 1387 | { |
1388 | int vmexit; | ||
1389 | |||
1387 | if (!is_nested(svm)) | 1390 | if (!is_nested(svm)) |
1388 | return 0; | 1391 | return 0; |
1389 | 1392 | ||
@@ -1392,7 +1395,11 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | |||
1392 | svm->vmcb->control.exit_info_1 = error_code; | 1395 | svm->vmcb->control.exit_info_1 = error_code; |
1393 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; | 1396 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; |
1394 | 1397 | ||
1395 | return nested_svm_exit_handled(svm); | 1398 | vmexit = nested_svm_intercept(svm); |
1399 | if (vmexit == NESTED_EXIT_DONE) | ||
1400 | svm->nested.exit_required = true; | ||
1401 | |||
1402 | return vmexit; | ||
1396 | } | 1403 | } |
1397 | 1404 | ||
1398 | static inline int nested_svm_intr(struct vcpu_svm *svm) | 1405 | static inline int nested_svm_intr(struct vcpu_svm *svm) |
@@ -1521,7 +1528,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) | |||
1521 | /* | 1528 | /* |
1522 | * If this function returns true, this #vmexit was already handled | 1529 | * If this function returns true, this #vmexit was already handled |
1523 | */ | 1530 | */ |
1524 | static int nested_svm_exit_handled(struct vcpu_svm *svm) | 1531 | static int nested_svm_intercept(struct vcpu_svm *svm) |
1525 | { | 1532 | { |
1526 | u32 exit_code = svm->vmcb->control.exit_code; | 1533 | u32 exit_code = svm->vmcb->control.exit_code; |
1527 | int vmexit = NESTED_EXIT_HOST; | 1534 | int vmexit = NESTED_EXIT_HOST; |
@@ -1567,9 +1574,17 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm) | |||
1567 | } | 1574 | } |
1568 | } | 1575 | } |
1569 | 1576 | ||
1570 | if (vmexit == NESTED_EXIT_DONE) { | 1577 | return vmexit; |
1578 | } | ||
1579 | |||
1580 | static int nested_svm_exit_handled(struct vcpu_svm *svm) | ||
1581 | { | ||
1582 | int vmexit; | ||
1583 | |||
1584 | vmexit = nested_svm_intercept(svm); | ||
1585 | |||
1586 | if (vmexit == NESTED_EXIT_DONE) | ||
1571 | nested_svm_vmexit(svm); | 1587 | nested_svm_vmexit(svm); |
1572 | } | ||
1573 | 1588 | ||
1574 | return vmexit; | 1589 | return vmexit; |
1575 | } | 1590 | } |