aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/vmx.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-01-05 19:36:54 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:27 -0500
commite2dec939db126989808853d218e426daaeebc9e2 (patch)
tree5c742e609e43090df396fc1c7a6b4c526099dbea /drivers/kvm/vmx.c
parent714b93da1a6d97307dfafb9915517879d8a66c0d (diff)
[PATCH] KVM: MMU: Detect oom conditions and propagate error to userspace
Signed-off-by: Avi Kivity <avi@qumranet.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r--drivers/kvm/vmx.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 59178ad4d344..ed3956739771 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1289,6 +1289,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1289 unsigned long cr2, rip; 1289 unsigned long cr2, rip;
1290 u32 vect_info; 1290 u32 vect_info;
1291 enum emulation_result er; 1291 enum emulation_result er;
1292 int r;
1292 1293
1293 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); 1294 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
1294 intr_info = vmcs_read32(VM_EXIT_INTR_INFO); 1295 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
@@ -1317,7 +1318,12 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1317 cr2 = vmcs_readl(EXIT_QUALIFICATION); 1318 cr2 = vmcs_readl(EXIT_QUALIFICATION);
1318 1319
1319 spin_lock(&vcpu->kvm->lock); 1320 spin_lock(&vcpu->kvm->lock);
1320 if (!kvm_mmu_page_fault(vcpu, cr2, error_code)) { 1321 r = kvm_mmu_page_fault(vcpu, cr2, error_code);
1322 if (r < 0) {
1323 spin_unlock(&vcpu->kvm->lock);
1324 return r;
1325 }
1326 if (!r) {
1321 spin_unlock(&vcpu->kvm->lock); 1327 spin_unlock(&vcpu->kvm->lock);
1322 return 1; 1328 return 1;
1323 } 1329 }
@@ -1680,6 +1686,7 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1680 u8 fail; 1686 u8 fail;
1681 u16 fs_sel, gs_sel, ldt_sel; 1687 u16 fs_sel, gs_sel, ldt_sel;
1682 int fs_gs_ldt_reload_needed; 1688 int fs_gs_ldt_reload_needed;
1689 int r;
1683 1690
1684again: 1691again:
1685 /* 1692 /*
@@ -1853,6 +1860,7 @@ again:
1853 if (fail) { 1860 if (fail) {
1854 kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY; 1861 kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
1855 kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR); 1862 kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
1863 r = 0;
1856 } else { 1864 } else {
1857 if (fs_gs_ldt_reload_needed) { 1865 if (fs_gs_ldt_reload_needed) {
1858 load_ldt(ldt_sel); 1866 load_ldt(ldt_sel);
@@ -1872,7 +1880,8 @@ again:
1872 } 1880 }
1873 vcpu->launched = 1; 1881 vcpu->launched = 1;
1874 kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT; 1882 kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
1875 if (kvm_handle_exit(kvm_run, vcpu)) { 1883 r = kvm_handle_exit(kvm_run, vcpu);
1884 if (r > 0) {
1876 /* Give scheduler a change to reschedule. */ 1885 /* Give scheduler a change to reschedule. */
1877 if (signal_pending(current)) { 1886 if (signal_pending(current)) {
1878 ++kvm_stat.signal_exits; 1887 ++kvm_stat.signal_exits;
@@ -1892,7 +1901,7 @@ again:
1892 } 1901 }
1893 1902
1894 post_kvm_run_save(vcpu, kvm_run); 1903 post_kvm_run_save(vcpu, kvm_run);
1895 return 0; 1904 return r;
1896} 1905}
1897 1906
1898static void vmx_flush_tlb(struct kvm_vcpu *vcpu) 1907static void vmx_flush_tlb(struct kvm_vcpu *vcpu)