aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2010-02-19 10:23:07 -0500
committerAvi Kivity <avi@redhat.com>2010-04-25 05:34:25 -0400
commit06fc7772690dec2a0e3814633357babf8f63af41 (patch)
tree77f08440830d67e120df705af2e2251241d70fba /arch/x86/kvm/svm.c
parent88ab24adc7142506c8583ac36a34fa388300b750 (diff)
KVM: SVM: Activate nested state only when guest state is complete
Certain functions called during the emulated world switch behave differently when the vcpu is running nested. This is not the expected behavior during a world switch emulation. This patch ensures that the nested state is activated only if the vcpu is completly in nested state. 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.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 481bd0ee5f7e..8ace0b0da933 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1633,6 +1633,9 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
1633 if (!nested_vmcb) 1633 if (!nested_vmcb)
1634 return 1; 1634 return 1;
1635 1635
1636 /* Exit nested SVM mode */
1637 svm->nested.vmcb = 0;
1638
1636 /* Give the current vmcb to the guest */ 1639 /* Give the current vmcb to the guest */
1637 disable_gif(svm); 1640 disable_gif(svm);
1638 1641
@@ -1720,9 +1723,6 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
1720 svm->vmcb->save.cpl = 0; 1723 svm->vmcb->save.cpl = 0;
1721 svm->vmcb->control.exit_int_info = 0; 1724 svm->vmcb->control.exit_int_info = 0;
1722 1725
1723 /* Exit nested SVM mode */
1724 svm->nested.vmcb = 0;
1725
1726 nested_svm_unmap(page); 1726 nested_svm_unmap(page);
1727 1727
1728 kvm_mmu_reset_context(&svm->vcpu); 1728 kvm_mmu_reset_context(&svm->vcpu);
@@ -1757,14 +1757,14 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
1757 struct vmcb *hsave = svm->nested.hsave; 1757 struct vmcb *hsave = svm->nested.hsave;
1758 struct vmcb *vmcb = svm->vmcb; 1758 struct vmcb *vmcb = svm->vmcb;
1759 struct page *page; 1759 struct page *page;
1760 u64 vmcb_gpa;
1761
1762 vmcb_gpa = svm->vmcb->save.rax;
1760 1763
1761 nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); 1764 nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
1762 if (!nested_vmcb) 1765 if (!nested_vmcb)
1763 return false; 1766 return false;
1764 1767
1765 /* nested_vmcb is our indicator if nested SVM is activated */
1766 svm->nested.vmcb = svm->vmcb->save.rax;
1767
1768 trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb, 1768 trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb,
1769 nested_vmcb->save.rip, 1769 nested_vmcb->save.rip,
1770 nested_vmcb->control.int_ctl, 1770 nested_vmcb->control.int_ctl,
@@ -1879,6 +1879,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
1879 1879
1880 nested_svm_unmap(page); 1880 nested_svm_unmap(page);
1881 1881
1882 /* nested_vmcb is our indicator if nested SVM is activated */
1883 svm->nested.vmcb = vmcb_gpa;
1884
1882 enable_gif(svm); 1885 enable_gif(svm);
1883 1886
1884 return true; 1887 return true;