This supports SDEI_1_0_FN_SDEI_{PRIVATE,SHARED}_RESET hypercall by adding kvm_sdei_hypercall_reset(). We can't direct the hypercall to underly firmware for passthrou event because it might be shared by multiple VMs. So the trick is to simulate the behaviour to unregister all the (private or shared) events which have been registered on the speicific VM. However, the request is directed to underly firmware by calling sdei_event_unregister() when last event (reference) exits. Signed-off-by: Gavin Shan <gshan@xxxxxxxxxx> --- arch/arm64/kvm/sdei.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c index 0816136e73a6..2d5e44bb5497 100644 --- a/arch/arm64/kvm/sdei.c +++ b/arch/arm64/kvm/sdei.c @@ -741,6 +741,18 @@ static unsigned long kvm_sdei_reset(struct kvm *kvm, unsigned int types) return ret; } +static unsigned long kvm_sdei_hypercall_reset(struct kvm_vcpu *vcpu, + bool is_private) +{ + struct kvm *kvm = vcpu->kvm; + unsigned int types = is_private ? (1 << SDEI_EVENT_TYPE_PRIVATE) : + (1 << SDEI_EVENT_TYPE_SHARED); + + kvm_sdei_reset(kvm, types); + + return SDEI_SUCCESS; +} + int kvm_sdei_hypercall(struct kvm_vcpu *vcpu) { u32 function = smccc_get_function(vcpu); @@ -782,8 +794,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; } -- 2.23.0 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm