Re: [PATCH v4 12/21] KVM: arm64: Support SDEI_{PRIVATE, SHARED}_RESET hypercall

From: Gavin Shan
Date: Tue Jan 11 2022 - 22:01:39 EST


Hi Eric,

On 11/10/21 4:37 AM, Eric Auger wrote:
On 8/15/21 2:13 AM, Gavin Shan wrote:
This supports SDEI_{PRIVATE, SHARED}_RESET. They are used by the
guest to purge the private or shared SDEI events, which are registered
to reset all private SDEI event registrations of the calling PE (resp.
PRIVATE or SHARED)

Ok.

previously.

Signed-off-by: Gavin Shan <gshan@xxxxxxxxxx>
---
arch/arm64/kvm/sdei.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)

diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c
index 3fb33258b494..62efee2b67b8 100644
--- a/arch/arm64/kvm/sdei.c
+++ b/arch/arm64/kvm/sdei.c
@@ -582,6 +582,29 @@ static unsigned long kvm_sdei_hypercall_mask(struct kvm_vcpu *vcpu,
return ret;
}
+static unsigned long kvm_sdei_hypercall_reset(struct kvm_vcpu *vcpu,
+ bool private)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_sdei_kvm *ksdei = kvm->arch.sdei;
+ struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
+ unsigned int mask = private ? (1 << SDEI_EVENT_TYPE_PRIVATE) :
+ (1 << SDEI_EVENT_TYPE_SHARED);
+ unsigned long ret = SDEI_SUCCESS;
+
+ /* Sanity check */
+ if (!(ksdei && vsdei)) {
+ ret = SDEI_NOT_SUPPORTED;
+ goto out;
+ }
+
+ spin_lock(&ksdei->lock);
+ kvm_sdei_remove_kvm_events(kvm, mask, false);
With kvm_sdei_remove_kvm_events() implementation, why do you make sure
that events which have a running handler get unregistered once the
handler completes? I just see the refcount check that prevents the "KVM
event object" from being removed.

Good point. I think here we need enhancement to cancel the pending
events prior to destroying them. I will think about it :)

+ spin_unlock(&ksdei->lock);
+out:
+ return ret;
+}
+
int kvm_sdei_hypercall(struct kvm_vcpu *vcpu)
{
u32 func = smccc_get_function(vcpu);
@@ -626,8 +649,14 @@ int kvm_sdei_hypercall(struct kvm_vcpu *vcpu)
break;
case SDEI_1_0_FN_SDEI_INTERRUPT_BIND:
case SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE:
+ ret = SDEI_NOT_SUPPORTED;
+ break;
case SDEI_1_0_FN_SDEI_PRIVATE_RESET:
+ ret = kvm_sdei_hypercall_reset(vcpu, true);
+ break;
case SDEI_1_0_FN_SDEI_SHARED_RESET:
+ ret = kvm_sdei_hypercall_reset(vcpu, false);
+ break;
default:
ret = SDEI_NOT_SUPPORTED;
}


Thanks,
Gavin