All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@linaro.org>
To: Ian Campbell <ian.campbell@citrix.com>, xen-devel@lists.xen.org
Cc: tim@xen.org, vijay.kilari@gmail.com, stefano.stabellini@eu.citrix.com
Subject: Re: [PATCH RFC 9/9] xen: arm: support for up to 48-bit IPA addressing on arm64
Date: Thu, 07 Aug 2014 16:49:13 +0100	[thread overview]
Message-ID: <53E39FF9.5010503@linaro.org> (raw)
In-Reply-To: <178041f951bc35a80f5a2a7e228b95ddc6c7a64d.1406728037.git.ian.campbell@citrix.com>

Hi Ian,

On 07/30/2014 02:47 PM, Ian Campbell wrote:
> Currently we support only 40-bits. This is insufficient on systems where
> peripherals which need to be 1:1 mapped to dom0 are above the 40-bit limit.
> 
> Unfortunately the hardware requirements are such that this means that the
> number of levels in the P2M is not static and must vary with the number of
> implemented physical address bits. This is described in ARM DDI 0487A.b Table
> D4-5. In short there is no single p2m configuration which supports everything
> from 40- to 48- bits.
> 
> For example a system which supports up to 40-bit addressing will only support 3
> level p2m (maximum SL0 is 1 == 3 levels), requiring a concatenated page table
> root consisting of two pages to make the full 40-bits of addressing.
> 
> A maximum of 16 pages can be concatenated meaning that a 3 level p2m can only
> support up to 43-bit addreses. Therefore support for 48-bit addressing requres

s/addreses/addresses/
s/requres/requires/

