This supports EVENT_REGISTER hypercall, which is used by guest to register event. The event won't be raised until it's registered and enabled. There are several cases where the request is injected: * The event isn't supported by KVM * The event has been registered or pending for unregistration * The reserved bits or relative mode are set in @flags argument Signed-off-by: Gavin Shan <gshan@xxxxxxxxxx> --- arch/arm64/kvm/sdei.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c index 0c4415fcad16..40c2d585470d 100644 --- a/arch/arm64/kvm/sdei.c +++ b/arch/arm64/kvm/sdei.c @@ -13,6 +13,34 @@ #include <kvm/arm_hypercalls.h> #include <asm/kvm_sdei.h> +static unsigned long event_register(struct kvm_vcpu *vcpu) +{ + struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei; + unsigned int num = smccc_get_arg(vcpu, 1); + unsigned long flags = smccc_get_arg(vcpu, 4); + + if (num >= KVM_NR_SDEI_EVENTS) + return SDEI_INVALID_PARAMETERS; + + /* Reject if the reserved bits or relative mode are set */ + if (flags & ~0x1UL) + return SDEI_INVALID_PARAMETERS; + + /* + * Reject if the event has been registered or pending for + * unregistration. + */ + if (test_bit(num, &vsdei->registered) || + test_bit(num, &vsdei->running)) + return SDEI_DENIED; + + vsdei->handlers[num].ep_addr = smccc_get_arg(vcpu, 2); + vsdei->handlers[num].ep_arg = smccc_get_arg(vcpu, 3); + set_bit(num, &vsdei->registered); + + return SDEI_SUCCESS; +} + int kvm_sdei_call(struct kvm_vcpu *vcpu) { struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei; @@ -31,6 +59,9 @@ int kvm_sdei_call(struct kvm_vcpu *vcpu) } switch (func) { + case SDEI_1_0_FN_SDEI_EVENT_REGISTER: + ret = event_register(vcpu); + break; default: ret = SDEI_NOT_SUPPORTED; } -- 2.23.0 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm