Skip to content

Commit 19ab2c8

Browse files
committed
KVM: x86: Check EMULTYPE_WRITE_PF_TO_SP before unprotecting gfn
Don't bother unprotecting the target gfn if EMULTYPE_WRITE_PF_TO_SP is set, as KVM will simply report the emulation failure to userspace. This will allow converting reexecute_instruction() to use kvm_mmu_unprotect_gfn_instead_retry() instead of kvm_mmu_unprotect_page(). Link: https://lore.kernel.org/r/20240831001538.336683-17-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 6205257 commit 19ab2c8

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

arch/x86/kvm/x86.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8869,6 +8869,19 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
88698869
if (!(emulation_type & EMULTYPE_ALLOW_RETRY_PF))
88708870
return false;
88718871

8872+
/*
8873+
* If the failed instruction faulted on an access to page tables that
8874+
* are used to translate any part of the instruction, KVM can't resolve
8875+
* the issue by unprotecting the gfn, as zapping the shadow page will
8876+
* result in the instruction taking a !PRESENT page fault and thus put
8877+
* the vCPU into an infinite loop of page faults. E.g. KVM will create
8878+
* a SPTE and write-protect the gfn to resolve the !PRESENT fault, and
8879+
* then zap the SPTE to unprotect the gfn, and then do it all over
8880+
* again. Report the error to userspace.
8881+
*/
8882+
if (emulation_type & EMULTYPE_WRITE_PF_TO_SP)
8883+
return false;
8884+
88728885
if (!vcpu->arch.mmu->root_role.direct) {
88738886
/*
88748887
* Write permission should be allowed since only
@@ -8894,16 +8907,13 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
88948907
kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
88958908

88968909
/*
8897-
* If the failed instruction faulted on an access to page tables that
8898-
* are used to translate any part of the instruction, KVM can't resolve
8899-
* the issue by unprotecting the gfn, as zapping the shadow page will
8900-
* result in the instruction taking a !PRESENT page fault and thus put
8901-
* the vCPU into an infinite loop of page faults. E.g. KVM will create
8902-
* a SPTE and write-protect the gfn to resolve the !PRESENT fault, and
8903-
* then zap the SPTE to unprotect the gfn, and then do it all over
8904-
* again. Report the error to userspace.
8910+
* Retry even if _this_ vCPU didn't unprotect the gfn, as it's possible
8911+
* all SPTEs were already zapped by a different task. The alternative
8912+
* is to report the error to userspace and likely terminate the guest,
8913+
* and the last_retry_{eip,addr} checks will prevent retrying the page
8914+
* fault indefinitely, i.e. there's nothing to lose by retrying.
89058915
*/
8906-
return !(emulation_type & EMULTYPE_WRITE_PF_TO_SP);
8916+
return true;
89078917
}
89088918

89098919
static int complete_emulated_mmio(struct kvm_vcpu *vcpu);

0 commit comments

Comments
 (0)