> SL0==2 (4 levels of paging).
> 
> After the previous patches our various p2m lookup and manipulation functions
> already support starting at arbitrary level and with arbitrary root
> concatenation. All that remains is to determine the correct settings from
> ID_AA64MMFR0_EL1.PARange for which we use a lookup table.
> 
> As well as supporting 44 and 48 bit addressing we can also reduce the order of
> the first level for systems which support only 32 or 36 physical address bits,
> saving a page.
> 
> Systems with 42-bits are an interesting case, since they only support 3 levels
> of paging, implying that 8 pages are required at the root level. So far I am
> not aware of any systems with peripheral located so high up (the only 42-bit
> system I've seen has nothing above 40-bits), so such systems remain configured
> for 40-bit IPA with a pair of pages at the root of the p2m.
> 
> Switching to synbolic names for the VTCR_EL2 bits as we go improves the clarity

s/synbolic/symbolic/

> of the result.
> 
> Parts of this are derived from "xen/arm: Add 4-level page table for
> stage 2 translation" by Vijaya Kumar K.
> 
> arm32 remains with the static 3-level, 2 page root configuration.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>  xen/arch/arm/p2m.c              |   82 +++++++++++++++++++++++++++++++--------
>  xen/include/asm-arm/p2m.h       |    2 +-
>  xen/include/asm-arm/processor.h |   28 +++++++++++++
>  3 files changed, 94 insertions(+), 18 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index e9938ae..0e8e8e0 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -11,10 +11,17 @@
>  #include <asm/hardirq.h>
>  #include <asm/page.h>
>  
> -#define P2M_ROOT_LEVEL       1
> +#ifdef CONFIG_ARM_64
> +static int __read_mostly p2m_root_order;

unsigned int? It might even be better to use uint8_t as we won't never
have an order greater than 256. Even though I'm not sure if it will
improve performance.

> +static int __read_mostly p2m_root_level;

same here.

> +#define P2M_ROOT_ORDER    p2m_root_order
> +#define P2M_ROOT_LEVEL p2m_root_level
> +#else
> +/* First level P2M is alway 2 consecutive pages */
> +#define P2M_ROOT_LEVEL 1
> +#define P2M_ROOT_ORDER    1
> +#endif
>  
> -/* First level P2M is 2 consecutive pages */
> -#define P2M_ROOT_ORDER 1
>  #define P2M_ROOT_PAGES    (1<<P2M_ROOT_ORDER)
>  
>  static bool_t p2m_valid(lpae_t pte)
> @@ -164,6 +171,8 @@ paddr_t p2m_lookup(struct domain *d, paddr_t paddr, p2m_type_t *t)
>  
>      map = __map_domain_page(p2m->root + root_table);
>  
> +    BUG_ON(P2M_ROOT_LEVEL >= 4);
> +

For ARM64, P2M_ROOT_LEVEL is set up once at startup and AFAIU should not
change.

Using BUG_ON seem excessive here. If you want to keep a test, I would
use ASSERT to avoid impacting hypervisor in production mode.

>      for ( level = P2M_ROOT_LEVEL ; level < 4 ; level++ )
>      {
>          mask = masks[level];
> @@ -883,6 +892,7 @@ int p2m_alloc_table(struct domain *d)
>  {
>      struct p2m_domain *p2m = &d->arch.p2m;
>      struct page_info *page;
> +    int i;

unsigned int.

[..]

>  #ifdef CONFIG_ARM_32
> -    val = 0x80003558;
> -#else
> -    val = 0x80023558;
> +    printk("P2M: 40-bit IPA\n");
> +    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
> +#else /* CONFIG_ARM_64 */
> +    const struct {
> +        unsigned pabits; /* Physical Address Size */

missing the unsigned int by mistake? Or maybe uint8_t.

> +        unsigned t0sz;   /* Desired T0SZ, minimum in comment */
> +        unsigned root_order; /* Page order of the root of the p2m */
> +        unsigned sl0;    /* Desired SL0, maximum in comment */
> +    } pa_range_info[] = {
> +        /* T0SZ minimum and SL0 maximum from ARM DDI 0487A.b Table D4-5 */
> +        /*      PA size, t0sz(min), root-order, sl0(max) */
> +        [0] = { 32,      32/*32*/,  0,          1 },
> +        [1] = { 36,      28/*28*/,  0,          1 },
> +        [2] = { 40,      24/*24*/,  1,          1 },
> +        [3] = { 42,      24/*22*/,  1,          1 },
> +        [4] = { 44,      20/*20*/,  0,          2 },
> +        [5] = { 48,      16/*16*/,  0,          2 },
> +        [6] = { 0 }, /* Invalid */
> +        [7] = { 0 }  /* Invalid */
> +    };
> +
> +    int cpu;

unsigned int

> +    int pa_range = 0x10; /* Larger than any possible value */

same here.

> +
> +    for_each_online_cpu ( cpu )
> +    {
> +        struct cpuinfo_arm *info = &cpu_data[cpu];
> +        if ( info->mm64.pa_range < pa_range )
> +            pa_range = info->mm64.pa_range;
> +    }
> +
> +    /* pa_range is 4 bits, but the defined encodings are only 3 bits */
> +    if ( pa_range&0x8 || !pa_range_info[pa_range].pabits )

I think a space is missing around & for clarity.

> +        panic("Unknown encoding of ID_AA64MMFR0_EL1.PARange %x\n", pa_range);
> +
> +    val |= VTCR_PS(pa_range);
> +    val |= VTCR_TG0_4K;
> +    val |= VTCR_SL0(pa_range_info[pa_range].sl0);
> +    val |= VTCR_T0SZ(pa_range_info[pa_range].t0sz);
> +
> +    p2m_root_order = pa_range_info[pa_range].root_order;
> +    p2m_root_level = 2 - pa_range_info[pa_range].sl0;

Following my comment on BUG_ON earlier, I think you should check that we
correctly support the values set in p2m_root_{order,level} and bail out
if necessary.

[..]

> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 979a41d..a744a67 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -116,6 +116,34 @@
>  #define TCR_RES1        (_AC(1,UL)<<31)
>  #endif
>  
> +/* VTCR: Stage 2 Translation Control */
> +
> +#define VTCR_T0SZ(x)    ((x)<<0)
> +
> +#define VTCR_SL0(x)     ((x)<<6)
> +
> +#define VTCR_IRGN0_NC   (_AC(0x0,UL)<<8)
> +#define VTCR_IRGN0_WBWA (_AC(0x1,UL)<<8)
> +#define VTCR_IRGN0_WT   (_AC(0x2,UL)<<8)
> +#define VTCR_IRGN0_WB   (_AC(0x3,UL)<<8)
> +
> +#define VTCR_ORGN0_NC   (_AC(0x0,UL)<<10)
> +#define VTCR_ORGN0_WBWA (_AC(0x1,UL)<<10)
> +#define VTCR_ORGN0_WT   (_AC(0x2,UL)<<10)
> +#define VTCR_ORGN0_WB   (_AC(0x3,UL)<<10)
> +
> +#define VTCR_SH0_NS     (_AC(0x0,UL)<<12)
> +#define VTCR_SH0_OS     (_AC(0x2,UL)<<12)
> +#define VTCR_SH0_IS     (_AC(0x3,UL)<<12)
> +
> +#define VTCR_TG0_4K     (_AC(0x0,UL)<<14) /* arm64 only */
> +#define VTCR_TG0_64K    (_AC(0x1,UL)<<14)
> +#define VTCR_TG0_16K    (_AC(0x2,UL)<<14)
> +
> +#define VTCR_PS(x)      ((x)<<16)

All the define from the "/* arm64 only */" up to here are arm64 only.

With the comment at the end of the line it's no clear that it's actually
the case. It might be worse to add an #ifdef CONFIG_ARM_64

Regards,

-- 
Julien Grall

  reply	other threads:[~2014-08-07 15:49 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 13:44 [PATCH RFC 0/9] xen: arm: support for > 40-bit physical addressing Ian Campbell
2014-07-30 13:47 ` [PATCH RFC 1/9] xen: arm: rename p2m->first_level to p2m->root Ian Campbell
2014-07-30 13:47   ` [PATCH RFC 2/9] xen: arm: Implement variable levels in dump_pt_walk Ian Campbell
2014-07-30 16:40     ` Julien Grall
2014-07-30 13:47   ` [PATCH RFC 3/9] xen: arm: handle concatenated root tables " Ian Campbell
2014-07-30 16:58     ` Julien Grall
2014-09-04 14:40       ` Ian Campbell
2014-09-08 20:54         ` Julien Grall
2014-07-30 13:47   ` [PATCH RFC 4/9] xen: arm: move setup_virt_paging to p2m.c Ian Campbell
2014-07-30 17:00     ` Julien Grall
2014-07-30 13:47   ` [PATCH RFC 5/9] xen: arm: Defer setting of VTCR_EL2 until after CPUs are up Ian Campbell
2014-07-30 17:11     ` Julien Grall
2014-09-04 14:50       ` Ian Campbell
2014-07-30 13:47   ` [PATCH RFC 6/9] xen: arm: handle variable p2m levels in p2m_lookup Ian Campbell
2014-07-31 11:14     ` Julien Grall
2014-09-04 14:54       ` Ian Campbell
2014-07-30 13:47   ` [PATCH RFC 7/9] xen: arm: handle variable p2m levels in apply_p2m_changes Ian Campbell
2014-07-31 15:38     ` Julien Grall
2014-08-11  7:00     ` Vijay Kilari
2014-08-26  9:11       ` Vijay Kilari
2014-09-04 14:01         ` Ian Campbell
2014-07-30 13:47   ` [PATCH RFC 8/9] xen: arm: support for up to 48-bit physical addressing on arm64 Ian Campbell
2014-08-07 15:33     ` Julien Grall
2014-07-30 13:47   ` [PATCH RFC 9/9] xen: arm: support for up to 48-bit IPA " Ian Campbell
2014-08-07 15:49     ` Julien Grall [this message]
2014-07-30 16:06   ` [PATCH RFC 1/9] xen: arm: rename p2m->first_level to p2m->root Julien Grall
2014-07-30 16:19     ` Ian Campbell
2014-07-30 16:23       ` Julien Grall
2014-07-31  8:22 ` [PATCH RFC 0/9] xen: arm: support for > 40-bit physical addressing Vijay Kilari
2014-07-31  8:54   ` Ian Campbell

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=53E39FF9.5010503@linaro.org \
    --to=julien.grall@linaro.org \
    --cc=ian.campbell@citrix.com \
    --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.