aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>2013-01-13 10:46:52 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2013-01-21 19:58:32 -0500
commit95b3cf69bdf8b27a02d878e24ca353cebb4e009e (patch)
tree0b57c99e4cbd2facc29df9b08f7d6ad3a388067f /arch/x86/kvm/x86.c
parent22368028febf81f5c6d1e9fdd737d50543219b00 (diff)
KVM: x86: let reexecute_instruction work for tdp
Currently, reexecute_instruction refused to retry all instructions if tdp is enabled. If nested npt is used, the emulation may be caused by shadow page, it can be fixed by dropping the shadow page. And the only condition that tdp can not retry the instruction is the access fault on error pfn Reviewed-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-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,