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 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.