KVM: async_pf: Inject 'page ready' event only if 'page not present' was previously injected
'Page not present' event may or may not get injected depending on guest's state. If the event wasn't injected, there is no need to inject the corresponding 'page ready' event as the guest may get confused. E.g. Linux thinks that the corresponding 'page not present' event wasn't delivered *yet* and allocates a 'dummy entry' for it. This entry is never freed. Note, 'wakeup all' events have no corresponding 'page not present' event and always get injected. s390 seems to always be able to inject 'page not present', the change is effectively a nop. Suggested-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Message-Id: <20200610175532.779793-2-vkuznets@redhat.com> Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=208081 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:

committed by
Paolo Bonzini

父節點
7863e346e1
當前提交
2a18b7e7cd
@@ -10511,7 +10511,7 @@ bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu)
|
||||
return kvm_arch_interrupt_allowed(vcpu);
|
||||
}
|
||||
|
||||
void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
|
||||
bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
|
||||
struct kvm_async_pf *work)
|
||||
{
|
||||
struct x86_exception fault;
|
||||
@@ -10528,6 +10528,7 @@ void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
|
||||
fault.address = work->arch.token;
|
||||
fault.async_page_fault = true;
|
||||
kvm_inject_page_fault(vcpu, &fault);
|
||||
return true;
|
||||
} else {
|
||||
/*
|
||||
* It is not possible to deliver a paravirtualized asynchronous
|
||||
@@ -10538,6 +10539,7 @@ void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
|
||||
* fault is retried, hopefully the page will be ready in the host.
|
||||
*/
|
||||
kvm_make_request(KVM_REQ_APF_HALT, vcpu);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10555,7 +10557,8 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
|
||||
kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
|
||||
trace_kvm_async_pf_ready(work->arch.token, work->cr2_or_gpa);
|
||||
|
||||
if (kvm_pv_async_pf_enabled(vcpu) &&
|
||||
if ((work->wakeup_all || work->notpresent_injected) &&
|
||||
kvm_pv_async_pf_enabled(vcpu) &&
|
||||
!apf_put_user_ready(vcpu, work->arch.token)) {
|
||||
vcpu->arch.apf.pageready_pending = true;
|
||||
kvm_apic_set_irq(vcpu, &irq, NULL);
|
||||
|
Reference in New Issue
Block a user