diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-04-06 06:30:03 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:57:06 -0400 |
commit | e3e9ed3d2c443fd90a04fb7ff231ad53ef087417 (patch) | |
tree | 527e793d02a79cbacc21348aaeda9d67f880dc51 | |
parent | 92a1f12d2598f429bd8639e21d89305e787115c5 (diff) |
KVM: SVM: Fix fault-rip on vmsave/vmload emulation
When the emulation of vmload or vmsave fails because the
guest passed an unsupported physical address it gets an #GP
with rip pointing to the instruction after vmsave/vmload.
This is a bug and fixed by this patch.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/svm.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a98873762433..a6bf2ad7429c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -2518,13 +2518,13 @@ static int vmload_interception(struct vcpu_svm *svm) | |||
2518 | if (nested_svm_check_permissions(svm)) | 2518 | if (nested_svm_check_permissions(svm)) |
2519 | return 1; | 2519 | return 1; |
2520 | 2520 | ||
2521 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
2522 | skip_emulated_instruction(&svm->vcpu); | ||
2523 | |||
2524 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); | 2521 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); |
2525 | if (!nested_vmcb) | 2522 | if (!nested_vmcb) |
2526 | return 1; | 2523 | return 1; |
2527 | 2524 | ||
2525 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
2526 | skip_emulated_instruction(&svm->vcpu); | ||
2527 | |||
2528 | nested_svm_vmloadsave(nested_vmcb, svm->vmcb); | 2528 | nested_svm_vmloadsave(nested_vmcb, svm->vmcb); |
2529 | nested_svm_unmap(page); | 2529 | nested_svm_unmap(page); |
2530 | 2530 | ||
@@ -2539,13 +2539,13 @@ static int vmsave_interception(struct vcpu_svm *svm) | |||
2539 | if (nested_svm_check_permissions(svm)) | 2539 | if (nested_svm_check_permissions(svm)) |
2540 | return 1; | 2540 | return 1; |
2541 | 2541 | ||
2542 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
2543 | skip_emulated_instruction(&svm->vcpu); | ||
2544 | |||
2545 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); | 2542 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); |
2546 | if (!nested_vmcb) | 2543 | if (!nested_vmcb) |
2547 | return 1; | 2544 | return 1; |
2548 | 2545 | ||
2546 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
2547 | skip_emulated_instruction(&svm->vcpu); | ||
2548 | |||
2549 | nested_svm_vmloadsave(svm->vmcb, nested_vmcb); | 2549 | nested_svm_vmloadsave(svm->vmcb, nested_vmcb); |
2550 | nested_svm_unmap(page); | 2550 | nested_svm_unmap(page); |
2551 | 2551 | ||