[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220527080253.1562538-6-gshan@redhat.com>
Date: Fri, 27 May 2022 16:02:36 +0800
From: Gavin Shan <gshan@...hat.com>
To: kvmarm@...ts.cs.columbia.edu
Cc: maz@...nel.org, linux-kernel@...r.kernel.org, eauger@...hat.com,
oupton@...gle.com, Jonathan.Cameron@...wei.com,
pbonzini@...hat.com, vkuznets@...hat.com, will@...nel.org,
james.morse@....com, mark.rutland@....com,
shannon.zhaosl@...il.com, shijie@...eremail.onmicrosoft.com,
shan.gavin@...il.com
Subject: [PATCH v7 05/22] KVM: arm64: Support EVENT_{ENABLE, DISABLE} hypercall
This supports EVENT_{ENABLE, DISABLE} hypercall. The event can be
pending, but never be delivered to guest until it's enabled.
* The request is rejected if the event isn't registered or pending
for unregistration.
* When the event is enabled, KVM_REQ_SDEI is set to so that the
event can be delivered to guest, if it has been pending. The
delivery logic will be implemented in subsequent patches. For
now, it's nothing other than a flag.
Signed-off-by: Gavin Shan <gshan@...hat.com>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/sdei.c | 33 +++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c9d053c2569e..79a0043a908c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -47,6 +47,7 @@
#define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
#define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
+#define KVM_REQ_SDEI KVM_ARCH_REQ(7)
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
KVM_DIRTY_LOG_INITIALLY_SET)
diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c
index 40c2d585470d..a4046e7b21d8 100644
--- a/arch/arm64/kvm/sdei.c
+++ b/arch/arm64/kvm/sdei.c
@@ -41,6 +41,33 @@ static unsigned long event_register(struct kvm_vcpu *vcpu)
return SDEI_SUCCESS;
}
+static unsigned long event_enable(struct kvm_vcpu *vcpu, bool enable)
+{
+ struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
+ unsigned int num = smccc_get_arg(vcpu, 1);
+
+ if (num >= KVM_NR_SDEI_EVENTS)
+ return SDEI_INVALID_PARAMETERS;
+
+ /*
+ * Reject if the event hasn't been registered or pending
+ * for unregistration.
+ */
+ if (!test_bit(num, &vsdei->registered))
+ return SDEI_DENIED;
+
+ if (enable) {
+ set_bit(num, &vsdei->enabled);
+ if (!(vcpu->arch.flags & KVM_ARM64_SDEI_MASKED) &&
+ test_bit(num, &vsdei->pending))
+ kvm_make_request(KVM_REQ_SDEI, vcpu);
+ } else {
+ clear_bit(num, &vsdei->enabled);
+ }
+
+ return SDEI_SUCCESS;
+}
+
int kvm_sdei_call(struct kvm_vcpu *vcpu)
{
struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
@@ -62,6 +89,12 @@ int kvm_sdei_call(struct kvm_vcpu *vcpu)
case SDEI_1_0_FN_SDEI_EVENT_REGISTER:
ret = event_register(vcpu);
break;
+ case SDEI_1_0_FN_SDEI_EVENT_ENABLE:
+ ret = event_enable(vcpu, true);
+ break;
+ case SDEI_1_0_FN_SDEI_EVENT_DISABLE:
+ ret = event_enable(vcpu, false);
+ break;
default:
ret = SDEI_NOT_SUPPORTED;
}
--
2.23.0
Powered by blists - more mailing lists