From: yong.wu@mediatek.com (Yong Wu)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 1/3] iommu/io-pgtable: Add ARMv7 short descriptor support
Date: Mon, 18 Jan 2016 14:28:55 +0800 [thread overview]
Message-ID: <1453098535.10156.21.camel@mhfsdcap03> (raw)
In-Reply-To: <56990CAC.5020606@arm.com>
On Fri, 2016-01-15 at 15:13 +0000, Robin Murphy wrote:
> On 14/01/16 13:05, Yong Wu wrote:
> > On Thu, 2015-12-17 at 20:50 +0000, Robin Murphy wrote:
> >> Add a nearly-complete ARMv7 short descriptor implementation, omitting
> >> only a few legacy and CPU-centric aspects which shouldn't be necessary
> >> for IOMMU API use anyway.
[...]
> >> +static int arm_v7s_split_blk_unmap(struct arm_v7s_io_pgtable *data,
> >> + unsigned long iova, size_t size,
> >> + arm_v7s_iopte *ptep)
> >> +{
> >> + unsigned long blk_start, blk_end, blk_size;
> >> + phys_addr_t blk_paddr;
> >> + arm_v7s_iopte table = 0;
> >> + struct io_pgtable_cfg *cfg = &data->iop.cfg;
> >> + int prot = arm_v7s_pte_to_prot(*ptep, 1);
> >> +
> >> + blk_size = ARM_V7S_BLOCK_SIZE(1);
> >> + blk_start = iova & ARM_V7S_LVL_MASK(1);
> >> + blk_end = blk_start + ARM_V7S_BLOCK_SIZE(1);
> >> + blk_paddr = *ptep & ARM_V7S_LVL_MASK(1);
> >> +
> >> + for (; blk_start < blk_end; blk_start += size, blk_paddr += size) {
> >> + arm_v7s_iopte *tablep;
> >> +
> >> + /* Unmap! */
> >> + if (blk_start == iova)
> >> + continue;
> >> +
> >> + /* __arm_v7s_map expects a pointer to the start of the table */
> >> + tablep = &table - ARM_V7S_LVL_IDX(blk_start, 1);
> >
> > The "table" seems not be initialized here. (LPAE too.) maybe I don't
> > get it here.
>
> It took me about 2 hours of staring at the original code to fully get my
> head round it, too ;) The comment would perhaps be better worded as
> "__arm_v7s_map expects a pointer to the start of *a* table". What we're
> doing is building up the whole level 2 table (with the relevant pages
> mapped) in advance _before_ touching the live level 1 table. Since
> __arm_v7s_map() is going to take the table pointer we pass and write an
> entry for the new level 2 table at the relevant index, we construct
> _just that entry_ ("arm_v7s_iopte table = 0;") and fake up a
> corresponding 'level 1 table pointer' - chances are that tablep itself
> is dangling way off the bottom of the stack somewhere, but the only
> entry in that 'table' that's going to be dereferenced is the one backed
> by the local variable.
Thanks for this comment, I get it.
It works well but I still don't think "tablep" is safe here. Currently
it must rely on "ptep += ARM_V7S_LVL_IDX(iova, lvl)" in the
__arm_v7s_map. this may be danger if __arm_v7s_map is changed in the
further. and at least it is not readable, 2 hours is needed even though
it's you;).
And the lvl is always 1 in the __arm_v7s_map below, so "tablep" is
expected to be the start of the lvl1 table rather than *a* start of the
table.
>
> > If we would like to get the start of the table, maybe :
> >
> > tablep = ptep - ARM_V7S_LVL_IDX(blk_start, 1);
> >
> > Even though we change "tablep" here, it will also fail in the
> > __arm_v7s_map since there is a value in current ptep(the pa of the
> > section), then it will call iopte_deref instread of creating a new
> > pgtable in the __arm_v7s_map below, then it will abort.
> >
> > so maybe we need unmap the ptep before this "for" loop.
> > __arm_v7s_set_pte(ptep, 0, 1, cfg);
> >
> >> + if (__arm_v7s_map(data, blk_start, blk_paddr, size, prot, 1,
> >> + tablep) < 0) {
> >> + if (table) {
> >> + /* Free the table we allocated */
> >> + tablep = iopte_deref(table, 1);
> >> + __arm_v7s_free_table(tablep, 2, data);
> >
> > Following Will's quesion before, do we need flush tlb here?
>
> No; this is just cleaning up the uncommitted preparatory work if map
> failure left a partially-created next-level table - in fact, now that I
> look at it, with only two levels the only way that can happen is if we
> allocate a new empty table but find nonzero entries when installing the
> PTEs, and that suggests a level of system corruption I'm not sure it's
> even worth trying to handle.
>
> Anyway, from the IOMMU's perspective, at this point it knows nothing
> about the new table and the section mapping is still live...
>
> >> + }
> >> + return 0; /* Bytes unmapped */
> >> + }
> >> + }
> >> +
> >> + __arm_v7s_set_pte(ptep, table, 1, cfg);
> >
> > Is this in order to update the lvl2 pgtable base address? why it's
> > not updated in __arm_v7s_map which create a lvl2 pgtable?
>
> ...until here, when we drop the table entry over the top of the section
> entry and TLBI the section, for an atomic valid->valid transition.
>
> >> + iova &= ~(blk_size - 1);
> >> + cfg->tlb->tlb_add_flush(iova, blk_size, blk_size, true, data->iop.cookie);
> >> + return size;
> >> +}
> >> +
> >
> > All the others looks good for me. Thanks.
>
> Cool, thanks. I'll send out a proper v3 once everyone's finished with
> merge window stuff, but below is the local diff I now have.
>
> Robin.
>
next prev parent reply other threads:[~2016-01-18 6:28 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-17 20:50 [PATCH v2 0/3] io-pgtable ARM short descriptor format Robin Murphy
2015-12-17 20:50 ` [PATCH v2 1/3] iommu/io-pgtable: Add ARMv7 short descriptor support Robin Murphy
2016-01-14 13:05 ` Yong Wu
2016-01-15 15:13 ` Robin Murphy
2016-01-18 6:28 ` Yong Wu [this message]
2016-01-18 7:22 ` Yong Wu
2015-12-17 20:50 ` [PATCH v2 2/3] iommu/io-pgtable: Add helper functions for TLB ops Robin Murphy
2016-01-12 18:28 ` Will Deacon
2016-01-15 23:24 ` Laurent Pinchart
2015-12-17 20:50 ` [PATCH v2 3/3] iommu/io-pgtable: Avoid redundant TLB syncs Robin Murphy
2016-01-12 18:27 ` Will Deacon
2016-01-13 11:18 ` Robin Murphy
2016-01-13 11:22 ` Robin Murphy
2016-01-15 23:26 ` Laurent Pinchart
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=1453098535.10156.21.camel@mhfsdcap03 \
--to=yong.wu@mediatek.com \
--cc=linux-arm-kernel@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox