return EMULATE_FAIL;
 }
 
+static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
+{
+       gpa_t gpa;
+
+       /*
+        * if emulation was due to access to shadowed page table
+        * and it failed try to unshadow page and re-entetr the
+        * guest to let CPU execute the instruction.
+        */
+       if (kvm_mmu_unprotect_page_virt(vcpu, gva))
+               return true;
+
+       gpa = kvm_mmu_gva_to_gpa_system(vcpu, gva, NULL);
+
+       if (gpa == UNMAPPED_GVA)
+               return true; /* let cpu generate fault */
+
+       if (!kvm_is_error_hva(gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT)))
+               return true;
+
+       return false;
+}
+
 int emulate_instruction(struct kvm_vcpu *vcpu,
                        unsigned long cr2,
                        u16 error_code,
 
                ++vcpu->stat.insn_emulation;
                if (r)  {
-                       if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
+                       if (reexecute_instruction(vcpu, cr2))
                                return EMULATE_DONE;
                        if (emulation_type & EMULTYPE_SKIP)
                                return EMULATE_FAIL;
        r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
 
        if (r) { /* emulation failed */
-               /*
-                * if emulation was due to access to shadowed page table
-                * and it failed try to unshadow page and re-entetr the
-                * guest to let CPU execute the instruction.
-                */
-               if (kvm_mmu_unprotect_page_virt(vcpu, cr2))
+               if (reexecute_instruction(vcpu, cr2))
                        return EMULATE_DONE;
 
                return handle_emulation_failure(vcpu);