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@xxxxxxxxxx> --- 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 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm