[PATCH v4 27/56] KVM: arm/arm64: vgic-new: Add ACTIVE registers handlers
Andre Przywara
andre.przywara at arm.com
Thu May 19 03:12:55 PDT 2016
Hi Marc,
can you have a quick look below?
On 18/05/16 14:01, Christoffer Dall wrote:
>> +
>> +void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
>> + gpa_t addr, unsigned int len,
>> + unsigned long val)
>> +{
>> + u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
>> + int i;
>> +
>> + kvm_arm_halt_guest(vcpu->kvm);
>> + for_each_set_bit(i, &val, len * 8) {
>> + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
>> +
>> + spin_lock(&irq->irq_lock);
>> + /*
>> + * If this virtual IRQ was written into a list register, we
>> + * have to make sure the CPU that runs the VCPU thread has
>> + * synced back LR state to the struct vgic_irq. We can only
>> + * know this for sure, when either this irq is not assigned to
>> + * anyone's AP list anymore, or the VCPU thread is not
>> + * running on any CPUs.
>> + *
>> + * In the opposite case, we know the VCPU thread may be on its
>> + * way back from the guest and still has to sync back this
>> + * IRQ, so we release and re-acquire the spin_lock to let the
>> + * other thread sync back the IRQ.
>> + */
>> + while (irq->vcpu && /* IRQ may have state in an LR somewhere */
>> + irq->vcpu->cpu != -1) /* VCPU thread is running */
>> + cond_resched_lock(&irq->irq_lock);
>> +
>> + irq->active = false;
>> + spin_unlock(&irq->irq_lock);
>> + }
>> + kvm_arm_resume_guest(vcpu->kvm);
>> +}
>> +
>> +void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
>> + gpa_t addr, unsigned int len,
>> + unsigned long val)
>> +{
>> + u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
>> + int i;
>> +
>> + for_each_set_bit(i, &val, len * 8) {
>> + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
>> +
>> + spin_lock(&irq->irq_lock);
>> +
>> + /*
>> + * If the IRQ was already active or it was on a VCPU before
>> + * or there is no target VCPU assigned at the moment, then
>> + * just proceed.
>> + */
>> + if (irq->active || irq->vcpu || !irq->target_vcpu) {
>
> why is it that we don't care if this IRQ is on a LR, for example being
> just pending and not active, and we thereby loose this active state when
> the vcpu syncs back the state?
Mmmh, good question. I don't remember anymore why this irq->vcpu check
was added.
Marc, can you confirm that this is OK to be removed?
I think it's an optimization anyway.
Thanks,
Andre,
>
> We care for the case where we clear the active state, but not when we
> set it. Perhaps we discussed this in the past, but now I've forgotten,
> so that should at least be documented somehow.
>
>> + irq->active = true;
>> +
>> + spin_unlock(&irq->irq_lock);
>> + continue;
>> + }
>> +
>> + irq->active = true;
>> + vgic_queue_irq_unlock(vcpu->kvm, irq);
>
> this won't work just yet, but I think all that's needed to make it work
> is this patchlet:
>
> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> index c22f7e2..27204f22 100644
> --- a/virt/kvm/arm/vgic/vgic.c
> +++ b/virt/kvm/arm/vgic/vgic.c
> @@ -81,7 +81,7 @@ static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq)
>
> /* If the interrupt is active, it must stay on the current vcpu */
> if (irq->active)
> - return irq->vcpu;
> + return irq->vcpu ? : irq->target_vcpu;
>
> /*
> * If the IRQ is not active but enabled and pending, we should direct
>
>
> Thanks,
> -Christoffer
>
More information about the linux-arm-kernel
mailing list