[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 5/6] vpt: add support for level interrupts



On Fri, Jun 22, 2018 at 08:23:02AM -0600, Jan Beulich wrote:
> >>> On 08.06.18 at 17:07, <roger.pau@xxxxxxxxxx> wrote:
> > @@ -316,7 +317,9 @@ int pt_update_irq(struct vcpu *v)
> >          if ( pt->pending_intr_nr )
> >          {
> >              /* RTC code takes care of disabling the timer itself. */
> > -            if ( (pt->irq != RTC_IRQ || !pt->priv) && pt_irq_masked(pt) )
> > +            if ( (pt->irq != RTC_IRQ || !pt->priv) && pt_irq_masked(pt) &&
> > +                 /* Level interrupts should be asserted even if masked. */
> > +                 !pt->level )
> >              {
> >                  /* suspend timer emulation */
> 
> Especially with this comment I'm not convinced this change is fully
> correct: Once a level triggered interrupt is latched in IRR, no
> further assertions are meaningful, and hence emulation could (and
> hence should) still be stopped to reduce resource consumption.

Hm, I can see your point, but that's going to make the implementation
of HPET level trigger interrupts more complex.

From my reading of the spec, when a level triggered HPET interrupt
fires the ISR bit must be set, regardless of whether the IRR of the
io-apic entry is set or not.

Maybe the right solution is to add a pt_irq_pending that checks the
IRR bit, and a new flag that the caller can set in order to requests
callbacks regardless of whether the interrupt has been injected or
not. Would you agree to that plan?

> > @@ -374,13 +378,36 @@ int pt_update_irq(struct vcpu *v)
> >          break;
> >  
> >      case PTSRC_ioapic:
> > -        /*
> > -         * NB: At the moment IO-APIC routed interrupts generated by vpt 
> > devices
> > -         * (HPET) are edge-triggered.
> > -         */
> > -        pt_vector = hvm_ioapic_assert(v->domain, irq, false);
> > +        pt_vector = hvm_ioapic_assert(v->domain, irq, level);
> >          if ( pt_vector < 0 || !vlapic_test_irq(vcpu_vlapic(v), pt_vector) )
> > +        {
> >              pt_vector = -1;
> > +            if ( level )
> > +            {
> > +                /*
> > +                 * Level interrupts are asserted even if the interrupt is
> > +                 * masked, so also execute the callback associated with the
> > +                 * timer.
> > +                 */
> > +                time_cb *cb = NULL;
> > +                void *cb_priv;
> > +
> > +                spin_lock(&v->arch.hvm_vcpu.tm_lock);
> > +                /* Make sure the timer is still on the list. */
> > +                list_for_each_entry ( pt, &v->arch.hvm_vcpu.tm_list, list )
> > +                    if ( pt == earliest_pt )
> > +                    {
> > +                        pt_irq_fired(v, pt);
> > +                        cb = pt->cb;
> > +                        cb_priv = pt->priv;
> > +                        break;
> > +                    }
> > +                spin_unlock(&v->arch.hvm_vcpu.tm_lock);
> > +
> > +                if ( cb != NULL )
> > +                    cb(v, cb_priv);
> > +            }
> > +        }
> >          break;
> 
> I'm not fully convinced, especially in the case that hvm_ioapic_assert()
> returned a negative value: Either the callback needs to be called in all
> cases (even if an edge triggered interrupt was not successfully asserted),
> or only when an interrupt really gets surfaced to the guest.

See my proposal above for adding a new option to signal whether the
callback should be executed regardless of whether interrupt injection
succeeded or not.

> 
> > @@ -447,12 +474,13 @@ void pt_migrate(struct vcpu *v)
> >  
> >  void create_periodic_time(
> >      struct vcpu *v, struct periodic_time *pt, uint64_t delta,
> > -    uint64_t period, uint8_t irq, time_cb *cb, void *data)
> > +    uint64_t period, uint8_t irq, time_cb *cb, void *data, bool level)
> >  {
> >      if ( !pt->source ||
> >           (irq >= NR_ISAIRQS && pt->source == PTSRC_isa) ||
> >           (irq >= hvm_domain_irq(v->domain)->nr_gsis &&
> > -          pt->source == PTSRC_ioapic) )
> > +          pt->source == PTSRC_ioapic) ||
> > +         (level && pt->source != PTSRC_ioapic) )
> 
> Could I talk you into avoiding the double checking against PTSRC_ioapic,
> by using a conditional expression?

So something like:

pt->source == PTSRC_ioapic ? irq >= hvm_domain_irq(v->domain)->nr_gsis : level

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.