All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mostafa Saleh <smostafa@google.com>
To: Jean-Philippe Brucker <jean-philippe@linaro.org>
Cc: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,
	Eric Auger <eric.auger@redhat.com>,
	qemu-arm@nongnu.org
Subject: Re: [PATCH] hw/arm/smmuv3: Add GBPA register
Date: Thu, 5 Jan 2023 17:26:26 +0000	[thread overview]
Message-ID: <Y7cIQqc19+Phb/CV@google.com> (raw)
In-Reply-To: <Y7VxFpoTjwNaolTG@myrica>

Hi Jean,

Thanks for taking the time to look into this.

On Wed, Jan 04, 2023 at 12:29:10PM +0000, Jean-Philippe Brucker wrote:
> Hi Mostafa,
> 
> On Mon, Dec 19, 2022 at 12:57:20PM +0000, Mostafa Saleh wrote:
> > GBPA register can be used to globally abort all
> > transactions.
> > 
> > Only UPDATE and ABORT bits are considered in this patch.
> 
> That's fair, although it effectively implements all bits since
> smmuv3_translate() ignores memory attributes anyway
> 
> > 
> > It is described in the SMMU manual in "6.3.14 SMMU_GBPA".
> > ABORT reset value is IMPLEMENTATION DEFINED, it is chosen to
> > be zero(Do not abort incoming transactions).
> > 
> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > ---
> >  hw/arm/smmuv3-internal.h |  4 ++++
> >  hw/arm/smmuv3.c          | 14 ++++++++++++++
> >  include/hw/arm/smmuv3.h  |  1 +
> >  3 files changed, 19 insertions(+)
> > 
> > diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
> > index bce161870f..71f70141e8 100644
> > --- a/hw/arm/smmuv3-internal.h
> > +++ b/hw/arm/smmuv3-internal.h
> > @@ -79,6 +79,10 @@ REG32(CR0ACK,              0x24)
> >  REG32(CR1,                 0x28)
> >  REG32(CR2,                 0x2c)
> >  REG32(STATUSR,             0x40)
> > +REG32(GBPA,                0x44)
> > +    FIELD(GBPA, ABORT,        20, 1)
> > +    FIELD(GBPA, UPDATE,       31, 1)
> > +
> >  REG32(IRQ_CTRL,            0x50)
> >      FIELD(IRQ_CTRL, GERROR_IRQEN,        0, 1)
> >      FIELD(IRQ_CTRL, PRI_IRQEN,           1, 1)
> > diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> > index 955b89c8d5..2843bc3da9 100644
> > --- a/hw/arm/smmuv3.c
> > +++ b/hw/arm/smmuv3.c
> > @@ -285,6 +285,7 @@ static void smmuv3_init_regs(SMMUv3State *s)
> >      s->gerror = 0;
> >      s->gerrorn = 0;
> >      s->statusr = 0;
> > +    s->gbpa = 0;
> >  }
> >  
> >  static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
> > @@ -663,6 +664,11 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
> >          goto epilogue;
> >      }
> >  
> > +    if (FIELD_EX32(s->gbpa, GBPA, ABORT)) {
> > +        status = SMMU_TRANS_ABORT;
> > +        goto epilogue;
> > +    }
> > +
> 
> GBPA is only taken into account when SMMU_CR0.SMMUEN is 0 (6.3.9.6 SMMUEN)
> 
I missed that, will update it in V2.

