All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: Shashi Mallela <shashi.mallela@linaro.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	Radoslaw Biernacki <rad@semihalf.com>,
	QEMU Developers <qemu-devel@nongnu.org>,
	qemu-arm <qemu-arm@nongnu.org>,
	Igor Mammedov <imammedo@redhat.com>,
	Leif Lindholm <leif@nuviainc.com>
Subject: Re: [PATCH v5 06/10] hw/intc: GICv3 redistributor ITS processing
Date: Mon, 5 Jul 2021 15:43:33 +0100	[thread overview]
Message-ID: <CAFEAcA-OC2UHfYFwgvXhZmkLAa7fhjog9HPGJMgXDyeUp3-X6g@mail.gmail.com> (raw)
In-Reply-To: <20210630153156.9421-7-shashi.mallela@linaro.org>

On Wed, 30 Jun 2021 at 16:32, Shashi Mallela <shashi.mallela@linaro.org> wrote:
>
> Implemented lpi processing at redistributor to get lpi config info
> from lpi configuration table,determine priority,set pending state in
> lpi pending table and forward the lpi to cpuif.Added logic to invoke
> redistributor lpi processing with translated LPI which set/clear LPI
> from ITS device as part of ITS INT,CLEAR,DISCARD command and
> GITS_TRANSLATER processing.
>
> Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
> ---
>  hw/intc/arm_gicv3.c                |  14 +++
>  hw/intc/arm_gicv3_common.c         |   1 +
>  hw/intc/arm_gicv3_cpuif.c          |   7 +-
>  hw/intc/arm_gicv3_its.c            |  24 ++++-
>  hw/intc/arm_gicv3_redist.c         | 142 +++++++++++++++++++++++++++++
>  hw/intc/gicv3_internal.h           |   8 ++
>  include/hw/intc/arm_gicv3_common.h |   7 ++
>  7 files changed, 197 insertions(+), 6 deletions(-)

> diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
> index adaee72c1f..5adb55a01a 100644
> --- a/hw/intc/arm_gicv3_its.c
> +++ b/hw/intc/arm_gicv3_its.c
> @@ -225,6 +225,7 @@ static MemTxResult process_its_cmd(GICv3ITSState *s, uint64_t value,
>      bool ite_valid = false;
>      uint64_t cte = 0;
>      bool cte_valid = false;
> +    uint64_t rdbase;
>      IteEntry ite;
>
>      if (cmd == NONE) {
> @@ -282,10 +283,18 @@ static MemTxResult process_its_cmd(GICv3ITSState *s, uint64_t value,
>           * command in the queue
>           */
>      } else {
> -        /*
> -         * Current implementation only supports rdbase == procnum
> -         * Hence rdbase physical address is ignored
> -         */

This change doesn't make us start handling the "is a physical address"
case, so why delete the comment?

> +        rdbase = (cte >> 1U) & RDBASE_PROCNUM_MASK;
> +
> +        if (rdbase > s->gicv3->num_cpu) {
> +            return res;
> +        }
> +
> +        if ((cmd == CLEAR) || (cmd == DISCARD)) {
> +            gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0);
> +        } else {
> +            gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1);
> +        }
> +
>          if (cmd == DISCARD) {
>              memset(&ite, 0 , sizeof(ite));
>              /* remove mapping from interrupt translation table */
> @@ -672,6 +681,13 @@ static void process_cmdq(GICv3ITSState *s)
>              break;
>          case GITS_CMD_INV:
>          case GITS_CMD_INVALL:
> +            /*
> +             * Current implementation doesn't cache any ITS tables,
> +             * but the calculated lpi priority information.We only

Missing space after "."

> +             * need to trigger lpi priority re-calculation to be in
> +             * sync with LPI config table or pending table changes.
> +             */
> +            gicv3_redist_update_lpi(s->gicv3->cpu);

I think we need to recalculate for all redistributors, not just the first one.

>              break;
>          default:
>              break;
> diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
> index fc3d95dcc6..97553e6ada 100644
> --- a/hw/intc/arm_gicv3_redist.c
> +++ b/hw/intc/arm_gicv3_redist.c
> @@ -254,6 +254,9 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
>          if (cs->gicr_typer & GICR_TYPER_PLPIS) {
>              if (value & GICR_CTLR_ENABLE_LPIS) {
>                  cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
> +                /* Check for any pending interr in pending table */
> +                gicv3_redist_update_lpi(cs);
> +                gicv3_redist_update(cs);
>              } else {
>                  cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
>              }
> @@ -532,6 +535,145 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
>      return r;
>  }
>
> +static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
> +{
> +    AddressSpace *as = &cs->gic->dma_as;
> +    uint64_t lpict_baddr;
> +    uint8_t lpite;
> +    uint8_t prio;
> +
> +    lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;
> +
> +    address_space_read(as, lpict_baddr + ((irq - GICV3_LPI_INTID_START) *
> +                       sizeof(lpite)), MEMTXATTRS_UNSPECIFIED, &lpite,
> +                       sizeof(lpite));
> +
> +    if (!(lpite & LPI_CTE_ENABLED)) {
> +        return;
> +    }
> +
> +    if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
> +        prio = lpite & LPI_PRIORITY_MASK;
> +    } else {
> +        prio = ((lpite & LPI_PRIORITY_MASK) >> 1) & 0x80;

Need to OR with 0x80, not AND.

> +    }
> +
> +    if ((prio < cs->hpplpi.prio) ||
> +        ((prio == cs->hpplpi.prio) && (irq <= cs->hpplpi.irq))) {
> +        cs->hpplpi.irq = irq;
> +        cs->hpplpi.prio = prio;
> +        /* LPIs are always non-secure Grp1 interrupts */
> +        cs->hpplpi.grp = GICV3_G1NS;
> +    }
> +}
> +
> +void gicv3_redist_update_lpi(GICv3CPUState *cs)
> +{
> +    /*
> +     * This function scans the LPI pending table and for each pending
> +     * LPI, reads the corresponding entry from LPI configuration table
> +     * to extract the priority info and determine if the current LPI
> +     * priority is lower than the last computed high priority lpi interrupt.
> +     * If yes, replace current LPI as the new high priority lpi interrupt.
> +     */
> +    AddressSpace *as = &cs->gic->dma_as;
> +    uint64_t lpipt_baddr;
> +    uint32_t pendt_size = 0;
> +    uint8_t pend;
> +    int i;
> +    uint64_t idbits;
> +
> +    idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
> +                 GICD_TYPER_IDBITS);
> +
> +    if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
> +        !cs->gicr_pendbaser || (idbits < GICR_PROPBASER_IDBITS_THRESHOLD)) {
> +        return;
> +    }
> +
> +    cs->hpplpi.prio = 0xff;
> +
> +    lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
> +
> +    /* Determine the highest priority pending interrupt among LPIs */
> +    pendt_size = (1ULL << (idbits + 1));
> +
> +    for (i = 0; i < pendt_size / 8; i++) {
> +        address_space_read(as, lpipt_baddr +
> +                (((GICV3_LPI_INTID_START + i) / 8) * sizeof(pend)),
> +                MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
> +
> +        if (!((1 << ((GICV3_LPI_INTID_START + i) % 8)) & pend)) {
> +            continue;
> +        }
> +
> +        gicv3_redist_check_lpi_priority(cs, GICV3_LPI_INTID_START + i);
> +    }
> +}
> +
> +void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
> +{
> +    /*
> +     * This function updates the pending bit in lpi pending table for
> +     * the irq being activated or deactivated.
> +     */
> +    AddressSpace *as = &cs->gic->dma_as;
> +    uint64_t lpipt_baddr;
> +    bool ispend = false;
> +    uint8_t pend;
> +
> +    /*
> +     * get the bit value corresponding to this irq in the
> +     * lpi pending table
> +     */
> +    lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
> +
> +    address_space_read(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
> +                       MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
> +
> +    /*
> +     * check if this LPI is better than the current hpplpi, if yes
> +     * just set hpplpi.prio and .irq without doing a full rescan
> +     */
> +    if (level) {
> +        gicv3_redist_check_lpi_priority(cs, irq);
> +    }
> +
> +    ispend = extract32(pend, irq % 8, 1);
> +
> +    /* no change in the value of pending bit,return */

Missing space after comma.

> +    if (ispend == level) {
> +        return;
> +    }

I would put the "is the level same as it already was" check before
we go off and do the priority-check, not after. Then you can do all
the handling of "the level changed" at the end, with
 if (level) {
     gicv3_redist_check_lpi_priority(...);
 } else {
     gicv3_redist_update_lpi(...);
 }

Also, if this is a level == 0, you don't need to do the full rescan
of the LPI table unless the LPI being deactivated is the current
highest priority LPI.

> +    pend = deposit32(pend, irq % 8, 1, level ? 1 : 0);
> +
> +    address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
> +                        MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
> +
> +    if (!level) {
> +        gicv3_redist_update_lpi(cs);
> +    }
> +}
> +
> +void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
> +{
> +    uint64_t idbits;
> +
> +    idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
> +                 GICD_TYPER_IDBITS);
> +
> +    if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
> +         !cs->gicr_pendbaser || (idbits < GICR_PROPBASER_IDBITS_THRESHOLD) ||
> +         (irq > (1ULL << (idbits + 1)))) {
> +        return;
> +    }
> +
> +    /* set/clear the pending bit for this irq */
> +    gicv3_redist_lpi_pending(cs, irq, level);
> +
> +    gicv3_redist_update(cs);
> +}
> +
>  void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
>  {
>      /* Update redistributor state for a change in an external PPI input line */
> diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
> index 43ce4a8a95..c0ec1d9a66 100644
> --- a/hw/intc/gicv3_internal.h
> +++ b/hw/intc/gicv3_internal.h
> @@ -308,6 +308,11 @@ FIELD(GITS_TYPER, CIL, 36, 1)
>
>  #define L1TABLE_ENTRY_SIZE         8
>
> +#define LPI_CTE_ENABLED          TABLE_ENTRY_VALID_MASK
> +#define LPI_CTE_PRIORITY_OFFSET    2
> +#define LPI_CTE_PRIORITY_MASK     ((1U << 6) - 1)

These aren't using the standard naming convention (_SHIFT for the
bitshift, and the _MASK should be in-place, not in the ls bits).
But you don't use the defines anyway, so you could just not bother
defining them.

thanks
-- PMM


  reply	other threads:[~2021-07-05 14:45 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-30 15:31 [PATCH v5 00/10] GICv3 LPI and ITS feature implementation Shashi Mallela
2021-06-30 15:31 ` [PATCH v5 01/10] hw/intc: GICv3 ITS initial framework Shashi Mallela
2021-07-05 14:58   ` Peter Maydell
2021-07-05 15:55     ` shashi.mallela
2021-07-05 16:25       ` Peter Maydell
2021-07-05 17:04         ` shashi.mallela
2021-07-05 18:58           ` Peter Maydell
2021-07-07  2:08             ` shashi.mallela
2021-07-06  7:44   ` Eric Auger
2021-07-07  2:06     ` shashi.mallela
2021-06-30 15:31 ` [PATCH v5 02/10] hw/intc: GICv3 ITS register definitions added Shashi Mallela
2021-07-06  9:29   ` Eric Auger
2021-07-08 17:27     ` Eric Auger
2021-08-05 21:14       ` shashi.mallela
2021-06-30 15:31 ` [PATCH v5 03/10] hw/intc: GICv3 ITS command queue framework Shashi Mallela
2021-07-06  9:31   ` Eric Auger
2021-06-30 15:31 ` [PATCH v5 04/10] hw/intc: GICv3 ITS Command processing Shashi Mallela
2021-07-05 14:07   ` Peter Maydell
2021-07-06  9:27     ` Eric Auger
2021-07-07  2:02       ` shashi.mallela
2021-07-05 14:54   ` Peter Maydell
2021-07-06  0:47     ` shashi.mallela
2021-07-06  3:25       ` shashi.mallela
2021-07-06  9:19         ` Peter Maydell
2021-07-06 12:46           ` shashi.mallela
2021-07-06 13:27             ` Peter Maydell
2021-07-07  2:08               ` shashi.mallela
2021-07-06 10:04         ` Eric Auger
2021-07-06 10:07           ` Peter Maydell
2021-07-06 10:05   ` Eric Auger
2021-06-30 15:31 ` [PATCH v5 05/10] hw/intc: GICv3 ITS Feature enablement Shashi Mallela
2021-07-05 14:20   ` Peter Maydell
2021-06-30 15:31 ` [PATCH v5 06/10] hw/intc: GICv3 redistributor ITS processing Shashi Mallela
2021-07-05 14:43   ` Peter Maydell [this message]
2021-06-30 15:31 ` [PATCH v5 07/10] hw/arm/sbsa-ref: add ITS support in SBSA GIC Shashi Mallela
2021-07-05 14:59   ` Peter Maydell
2021-06-30 15:31 ` [PATCH v5 08/10] tests/data/acpi/virt: Add IORT files for ITS Shashi Mallela
2021-06-30 15:31 ` [PATCH v5 09/10] hw/arm/virt: add ITS support in virt GIC Shashi Mallela
2021-06-30 15:31 ` [PATCH v5 10/10] tests/data/acpi/virt: Update IORT files for ITS Shashi Mallela
2021-07-05 15:02   ` Peter Maydell
2021-07-05 15:05 ` [PATCH v5 00/10] GICv3 LPI and ITS feature implementation Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFEAcA-OC2UHfYFwgvXhZmkLAa7fhjog9HPGJMgXDyeUp3-X6g@mail.gmail.com \
    --to=peter.maydell@linaro.org \
    --cc=imammedo@redhat.com \
    --cc=leif@nuviainc.com \
    --cc=mst@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rad@semihalf.com \
    --cc=shashi.mallela@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.