diff options
author | Avi Kivity <avi@qumranet.com> | 2007-01-05 19:36:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:27 -0500 |
commit | e2dec939db126989808853d218e426daaeebc9e2 (patch) | |
tree | 5c742e609e43090df396fc1c7a6b4c526099dbea /drivers/kvm/vmx.c | |
parent | 714b93da1a6d97307dfafb9915517879d8a66c0d (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.c | 15 |
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 | ||
1684 | again: | 1691 | again: |
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 | ||
1898 | static void vmx_flush_tlb(struct kvm_vcpu *vcpu) | 1907 | static void vmx_flush_tlb(struct kvm_vcpu *vcpu) |