> >      cfg = smmuv3_get_config(sdev, &event);
> >      if (!cfg) {
> >          status = SMMU_TRANS_ERROR;
> > @@ -1170,6 +1176,10 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
> >      case A_GERROR_IRQ_CFG2:
> >          s->gerror_irq_cfg2 = data;
> >          return MEMTX_OK;
> > +    case A_GBPA:
> > +        /* Ignore update bit as write is synchronous. */
> 
> We could also ignore a write that has Update=0, since that's required for
> SMMUv3.2+ implementations (6.3.14.1 Update procedure)

I will add it in V2.

> > +        s->gbpa = data & ~R_GBPA_UPDATE_MASK;
> 
> Do we need to synchronize with concurrent transactions here?
> I couldn't find if QEMU already serializes MMIO writes and IOMMU
> translation.
> 
> "Transactions arriving at the SMMU after completion of a GPBA update are
> guaranteed to take the new attributes written." The guest tests completion
> by reading the Update bit:
> 
> 	vCPU (host CPU 0)		Device thread (host CPU 1)
> 
> 	(a) read GBPA.abort = 1
> 	(b) write GBPA.{update,abort} = {1,0}
> 	(c) read GBPA.update = 0
> 	(d) launch DMA			(e) execute DMA
> 					(f) translation must read GBPA.abort = 0
> 
> I guess memory barriers after (b) and before (f) would ensure that. But I
> wonder if SMMUEN also needs additional synchronization, and in that case a
> rwlock would probably be simpler.
> 

From what I see, it does with qemu_global_mutex.
smmu_write_mmio: acquired from context of io_writex
smmuv3_translate: acquired from context of os_host_main_loop_wait
So I'd assume this should be fine. (I also checked with GDB)

However, if I missed something, and we need to synchronize, I think this
would also be a bug in SMMUEN.
As it is written from smmu_write_mmio and read at smmuv3_translate the
same way as GBPA.

And as described here (6.3.9.6 SMMUEN)
Completion of an Update of SMMUEN from 0 to 1 ensures that:
-Configuration written to SMMU_(S_)CR2 has taken effect.
-All new transactions will be treated with STE configuration relevant to
their stream, and will not undergo SMMU bypass.

So it will suffer from the same problem.

Thanks,
Mostafa

> Thanks,
> Jean
> 
> > +        return MEMTX_OK;
> >      case A_STRTAB_BASE: /* 64b */
> >          s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
> >          return MEMTX_OK;
> > @@ -1318,6 +1328,9 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
> >      case A_STATUSR:
> >          *data = s->statusr;
> >          return MEMTX_OK;
> > +    case A_GBPA:
> > +        *data = s->gbpa;
> > +        return MEMTX_OK;
> >      case A_IRQ_CTRL:
> >      case A_IRQ_CTRL_ACK:
> >          *data = s->irq_ctrl;
> > @@ -1495,6 +1508,7 @@ static const VMStateDescription vmstate_smmuv3 = {
> >          VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3),
> >          VMSTATE_UINT32(cr0ack, SMMUv3State),
> >          VMSTATE_UINT32(statusr, SMMUv3State),
> > +        VMSTATE_UINT32(gbpa, SMMUv3State),
> >          VMSTATE_UINT32(irq_ctrl, SMMUv3State),
> >          VMSTATE_UINT32(gerror, SMMUv3State),
> >          VMSTATE_UINT32(gerrorn, SMMUv3State),
> > diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> > index f1921fdf9e..9899fa1860 100644
> > --- a/include/hw/arm/smmuv3.h
> > +++ b/include/hw/arm/smmuv3.h
> > @@ -46,6 +46,7 @@ struct SMMUv3State {
> >      uint32_t cr[3];
> >      uint32_t cr0ack;
> >      uint32_t statusr;
> > +    uint32_t gbpa;
> >      uint32_t irq_ctrl;
> >      uint32_t gerror;
> >      uint32_t gerrorn;
> > -- 
> > 2.39.0.314.g84b9a713c41-goog
> > 
> > 

  reply	other threads:[~2023-01-05 17:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-19 12:57 [PATCH] hw/arm/smmuv3: Add GBPA register Mostafa Saleh
2023-01-04 12:29 ` Jean-Philippe Brucker
2023-01-05 17:26   ` Mostafa Saleh [this message]
2023-01-06 13:07   ` Eric Auger
2023-01-09 13:53     ` Mostafa Saleh

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=Y7cIQqc19+Phb/CV@google.com \
    --to=smostafa@google.com \
    --cc=eric.auger@redhat.com \
    --cc=jean-philippe@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.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.