|
@@ -1289,6 +1289,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|
unsigned long cr2, rip;
|
|
unsigned long cr2, rip;
|
|
u32 vect_info;
|
|
u32 vect_info;
|
|
enum emulation_result er;
|
|
enum emulation_result er;
|
|
|
|
+ int r;
|
|
|
|
|
|
vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
|
|
vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
|
|
intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
|
|
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)
|
|
cr2 = vmcs_readl(EXIT_QUALIFICATION);
|
|
cr2 = vmcs_readl(EXIT_QUALIFICATION);
|
|
|
|
|
|
spin_lock(&vcpu->kvm->lock);
|
|
spin_lock(&vcpu->kvm->lock);
|
|
- if (!kvm_mmu_page_fault(vcpu, cr2, error_code)) {
|
|
|
|
|
|
+ r = kvm_mmu_page_fault(vcpu, cr2, error_code);
|
|
|
|
+ if (r < 0) {
|
|
|
|
+ spin_unlock(&vcpu->kvm->lock);
|
|
|
|
+ return r;
|
|
|
|
+ }
|
|
|
|
+ if (!r) {
|
|
spin_unlock(&vcpu->kvm->lock);
|
|
spin_unlock(&vcpu->kvm->lock);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1680,6 +1686,7 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|
u8 fail;
|
|
u8 fail;
|
|
u16 fs_sel, gs_sel, ldt_sel;
|
|
u16 fs_sel, gs_sel, ldt_sel;
|
|
int fs_gs_ldt_reload_needed;
|
|
int fs_gs_ldt_reload_needed;
|
|
|
|
+ int r;
|
|
|
|
|
|
again:
|
|
again:
|
|
/*
|
|
/*
|
|
@@ -1853,6 +1860,7 @@ again:
|
|
if (fail) {
|
|
if (fail) {
|
|
kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
|
|
kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
|
|
kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
|
|
kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
|
|
|
|
+ r = 0;
|
|
} else {
|
|
} else {
|
|
if (fs_gs_ldt_reload_needed) {
|
|
if (fs_gs_ldt_reload_needed) {
|
|
load_ldt(ldt_sel);
|
|
load_ldt(ldt_sel);
|
|
@@ -1872,7 +1880,8 @@ again:
|
|
}
|
|
}
|
|
vcpu->launched = 1;
|
|
vcpu->launched = 1;
|
|
kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
|
|
kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
|
|
- if (kvm_handle_exit(kvm_run, vcpu)) {
|
|
|
|
|
|
+ r = kvm_handle_exit(kvm_run, vcpu);
|
|
|
|
+ if (r > 0) {
|
|
/* Give scheduler a change to reschedule. */
|
|
/* Give scheduler a change to reschedule. */
|
|
if (signal_pending(current)) {
|
|
if (signal_pending(current)) {
|
|
++kvm_stat.signal_exits;
|
|
++kvm_stat.signal_exits;
|
|
@@ -1892,7 +1901,7 @@ again:
|
|
}
|
|
}
|
|
|
|
|
|
post_kvm_run_save(vcpu, kvm_run);
|
|
post_kvm_run_save(vcpu, kvm_run);
|
|
- return 0;
|
|
|
|
|
|
+ return r;
|
|
}
|
|
}
|
|
|
|
|
|
static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
|
|
static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
|