[PATCH v4 03/13] ARM: KVM: Initial VGIC infrastructure support
Will Deacon
will.deacon at arm.com
Wed Nov 28 09:13:28 EST 2012
On Wed, Nov 28, 2012 at 01:09:37PM +0000, Marc Zyngier wrote:
> On 28/11/12 12:49, Will Deacon wrote:
> > On Sat, Nov 10, 2012 at 03:44:37PM +0000, Christoffer Dall wrote:
> >> @@ -363,7 +370,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
> >> */
> >> int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
> >> {
> >> - return !!v->arch.irq_lines;
> >> + return !!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v);
> >> }
> >
> > So interrupt injection without the in-kernel GIC updates irq_lines, but the
> > in-kernel GIC has its own separate data structures? Why can't the in-kernel GIC
> > just use irq_lines instead of irq_pending_on_cpu?
>
> They serve very different purposes:
> - irq_lines directly controls the IRQ and FIQ lines (it is or-ed into
> the HCR register before entering the guest)
> - irq_pending_on_cpu deals with the CPU interface, and only that. Plus,
> it is a kernel only thing. What triggers the interrupt on the guest is
> the presence of list registers with a pending state.
>
> You signal interrupts one way or the other.
Ok, thanks for the explanation. I suspect that we could use (another)
cosmetic change then. How about cpui_irq_pending and hcr_irq_pending?
> >> int kvm_arch_vcpu_in_guest_mode(struct kvm_vcpu *v)
> >> @@ -633,6 +640,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
> >>
> >> update_vttbr(vcpu->kvm);
> >>
> >> + kvm_vgic_sync_to_cpu(vcpu);
> >> +
> >> local_irq_disable();
> >>
> >> /*
> >> @@ -645,6 +654,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
> >>
> >> if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
> >> local_irq_enable();
> >> + kvm_vgic_sync_from_cpu(vcpu);
> >> continue;
> >> }
> >
> > For VFP, we use different terminology (sync and flush). I don't think they're
> > any clearer than what you have, but the consistency would be nice.
>
> Which one maps to which?
sync: hardware -> data structure
flush: data structure -> hardware
> > Given that both these functions are run with interrupts enabled, why doesn't
> > the second require a lock for updating dist->irq_pending_on_cpu? I notice
> > there's a random smp_mb() over there...
>
> Updating *only* irq_pending_on_cpu doesn't require the lock (set_bit()
> should be safe, and I think the smp_mb() is a leftover of some debugging
> hack). kvm_vgic_to_cpu() does a lot more (it picks interrupt from the
> distributor, hence requires the lock to be taken).
Ok, if the barrier is just a hangover from something else and you don't have
any races with test/clear operations then you should be alright.
Will
More information about the linux-arm-kernel
mailing list