aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/x86.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f0288c52d5e4..6f9cab071eca 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4751,25 +4751,25 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
4751 return r; 4751 return r;
4752} 4752}
4753 4753
4754static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva) 4754static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2)
4755{ 4755{
4756 gpa_t gpa; 4756 gpa_t gpa = cr2;
4757 pfn_t pfn; 4757 pfn_t pfn;
4758 4758
4759 if (tdp_enabled) 4759 if (!vcpu->arch.mmu.direct_map) {
4760 return false; 4760 /*
4761 4761 * Write permission should be allowed since only
4762 gpa = kvm_mmu_gva_to_gpa_system(vcpu, gva, NULL); 4762 * write access need to be emulated.
4763 if (gpa == UNMAPPED_GVA) 4763 */
4764 return true; /* let cpu generate fault */ 4764 gpa = kvm_mmu_gva_to_gpa_write(vcpu, cr2, NULL);
4765 4765
4766 /* 4766 /*
4767 * if emulation was due to access to shadowed page table 4767 * If the mapping is invalid in guest, let cpu retry
4768 * and it failed try to unshadow page and re-enter the 4768 * it to generate fault.
4769 * guest to let CPU execute the instruction. 4769 */
4770 */ 4770 if (gpa == UNMAPPED_GVA)
4771 if (kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa))) 4771 return true;
4772 return true; 4772 }
4773 4773
4774 /* 4774 /*
4775 * Do not retry the unhandleable instruction if it faults on the 4775 * Do not retry the unhandleable instruction if it faults on the
@@ -4778,12 +4778,37 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
4778 * instruction -> ... 4778 * instruction -> ...
4779 */ 4779 */
4780 pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa)); 4780 pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa));
4781 if (!is_error_noslot_pfn(pfn)) { 4781
4782 kvm_release_pfn_clean(pfn); 4782 /*
4783 * If the instruction failed on the error pfn, it can not be fixed,
4784 * report the error to userspace.
4785 */
4786 if (is_error_noslot_pfn(pfn))
4787 return false;
4788
4789 kvm_release_pfn_clean(pfn);
4790
4791 /* The instructions are well-emulated on direct mmu. */
4792 if (vcpu->arch.mmu.direct_map) {
4793 unsigned int indirect_shadow_pages;
4794
4795 spin_lock(&vcpu->kvm->mmu_lock);
4796 indirect_shadow_pages = vcpu->kvm->arch.indirect_shadow_pages;
4797 spin_unlock(&vcpu->kvm->mmu_lock);
4798
4799 if (indirect_shadow_pages)
4800 kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
4801
4783 return true; 4802 return true;
4784 } 4803 }
4785 4804
4786 return false; 4805 /*
4806 * if emulation was due to access to shadowed page table
4807 * and it failed try to unshadow page and re-enter the
4808 * guest to let CPU execute the instruction.
4809 */
4810 kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
4811 return true;
4787} 4812}
4788 4813
4789static bool retry_instruction(struct x86_emulate_ctxt *ctxt, 4814static bool retry_instruction(struct x86_emulate_ctxt *ctxt,