2022-04-05 00:08:09

by Gavin Shan

[permalink] [raw]
Subject: [PATCH v6 14/18] KVM: arm64: Support SDEI_EVENT_SIGNAL hypercall

This supports SDEI_EVENT_SIGNAL hypercall. It's used by guest
to inject event, whose number must be zero to the specified
vCPU. As the shared event isn't supported, calling vCPU is
assumed to be the target.

Signed-off-by: Gavin Shan <[email protected]>
---
arch/arm64/kvm/sdei.c | 45 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)

diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c
index ebdbe7810cf0..e1f6ab9800ee 100644
--- a/arch/arm64/kvm/sdei.c
+++ b/arch/arm64/kvm/sdei.c
@@ -455,6 +455,48 @@ static unsigned long hypercall_mask(struct kvm_vcpu *vcpu, bool mask)
return ret;
}

+static unsigned long hypercall_signal(struct kvm_vcpu *vcpu)
+{
+ struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
+ struct kvm_sdei_event *event;
+ unsigned int num = smccc_get_arg(vcpu, 1);
+ unsigned long ret = SDEI_SUCCESS;
+
+ /*
+ * The event must be the software signaled one, whose number
+ * is zero.
+ */
+ if (!kvm_sdei_is_sw_signaled(num)) {
+ ret = SDEI_INVALID_PARAMETERS;
+ goto out;
+ }
+
+ spin_lock(&vsdei->lock);
+
+ /* Check if the vcpu has been masked */
+ if (vsdei->masked) {
+ ret = SDEI_INVALID_PARAMETERS;
+ goto unlock;
+ }
+
+ /* Check if the event exists */
+ event = find_event(vcpu, num);
+ if (!event) {
+ ret = SDEI_INVALID_PARAMETERS;
+ goto unlock;
+ }
+
+ if (inject_event(vcpu, event)) {
+ ret = SDEI_INVALID_PARAMETERS;
+ goto unlock;
+ }
+
+unlock:
+ spin_unlock(&vsdei->lock);
+out:
+ return ret;
+}
+
static unsigned long hypercall_reset(struct kvm_vcpu *vcpu, bool private)
{
struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
@@ -539,6 +581,9 @@ int kvm_sdei_call(struct kvm_vcpu *vcpu)
case SDEI_1_0_FN_SDEI_PE_UNMASK:
ret = hypercall_mask(vcpu, false);
break;
+ case SDEI_1_1_FN_SDEI_EVENT_SIGNAL:
+ ret = hypercall_signal(vcpu);
+ break;
case SDEI_1_0_FN_SDEI_PRIVATE_RESET:
ret = hypercall_reset(vcpu, true);
break;
--
2.23.0


2022-05-02 12:31:29

by Gavin Shan

[permalink] [raw]
Subject: Re: [PATCH v6 14/18] KVM: arm64: Support SDEI_EVENT_SIGNAL hypercall

Hi Oliver,

On 5/1/22 5:32 AM, Oliver Upton wrote:
> On Sun, Apr 03, 2022 at 11:39:07PM +0800, Gavin Shan wrote:
>> This supports SDEI_EVENT_SIGNAL hypercall. It's used by guest
>> to inject event, whose number must be zero to the specified
>> vCPU. As the shared event isn't supported, calling vCPU is
>> assumed to be the target.
>>
>> Signed-off-by: Gavin Shan <[email protected]>
>> ---
>> arch/arm64/kvm/sdei.c | 45 +++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 45 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c
>> index ebdbe7810cf0..e1f6ab9800ee 100644
>> --- a/arch/arm64/kvm/sdei.c
>> +++ b/arch/arm64/kvm/sdei.c
>> @@ -455,6 +455,48 @@ static unsigned long hypercall_mask(struct kvm_vcpu *vcpu, bool mask)
>> return ret;
>> }
>>
>> +static unsigned long hypercall_signal(struct kvm_vcpu *vcpu)
>> +{
>> + struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
>> + struct kvm_sdei_event *event;
>> + unsigned int num = smccc_get_arg(vcpu, 1);
>> + unsigned long ret = SDEI_SUCCESS;
>> +
>> + /*
>> + * The event must be the software signaled one, whose number
>> + * is zero.
>> + */
>> + if (!kvm_sdei_is_sw_signaled(num)) {
>> + ret = SDEI_INVALID_PARAMETERS;
>> + goto out;
>> + }
>> +
>> + spin_lock(&vsdei->lock);
>> +
>> + /* Check if the vcpu has been masked */
>> + if (vsdei->masked) {
>> + ret = SDEI_INVALID_PARAMETERS;
>> + goto unlock;
>> + }
>
> You should still be able to signal an event if the vCPU is masked. Just
> means the bit will rot in the pending bitmap until the vCPU is unmasked.
>

Nice point! The event pending state is set if vCPU is masked. However,
it's not becoming active until the vCPU is unmasked :)

Thanks,
Gavin

2022-05-02 23:18:53

by Oliver Upton

[permalink] [raw]
Subject: Re: [PATCH v6 14/18] KVM: arm64: Support SDEI_EVENT_SIGNAL hypercall

Hi Gavin,

On Sun, Apr 03, 2022 at 11:39:07PM +0800, Gavin Shan wrote:
> This supports SDEI_EVENT_SIGNAL hypercall. It's used by guest
> to inject event, whose number must be zero to the specified
> vCPU. As the shared event isn't supported, calling vCPU is
> assumed to be the target.
>
> Signed-off-by: Gavin Shan <[email protected]>
> ---
> arch/arm64/kvm/sdei.c | 45 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/arch/arm64/kvm/sdei.c b/arch/arm64/kvm/sdei.c
> index ebdbe7810cf0..e1f6ab9800ee 100644
> --- a/arch/arm64/kvm/sdei.c
> +++ b/arch/arm64/kvm/sdei.c
> @@ -455,6 +455,48 @@ static unsigned long hypercall_mask(struct kvm_vcpu *vcpu, bool mask)
> return ret;
> }
>
> +static unsigned long hypercall_signal(struct kvm_vcpu *vcpu)
> +{
> + struct kvm_sdei_vcpu *vsdei = vcpu->arch.sdei;
> + struct kvm_sdei_event *event;
> + unsigned int num = smccc_get_arg(vcpu, 1);
> + unsigned long ret = SDEI_SUCCESS;
> +
> + /*
> + * The event must be the software signaled one, whose number
> + * is zero.
> + */
> + if (!kvm_sdei_is_sw_signaled(num)) {
> + ret = SDEI_INVALID_PARAMETERS;
> + goto out;
> + }
> +
> + spin_lock(&vsdei->lock);
> +
> + /* Check if the vcpu has been masked */
> + if (vsdei->masked) {
> + ret = SDEI_INVALID_PARAMETERS;
> + goto unlock;
> + }

You should still be able to signal an event if the vCPU is masked. Just
means the bit will rot in the pending bitmap until the vCPU is unmasked.

--
Thanks,
Oliver