Patch "KVM: async_pf: Fix #DF due to inject "Page not Present" and "Page Ready" exceptions simultaneously" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: async_pf: Fix #DF due to inject "Page not Present" and "Page Ready" exceptions simultaneously
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-async_pf-fix-df-due-to-inject-page-not-present-and-page-ready-exceptions-simultaneously.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
9a6e7c39810e4a8bc7fc95056cefb40583fe07efMon Sep 17 00:00:00 2001
From: Wanpeng Li <[email protected]>
Date: Thu, 14 Sep 2017 03:54:16 -0700
Subject: KVM: async_pf: Fix #DF due to inject "Page not Present" and "Page Ready" exceptions simultaneously
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Wanpeng Li <[email protected]>
commit 9a6e7c39810e4a8bc7fc95056cefb40583fe07ef upstream.
qemu-system-x86-8600 [004] d..1 7205.687530: kvm_entry: vcpu 2
qemu-system-x86-8600 [004] .... 7205.687532: kvm_exit: reason EXCEPTION_NMI rip 0xffffffffa921297d info ffffeb2c0e44e018 80000b0e
qemu-system-x86-8600 [004] .... 7205.687532: kvm_page_fault: address ffffeb2c0e44e018 error_code 0
qemu-system-x86-8600 [004] .... 7205.687620: kvm_try_async_get_page: gva = 0xffffeb2c0e44e018, gfn = 0x427e4e
qemu-system-x86-8600 [004] .N.. 7205.687628: kvm_async_pf_not_present: token 0x8b002 gva 0xffffeb2c0e44e018
kworker/4:2-7814 [004] .... 7205.687655: kvm_async_pf_completed: gva 0xffffeb2c0e44e018 address 0x7fcc30c4e000
qemu-system-x86-8600 [004] .... 7205.687703: kvm_async_pf_ready: token 0x8b002 gva 0xffffeb2c0e44e018
qemu-system-x86-8600 [004] d..1 7205.687711: kvm_entry: vcpu 2After running some memory intensive workload in guest, I catch the kworker which completes the GUP too quickly, and queues an "Page Ready" #PF exception after the "Page not Present" exception before the next vmentry as the above trace which will result in #DF injected to guest.
This patch fixes it by clearing the queue for "Page not Present" if "Page Ready" occurs before the next vmentry since the GUP has already got the required page and shadow page table has already been fixed by "Page Ready" handler.
[port from upstream v4.14-rc1, Don't assign to kvm_queued_exception::injected or
x86_exception::async_page_fault]
--- arch/x86/kvm/x86.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)
arch/x86/kvm/x86.c +26 -8
@@ -8427,6 +8427,13 @@ static int apf_put_user(struct kvm_vcpu sizeof(val)); } +static int apf_get_user (struct kvm_vcpu *vcpu,u32 *val) +{ + +return kvm_read_guest_cached (vcpu->kvm, &vcpu->arch.apf.data, val, +sizeof (u32)); +} +void kvm_arch_async_page_not_present (struct kvm_vcpu *vcpu,struct kvm_async_pf *work) {
@@ -8453,6 +8460,7 @@ void kvm_arch_async_page_present(struct struct kvm_async_pf *work) {struct x86_exception fault; +u32 val;if (work->wakeup_all) work->arch.token = ~0 ;/* broadcast wakeup */
@@ -8460,14 +8468,24 @@ void kvm_arch_async_page_present(structkvm_del_async_pf_gfn (vcpu, work->arch.gfn);trace_kvm_async_pf_ready (work->arch.token, work->gva); -if ((vcpu->arch.apf.msr_val &KVM_ASYNC_PF_ENABLED ) && - !apf_put_user (vcpu,KVM_PV_REASON_PAGE_READY )) { - fault.vector =PF_VECTOR ; - fault.error_code_valid = true; - fault.error_code =0 ; - fault.nested_page_fault = false; - fault.address = work->arch.token; -kvm_inject_page_fault (vcpu, &fault); +if (vcpu->arch.apf.msr_val &KVM_ASYNC_PF_ENABLED && + !apf_get_user (vcpu, &val)) { +if (val ==KVM_PV_REASON_PAGE_NOT_PRESENT && + vcpu->arch.exception.pending && + vcpu->arch.exception.nr ==PF_VECTOR && + !apf_put_user (vcpu,0 )) { + vcpu->arch.exception.pending = false; + vcpu->arch.exception.nr =0 ; + vcpu->arch.exception.has_error_code = false; + vcpu->arch.exception.error_code =0 ; + }else if (!apf_put_user (vcpu,KVM_PV_REASON_PAGE_READY )) { + fault.vector =PF_VECTOR ; + fault.error_code_valid = true; + fault.error_code =0 ; + fault.nested_page_fault = false; + fault.address = work->arch.token; +kvm_inject_page_fault (vcpu, &fault); + } } vcpu->arch.apf.halted = false; vcpu->arch.mp_state =KVM_MP_STATE_RUNNABLE ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch queue-4.9/kvm-async_pf-fix-df-due-to-inject-page-not-present-and-page-ready-exceptions-simultaneously.patch