qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 15/25] spapr: notify the CPU when the XIVE inter


From: Benjamin Herrenschmidt
Subject: Re: [Qemu-devel] [PATCH 15/25] spapr: notify the CPU when the XIVE interrupt priority is more privileged
Date: Mon, 04 Dec 2017 10:09:20 -0600

On Mon, 2017-12-04 at 12:17 +1100, David Gibson wrote:
> On Sat, Dec 02, 2017 at 08:40:58AM -0600, Benjamin Herrenschmidt wrote:
> > On Thu, 2017-11-30 at 16:00 +1100, David Gibson wrote:
> > > 
> > > >  static uint64_t spapr_xive_icp_accept(sPAPRXiveICP *icp)
> > > >  {
> > > > -    return 0;
> > > > +    uint8_t nsr = icp->tima_os[TM_NSR];
> > > > +
> > > > +    qemu_irq_lower(icp->output);
> > > > +
> > > > +    if (icp->tima_os[TM_NSR] & TM_QW1_NSR_EO) {
> > > > +        uint8_t cppr = icp->tima_os[TM_PIPR];
> > > > +
> > > > +        icp->tima_os[TM_CPPR] = cppr;
> > > > +
> > > > +        /* Reset the pending buffer bit */
> > > > +        icp->tima_os[TM_IPB] &= ~priority_to_ipb(cppr);
> > > 
> > > What if multiple irqs of the same priority were queued?
> > 
> > It's the job of the OS to handle that case by consuming from the queue
> > until it's empty. There is an MMIO the guest can use if it wants to
> > that can set the IPB bits back to 1 for a given priority. Otherwise in
> > Linux we just have a SW way to force a replay.
> 
> Ok, so "accept" is effectively saying the OS is accepting all
> interrupts from that queue, right?

It's whatever you want it to mean. It's simply a test & clear on the
prio bit. From a HW standpoint, you could have multiple queues or just
set an internal SW flag to go chck again later etc...

> 
> > 
> > > > +        icp->tima_os[TM_PIPR] = ipb_to_pipr(icp->tima_os[TM_IPB]);
> > > > +
> > > > +        /* Drop Exception bit for OS */
> > > > +        icp->tima_os[TM_NSR] &= ~TM_QW1_NSR_EO;
> > > > +    }
> > > > +
> > > > +    return (nsr << 8) | icp->tima_os[TM_CPPR];
> > > > +}
> > > > +
> > > > +static void spapr_xive_icp_notify(sPAPRXiveICP *icp)
> > > > +{
> > > > +    if (icp->tima_os[TM_PIPR] < icp->tima_os[TM_CPPR]) {
> > > > +        icp->tima_os[TM_NSR] |= TM_QW1_NSR_EO;
> > > > +        qemu_irq_raise(icp->output);
> > > > +    }
> > > >  }
> > > >  
> > > >  static void spapr_xive_icp_set_cppr(sPAPRXiveICP *icp, uint8_t cppr)
> > > > @@ -51,6 +105,9 @@ static void spapr_xive_icp_set_cppr(sPAPRXiveICP 
> > > > *icp, uint8_t cppr)
> > > >      }
> > > >  
> > > >      icp->tima_os[TM_CPPR] = cppr;
> > > > +
> > > > +    /* CPPR has changed, inform the ICP which might raise an exception 
> > > > */
> > > > +    spapr_xive_icp_notify(icp);
> > > >  }
> > > >  
> > > >  /*
> > > > @@ -224,6 +281,8 @@ static void spapr_xive_irq(sPAPRXive *xive, int 
> > > > lisn)
> > > >      XiveEQ *eq;
> > > >      uint32_t eq_idx;
> > > >      uint8_t priority;
> > > > +    uint32_t server;
> > > > +    sPAPRXiveICP *icp;
> > > >  
> > > >      ive = spapr_xive_get_ive(xive, lisn);
> > > >      if (!ive || !(ive->w & IVE_VALID)) {
> > > > @@ -253,6 +312,13 @@ static void spapr_xive_irq(sPAPRXive *xive, int 
> > > > lisn)
> > > >          qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not 
> > > > implemented\n");
> > > >      }
> > > >  
> > > > +    server = GETFIELD(EQ_W6_NVT_INDEX, eq->w6);
> > > > +    icp = spapr_xive_icp_get(xive, server);
> > > > +    if (!icp) {
> > > > +        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No ICP for server %d\n", 
> > > > server);
> > > > +        return;
> > > > +    }
> > > > +
> > > >      if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) == 0) {
> > > >          priority = GETFIELD(EQ_W7_F0_PRIORITY, eq->w7);
> > > >  
> > > > @@ -260,9 +326,18 @@ static void spapr_xive_irq(sPAPRXive *xive, int 
> > > > lisn)
> > > >          if (priority == 0xff) {
> > > >              g_assert_not_reached();
> > > >          }
> > > > +
> > > > +        /* Update the IPB (Interrupt Pending Buffer) with the priority
> > > > +         * of the new notification and inform the ICP, which will
> > > > +         * decide to raise the exception, or not, depending the CPPR.
> > > > +         */
> > > > +        icp->tima_os[TM_IPB] |= priority_to_ipb(priority);
> > > > +        icp->tima_os[TM_PIPR] = ipb_to_pipr(icp->tima_os[TM_IPB]);
> > > >      } else {
> > > >          qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n");
> > > >      }
> > > > +
> > > > +    spapr_xive_icp_notify(icp);
> > > >  }
> > > >  
> > > >  /*
> > > 
> > > 
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]