From: Gavin Shan <gshan@redhat.com>
To: kvmarm@lists.cs.columbia.edu
Cc: linux-kernel@vger.kernel.org, pbonzini@redhat.com,
maz@kernel.org, james.morse@arm.com, Jonathan.Cameron@huawei.com,
mark.rutland@arm.com, will@kernel.org, shan.gavin@gmail.com
Subject: [PATCH v2 11/17] KVM: arm64: Support async PF hypercalls
Date: Tue, 9 Feb 2021 13:03:57 +0800 [thread overview]
Message-ID: <20210209050403.103143-12-gshan@redhat.com> (raw)
In-Reply-To: <20210209050403.103143-1-gshan@redhat.com>
This introduces (SMCCC) KVM vendor specific services to configure
the asynchronous page fault functionality. The following services
are introduced:
* ARM_SMCCC_KVM_FUNC_ASYNC_PF_VERSION
Returns the version, which can be used to identify ABI changes
in the future.
* ARM_SMCCC_KVM_FUNC_ASYNC_PF_SLOTS
Return maximal number of tokens that current vCPU can have.
It's used by guest to allocate the required resources.
* ARM_SMCCC_KVM_FUNC_ASYNC_PF_{SDEI, IRQ}
Return the associated SDEI or (PPI) IRQ number, configured by
vCPU ioctl command.
* ARM_SMCCC_KVM_FUNC_ASYNC_PF_ENABLE
Enable or disable asynchronous page fault on current vCPU.
The corresponding SDEI event and (PPI) IRQ are owned by VMM. So they
are configured by vCPU ioctl interface and it will be implemented when
the asynchronous page fault capability is exported in the subsequent
patches.
Signed-off-by: Gavin Shan <gshan@redhat.com>
---
arch/arm64/kvm/async_pf.c | 119 ++++++++++++++++++++++++++++++++++++++
include/linux/arm-smccc.h | 5 ++
2 files changed, 124 insertions(+)
diff --git a/arch/arm64/kvm/async_pf.c b/arch/arm64/kvm/async_pf.c
index f73c406456e9..4734c5b26aa8 100644
--- a/arch/arm64/kvm/async_pf.c
+++ b/arch/arm64/kvm/async_pf.c
@@ -313,12 +313,115 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
write_cache(vcpu, offsetof(struct kvm_vcpu_pv_apf_data, token), 0);
}
+static void kvm_arch_async_sdei_notifier(struct kvm_vcpu *vcpu,
+ unsigned long num,
+ unsigned int state)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_arch_async_pf_control *apf = vcpu->arch.apf;
+
+ if (!apf)
+ return;
+
+ if (num != apf->sdei_event_num) {
+ kvm_err("%s: Invalid event number (%d-%d %lx-%llx)\n",
+ __func__, kvm->userspace_pid, vcpu->vcpu_idx,
+ num, apf->sdei_event_num);
+ return;
+ }
+
+ switch (state) {
+ case KVM_SDEI_NOTIFY_DELIVERED:
+ if (!apf->notpresent_pending)
+ break;
+
+ apf->notpresent_token = 0;
+ apf->notpresent_pending = false;
+ break;
+ case KVM_SDEI_NOTIFY_COMPLETED:
+ break;
+ default:
+ kvm_err("%s: Invalid state (%d-%d %lx-%d)\n",
+ __func__, kvm->userspace_pid, vcpu->vcpu_idx,
+ num, state);
+ }
+}
+
+static long kvm_arch_async_enable(struct kvm_vcpu *vcpu, u64 data)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_arch_async_pf_control *apf = vcpu->arch.apf;
+ gpa_t gpa = (data & ~0x3FUL);
+ bool enabled, enable;
+ int ret;
+
+ if (!apf || !irqchip_in_kernel(kvm))
+ return SMCCC_RET_NOT_SUPPORTED;
+
+ /* Bail if the state transition isn't allowed */
+ enabled = !!(apf->control_block & KVM_ASYNC_PF_ENABLED);
+ enable = !!(data & KVM_ASYNC_PF_ENABLED);
+ if (enable == enabled) {
+ kvm_debug("%s: Async PF has been %s on (%d-%d %llx-%llx)\n",
+ __func__, enabled ? "enabled" : "disabled",
+ kvm->userspace_pid, vcpu->vcpu_idx,
+ apf->control_block, data);
+ return SMCCC_RET_NOT_REQUIRED;
+ }
+
+ /* To disable the functinality */
+ if (!enable) {
+ kvm_clear_async_pf_completion_queue(vcpu);
+ apf->control_block = data;
+ return SMCCC_RET_SUCCESS;
+ }
+
+ /*
+ * The SDEI event and IRQ number should have been given
+ * prior to enablement.
+ */
+ if (!apf->sdei_event_num || !apf->irq) {
+ kvm_err("%s: Invalid SDEI event or IRQ (%d-%d %llx-%d)\n",
+ __func__, kvm->userspace_pid, vcpu->vcpu_idx,
+ apf->sdei_event_num, apf->irq);
+ return SMCCC_RET_INVALID_PARAMETER;
+ }
+
+ /* Register SDEI event notifier */
+ ret = kvm_sdei_register_notifier(kvm, apf->sdei_event_num,
+ kvm_arch_async_sdei_notifier);
+ if (ret) {
+ kvm_err("%s: Error %d registering SDEI notifier (%d-%d %llx)\n",
+ __func__, ret, kvm->userspace_pid, vcpu->vcpu_idx,
+ apf->sdei_event_num);
+ return SMCCC_RET_NOT_SUPPORTED;
+ }
+
+ /* Initialize cache shared by host and guest */
+ ret = kvm_gfn_to_hva_cache_init(kvm, &apf->cache, gpa,
+ offsetofend(struct kvm_vcpu_pv_apf_data, token));
+ if (ret) {
+ kvm_err("%s: Error %d initializing cache (%d-%d)\n",
+ __func__, ret, kvm->userspace_pid, vcpu->vcpu_idx);
+ return SMCCC_RET_NOT_SUPPORTED;
+ }
+
+ /* Flush the token table */
+ kvm_async_pf_reset_slot(vcpu);
+ apf->send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS);
+ kvm_async_pf_wakeup_all(vcpu);
+ apf->control_block = data;
+
+ return SMCCC_RET_SUCCESS;
+}
+
long kvm_arch_async_pf_hypercall(struct kvm_vcpu *vcpu,
long *r1, long *r2, long *r3)
{
struct kvm *kvm = vcpu->kvm;
struct kvm_arch_async_pf_control *apf = vcpu->arch.apf;
u32 func;
+ u64 data;
long ret = SMCCC_RET_SUCCESS;
if (!apf) {
@@ -328,6 +431,22 @@ long kvm_arch_async_pf_hypercall(struct kvm_vcpu *vcpu,
func = smccc_get_arg1(vcpu);
switch (func) {
+ case ARM_SMCCC_KVM_FUNC_ASYNC_PF_VERSION:
+ *r1 = 0x010000; /* v1.0.0 */
+ break;
+ case ARM_SMCCC_KVM_FUNC_ASYNC_PF_SLOTS:
+ *r1 = ASYNC_PF_PER_VCPU;
+ break;
+ case ARM_SMCCC_KVM_FUNC_ASYNC_PF_SDEI:
+ *r1 = apf->sdei_event_num;
+ break;
+ case ARM_SMCCC_KVM_FUNC_ASYNC_PF_IRQ:
+ *r1 = apf->irq;
+ break;
+ case ARM_SMCCC_KVM_FUNC_ASYNC_PF_ENABLE:
+ data = (smccc_get_arg3(vcpu) << 32) | smccc_get_arg2(vcpu);
+ ret = kvm_arch_async_enable(vcpu, data);
+ break;
case ARM_SMCCC_KVM_FUNC_ASYNC_PF_IRQ_ACK:
if (!apf->pageready_pending)
break;
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 0476afbd3178..ae081156132d 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -129,6 +129,11 @@
ARM_SMCCC_KVM_FUNC_FEATURES)
/* Asynchronous page fault service */
+#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_VERSION 0
+#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_SLOTS 1
+#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_SDEI 2
+#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_IRQ 3
+#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_ENABLE 4
#define ARM_SMCCC_KVM_FUNC_ASYNC_PF_IRQ_ACK 5
#define ARM_SMCCC_VENDOR_HYP_KVM_ASYNC_PF_FUNC_ID \
--
2.23.0
next prev parent reply other threads:[~2021-02-09 5:10 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-09 5:03 [PATCH v2 00/17] Support Asynchronous Page Fault Gavin Shan
2021-02-09 5:03 ` [PATCH v2 01/17] KVM: async_pf: Move struct kvm_async_pf around Gavin Shan
2021-02-09 5:03 ` [PATCH v2 02/17] KVM: async_pf: Add helper function to check completion queue Gavin Shan
2021-02-09 5:03 ` [PATCH v2 03/17] KVM: async_pf: Make GFN slot management generic Gavin Shan
2021-02-09 5:03 ` [PATCH v2 04/17] KVM: x86: Use generic async PF slot management Gavin Shan
2021-02-09 5:03 ` [PATCH v2 05/17] arm64: Probe for the presence of KVM hypervisor services during boot Gavin Shan
2021-02-09 5:03 ` [PATCH v2 06/17] KVM: arm64: Advertise KVM UID to guests via SMCCC Gavin Shan
2021-02-09 5:03 ` [PATCH v2 07/17] KVM: arm64: Export kvm_handle_user_mem_abort() Gavin Shan
2021-02-09 5:03 ` [PATCH v2 08/17] KVM: arm64: Add paravirtualization header files Gavin Shan
2021-02-09 5:03 ` [PATCH v2 09/17] KVM: arm64: Support page-not-present notification Gavin Shan
2021-02-09 5:03 ` [PATCH v2 10/17] KVM: arm64: Support page-ready notification Gavin Shan
2021-02-09 5:03 ` Gavin Shan [this message]
2021-02-09 5:03 ` [PATCH v2 12/17] KVM: arm64: Support async PF ioctl commands Gavin Shan
2021-02-09 5:03 ` [PATCH v2 13/17] KVM: arm64: Export async PF capability Gavin Shan
2021-02-09 5:04 ` [PATCH v2 14/17] arm64: Detect async PF para-virtualization feature Gavin Shan
2021-02-09 5:04 ` [PATCH v2 15/17] arm64: Reschedule process on aync PF Gavin Shan
2021-02-09 5:04 ` [PATCH v2 16/17] arm64: Enable async PF Gavin Shan
2021-02-09 5:04 ` [PATCH v2 17/17] KVM: arm64: Add async PF document Gavin Shan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210209050403.103143-12-gshan@redhat.com \
--to=gshan@redhat.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=pbonzini@redhat.com \
--cc=shan.gavin@gmail.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®