aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>2012-08-20 22:57:42 -0400
committerAvi Kivity <avi@redhat.com>2012-08-22 08:08:49 -0400
commit8e3d9d061b5d132217629e7b5635ff0c02488e65 (patch)
tree5af8ab12b3a61d46157d665ad0898b1ad0fc135e /arch/x86/kvm/x86.c
parent8fbe6a541f50eeec5e3e49bd92db23ade9496673 (diff)
KVM: x86: fix possible infinite loop caused by reexecute_instruction
Currently, we reexecute all unhandleable instructions if they do not access on the mmio, however, it can not work if host map the readonly memory to guest. If the instruction try to write this kind of memory, it will fault again when guest retry it, then we will goto a infinite loop: retry instruction -> write #PF -> emulation fail -> retry instruction -> ... Fix it by retrying the instruction only when it faults on the writable memory Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fb0d93788bfb..704680d0fa3e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4473,6 +4473,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
4473static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva) 4473static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
4474{ 4474{
4475 gpa_t gpa; 4475 gpa_t gpa;
4476 pfn_t pfn;
4476 4477
4477 if (tdp_enabled) 4478 if (tdp_enabled)
4478 return false; 4479 return false;
@@ -4490,8 +4491,17 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
4490 if (gpa == UNMAPPED_GVA) 4491 if (gpa == UNMAPPED_GVA)
4491 return true; /* let cpu generate fault */ 4492 return true; /* let cpu generate fault */
4492 4493
4493 if (!kvm_is_error_hva(gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT))) 4494 /*
4495 * Do not retry the unhandleable instruction if it faults on the
4496 * readonly host memory, otherwise it will goto a infinite loop:
4497 * retry instruction -> write #PF -> emulation fail -> retry
4498 * instruction -> ...
4499 */
4500 pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa));
4501 if (!is_error_pfn(pfn)) {
4502 kvm_release_pfn_clean(pfn);
4494 return true; 4503 return true;
4504 }
4495 4505
4496 return false; 4506 return false;
4497} 4507}