[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241118130403.23184-1-kalyazin@amazon.com>
Date: Mon, 18 Nov 2024 13:04:03 +0000
From: Nikita Kalyazin <kalyazin@...zon.com>
To: <pbonzini@...hat.com>, <seanjc@...gle.com>, <tglx@...utronix.de>,
<mingo@...hat.com>, <bp@...en8.de>, <dave.hansen@...ux.intel.com>,
<hpa@...or.com>, <kvm@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC: <david@...hat.com>, <peterx@...hat.com>, <oleg@...hat.com>,
<vkuznets@...hat.com>, <gshan@...hat.com>, <graf@...zon.de>,
<jgowans@...zon.com>, <roypat@...zon.co.uk>, <derekmn@...zon.com>,
<nsaenz@...zon.es>, <xmarcalx@...zon.com>, <kalyazin@...zon.com>
Subject: [PATCH] KVM: x86: async_pf: check earlier if can deliver async pf
On x86, async pagefault events can only be delivered if the page fault
was triggered by guest userspace, not kernel. This is because
the guest may be in non-sleepable context and will not be able
to reschedule.
However existing implementation pays the following overhead even for the
kernel-originated faults, even though it is known in advance that they
cannot be processed asynchronously:
- allocate async PF token
- create and schedule an async work
This patch avoids the overhead above in case of kernel-originated faults
by moving the `kvm_can_deliver_async_pf` check from
`kvm_arch_async_page_not_present` to `__kvm_faultin_pfn`.
Note that the existing check `kvm_can_do_async_pf` already calls
`kvm_can_deliver_async_pf` internally, however it only does that if the
`kvm_hlt_in_guest` check is true, ie userspace requested KVM not to exit
on guest halts via `KVM_CAP_X86_DISABLE_EXITS`. In that case the code
proceeds with the async fault processing with the following
justification in 1dfdb45ec510ba27e366878f97484e9c9e728902 ("KVM: x86:
clean up conditions for asynchronous page fault handling"):
"Even when asynchronous page fault is disabled, KVM does not want to pause
the host if a guest triggers a page fault; instead it will put it into
an artificial HLT state that allows running other host processes while
allowing interrupt delivery into the guest."
Signed-off-by: Nikita Kalyazin <kalyazin@...zon.com>
---
arch/x86/kvm/mmu/mmu.c | 3 ++-
arch/x86/kvm/x86.c | 5 ++---
arch/x86/kvm/x86.h | 2 ++
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 22e7ad235123..11d29d15b6cd 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -4369,7 +4369,8 @@ static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu,
trace_kvm_async_pf_repeated_fault(fault->addr, fault->gfn);
kvm_make_request(KVM_REQ_APF_HALT, vcpu);
return RET_PF_RETRY;
- } else if (kvm_arch_setup_async_pf(vcpu, fault)) {
+ } else if (kvm_can_deliver_async_pf(vcpu) &&
+ kvm_arch_setup_async_pf(vcpu, fault)) {
return RET_PF_RETRY;
}
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2e713480933a..8edae75b39f7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13355,7 +13355,7 @@ static inline bool apf_pageready_slot_free(struct kvm_vcpu *vcpu)
return !val;
}
-static bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu)
+bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu)
{
if (!kvm_pv_async_pf_enabled(vcpu))
@@ -13406,8 +13406,7 @@ bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
trace_kvm_async_pf_not_present(work->arch.token, work->cr2_or_gpa);
kvm_add_async_pf_gfn(vcpu, work->arch.gfn);
- if (kvm_can_deliver_async_pf(vcpu) &&
- !apf_put_user_notpresent(vcpu)) {
+ if (!apf_put_user_notpresent(vcpu)) {
fault.vector = PF_VECTOR;
fault.error_code_valid = true;
fault.error_code = 0;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index ec623d23d13d..9647f41e5c49 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -387,6 +387,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu);
fastpath_t handle_fastpath_hlt(struct kvm_vcpu *vcpu);
+bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu);
+
extern struct kvm_caps kvm_caps;
extern struct kvm_host_values kvm_host;
base-commit: d96c77bd4eeba469bddbbb14323d2191684da82a
--
2.40.1
Powered by blists - more mailing lists