From: Arianna Avanzini <avanzini.arianna@gmail.com>
To: Ian Campbell <ian.campbell@citrix.com>
Cc: stefano.stabellini@eu.citrix.com, tim@xen.org,
vijay.kilari@gmail.com, julien.grall@linaro.org,
xen-devel@lists.xen.org
Subject: Re: [PATCH v2 7/9] xen: arm: handle variable p2m levels in apply_p2m_changes
Date: Sat, 6 Sep 2014 01:32:36 +0200 [thread overview]
Message-ID: <20140905233235.GC969@gmail.com> (raw)
In-Reply-To: <8fbbcaa9097d88db66a4527b23eca5d02970fa99.1409847257.git.ian.campbell@citrix.com>
On Thu, Sep 04, 2014 at 05:14:15PM +0100, Ian Campbell wrote:
> As with previous changes this involves conversion from a linear series of
> lookups into a loop over the levels.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Arianna Avanzini <avanzini.arianna@gmail.com>
(For the little it's worth, everything looks fine to me)
> ---
> v2:
> - Rebase, in particular over 4b25423aee13 "arch/arm: unmap partially-mapped
> memory regions" which had some interesting interactions (which I hope I've
> gotten right!)
> - Spell previous and concatenate correctly.
> - ASSERT rather than BUG_ON for concatenated level zero root.
> ---
> xen/arch/arm/p2m.c | 172 ++++++++++++++++++++++++----------------------------
> 1 file changed, 78 insertions(+), 94 deletions(-)
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index ea5e342..8e330c7 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -15,7 +15,6 @@
>
> /* First level P2M is 2 consecutive pages */
> #define P2M_ROOT_ORDER 1
> -#define P2M_ROOT_ENTRIES (LPAE_ENTRIES<<P2M_ROOT_ORDER)
> #define P2M_ROOT_PAGES (1<<P2M_ROOT_ORDER)
>
> static bool_t p2m_valid(lpae_t pte)
> @@ -119,31 +118,6 @@ void flush_tlb_domain(struct domain *d)
> p2m_load_VTTBR(current->domain);
> }
>
> -static int p2m_first_level_index(paddr_t addr)
> -{
> - /*
> - * 1st pages are concatenated so zeroeth offset gives us the
> - * index of the 1st page
> - */
> - return zeroeth_table_offset(addr);
> -}
> -
> -/*
> - * Map whichever of the first pages contain addr. The caller should
> - * then use first_table_offset as an index.
> - */
> -static lpae_t *p2m_map_first(struct p2m_domain *p2m, paddr_t addr)
> -{
> - struct page_info *page;
> -
> - if ( first_linear_offset(addr) >= P2M_ROOT_ENTRIES )
> - return NULL;
> -
> - page = p2m->root + p2m_first_level_index(addr);
> -
> - return __map_domain_page(page);
> -}
> -
> /*
> * Lookup the MFN corresponding to a domain's PFN.
> *
> @@ -733,13 +707,12 @@ static int apply_p2m_changes(struct domain *d,
> {
> int rc, ret;
> struct p2m_domain *p2m = &d->arch.p2m;
> - lpae_t *first = NULL, *second = NULL, *third = NULL;
> + lpae_t *mappings[4] = { NULL, };
> paddr_t addr, orig_maddr = maddr;
> unsigned int level = 0;
> - unsigned long cur_first_page = ~0,
> - cur_first_offset = ~0,
> - cur_second_offset = ~0;
> - unsigned long count = 0;
> + unsigned int cur_root_table = ~0;
> + unsigned int cur_offset[4] = { ~0, };
> + unsigned int count = 0;
> bool_t flush = false;
> bool_t flush_pt;
>
> @@ -751,9 +724,21 @@ static int apply_p2m_changes(struct domain *d,
>
> spin_lock(&p2m->lock);
>
> + /* Static mapping. P2M_ROOT_PAGES > 1 are handled below */
> + if ( P2M_ROOT_PAGES == 1 )
> + mappings[P2M_ROOT_LEVEL] = __map_domain_page(p2m->root);
> +
> addr = start_gpaddr;
> while ( addr < end_gpaddr )
> {
> + int root_table;
> + const unsigned int offsets[4] = {
> + zeroeth_table_offset(addr),
> + first_table_offset(addr),
> + second_table_offset(addr),
> + third_table_offset(addr)
> + };
> +
> /*
> * Arbitrarily, preempt every 512 operations or 8192 nops.
> * 512*P2M_ONE_PROGRESS == 8192*P2M_ONE_PROGRESS_NOP == 0x2000
> @@ -773,76 +758,72 @@ static int apply_p2m_changes(struct domain *d,
> count = 0;
> }
>
> - if ( cur_first_page != p2m_first_level_index(addr) )
> + if ( P2M_ROOT_PAGES > 1 )
> {
> - if ( first ) unmap_domain_page(first);
> - first = p2m_map_first(p2m, addr);
> - if ( !first )
> + int i;
> + /*
> + * Concatenated root-level tables. The table number will be the
> + * offset at the previous level. It is not possible to concatenate
> + * a level-0 root.
> + */
> + ASSERT(P2M_ROOT_LEVEL > 0);
> + root_table = offsets[P2M_ROOT_LEVEL - 1];
> + if ( root_table >= P2M_ROOT_PAGES )
> {
> rc = -EINVAL;
> goto out;
> }
> - cur_first_page = p2m_first_level_index(addr);
> - /* Any mapping further down is now invalid */
> - cur_first_offset = cur_second_offset = ~0;
> - }
> -
> - /* We only use a 3 level p2m at the moment, so no level 0,
> - * current hardware doesn't support super page mappings at
> - * level 0 anyway */
> -
> - level = 1;
> - ret = apply_one_level(d, &first[first_table_offset(addr)],
> - level, flush_pt, op,
> - start_gpaddr, end_gpaddr,
> - &addr, &maddr, &flush,
> - mattr, t);
> - if ( ret < 0 ) { rc = ret ; goto out; }
> - count += ret;
> - if ( ret != P2M_ONE_DESCEND ) continue;
> -
> - BUG_ON(!p2m_valid(first[first_table_offset(addr)]));
>
> - if ( cur_first_offset != first_table_offset(addr) )
> - {
> - if (second) unmap_domain_page(second);
> - second = map_domain_page(first[first_table_offset(addr)].p2m.base);
> - cur_first_offset = first_table_offset(addr);
> - /* Any mapping further down is now invalid */
> - cur_second_offset = ~0;
> + if ( cur_root_table != root_table )
> + {
> + if ( mappings[P2M_ROOT_LEVEL] )
> + unmap_domain_page(mappings[P2M_ROOT_LEVEL]);
> + mappings[P2M_ROOT_LEVEL] =
> + __map_domain_page(p2m->root + root_table);
> + if ( !mappings[P2M_ROOT_LEVEL] )
> + {
> + rc = -EINVAL;
> + goto out;
> + }
> + cur_root_table = root_table;
> + /* Any mapping further down is now invalid */
> + for ( i = P2M_ROOT_LEVEL; i < 4; i++ )
> + cur_offset[i] = ~0;
> + }
> }
> - /* else: second already valid */
> -
> - level = 2;
> - ret = apply_one_level(d,&second[second_table_offset(addr)],
> - level, flush_pt, op,
> - start_gpaddr, end_gpaddr,
> - &addr, &maddr, &flush,
> - mattr, t);
> - if ( ret < 0 ) { rc = ret ; goto out; }
> - count += ret;
> - if ( ret != P2M_ONE_DESCEND ) continue;
>
> - BUG_ON(!p2m_valid(second[second_table_offset(addr)]));
> -
> - if ( cur_second_offset != second_table_offset(addr) )
> + for ( level = P2M_ROOT_LEVEL; level < 4; level++ )
> {
> - /* map third level */
> - if (third) unmap_domain_page(third);
> - third = map_domain_page(second[second_table_offset(addr)].p2m.base);
> - cur_second_offset = second_table_offset(addr);
> + unsigned offset = offsets[level];
> + lpae_t *entry = &mappings[level][offset];
> +
> + ret = apply_one_level(d, entry,
> + level, flush_pt, op,
> + start_gpaddr, end_gpaddr,
> + &addr, &maddr, &flush,
> + mattr, t);
> + if ( ret < 0 ) { rc = ret ; goto out; }
> + count += ret;
> + /* L3 had better have done something! We cannot descend any further */
> + BUG_ON(level == 3 && ret == P2M_ONE_DESCEND);
> + if ( ret != P2M_ONE_DESCEND ) break;
> +
> + BUG_ON(!p2m_valid(*entry));
> +
> + if ( cur_offset[level] != offset )
> + {
> + /* Update mapping for next level */
> + int i;
> + if ( mappings[level+1] )
> + unmap_domain_page(mappings[level+1]);
> + mappings[level+1] = map_domain_page(entry->p2m.base);
> + cur_offset[level] = offset;
> + /* Any mapping further down is now invalid */
> + for ( i = level+1; i < 4; i++ )
> + cur_offset[i] = ~0;
> + }
> + /* else: next level already valid */
> }
> -
> - level = 3;
> - ret = apply_one_level(d, &third[third_table_offset(addr)],
> - level, flush_pt, op,
> - start_gpaddr, end_gpaddr,
> - &addr, &maddr, &flush,
> - mattr, t);
> - if ( ret < 0 ) { rc = ret ; goto out; }
> - /* L3 had better have done something! We cannot descend any further */
> - BUG_ON(ret == P2M_ONE_DESCEND);
> - count += ret;
> }
>
> if ( flush )
> @@ -866,9 +847,6 @@ static int apply_p2m_changes(struct domain *d,
> rc = 0;
>
> out:
> - if (third) unmap_domain_page(third);
> - if (second) unmap_domain_page(second);
> - if (first) unmap_domain_page(first);
> if ( rc < 0 && ( op == INSERT || op == ALLOCATE ) &&
> addr != start_gpaddr )
> {
> @@ -884,6 +862,12 @@ out:
> mattr, p2m_invalid);
> }
>
> + for ( level = P2M_ROOT_LEVEL; level < 4; level ++ )
> + {
> + if ( mappings[level] )
> + unmap_domain_page(mappings[level]);
> + }
> +
> spin_unlock(&p2m->lock);
>
> return rc;
> --
> 1.7.10.4
>
--
/*
* Arianna Avanzini
* avanzini.arianna@gmail.com
* 73628@studenti.unimore.it
*/
next prev parent reply other threads:[~2014-09-05 23:32 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-04 16:13 [PATCH v2 0/9] xen: arm: support for > 40-bit physical addressing Ian Campbell
2014-09-04 16:14 ` [PATCH v2 1/9] xen: arm: rename p2m->first_level to p2m->root Ian Campbell
2014-09-04 16:14 ` [PATCH v2 2/9] xen: arm: Implement variable levels in dump_pt_walk Ian Campbell
2014-09-08 21:24 ` Julien Grall
2014-09-08 22:12 ` Julien Grall
2014-09-09 15:04 ` Ian Campbell
2014-09-09 15:08 ` Ian Campbell
2014-09-09 16:04 ` Andrew Cooper
2014-09-08 21:33 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 3/9] xen: arm: handle concatenated root tables " Ian Campbell
2014-09-08 21:43 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 4/9] xen: arm: move setup_virt_paging to p2m.[ch] from mm.[ch] Ian Campbell
2014-09-04 16:14 ` [PATCH v2 5/9] xen: arm: Defer setting of VTCR_EL2 until after CPUs are up Ian Campbell
2014-09-08 21:46 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 6/9] xen: arm: handle variable p2m levels in p2m_lookup Ian Campbell
2014-09-08 22:05 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 7/9] xen: arm: handle variable p2m levels in apply_p2m_changes Ian Campbell
2014-09-05 23:32 ` Arianna Avanzini [this message]
2014-09-08 8:59 ` Ian Campbell
2014-09-08 22:22 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 8/9] xen: arm: support for up to 48-bit physical addressing on arm64 Ian Campbell
2014-09-08 23:28 ` Julien Grall
2014-09-04 16:14 ` [PATCH v2 9/9] xen: arm: support for up to 48-bit IPA " Ian Campbell
2014-09-08 23:42 ` Julien Grall
2014-09-08 21:05 ` [PATCH v2 1/9] xen: arm: rename p2m->first_level to p2m->root Julien Grall
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=20140905233235.GC969@gmail.com \
--to=avanzini.arianna@gmail.com \
--cc=ian.campbell@citrix.com \
--cc=julien.grall@linaro.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=tim@xen.org \
--cc=vijay.kilari@gmail.com \
--cc=xen-devel@lists.xen.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;
as well as URLs for NNTP newsgroup(s).