diff mbox

[Xen-devel,v2,3/4] xen: arm: Do not use level 0 section mappings in boot page tables.

Message ID 1405699976-9260-3-git-send-email-ian.campbell@citrix.com
State New
Headers show

Commit Message

Ian Campbell July 18, 2014, 4:12 p.m. UTC
Level 0 does not support superpage mappings, meaning that systems on where Xen
is loaded above 512GB (I'm not aware of any such systems) the 1:1 mapping on
the boot page tables is invalid.

In order to avoid this issue we need an additional first level page table
mapped by the appropriate L0 slot and containing a 1:1 superpage mapping.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
v2: Fixed stray hard tab
---
 xen/arch/arm/arm64/head.S |   21 ++++++++++++++++++---
 xen/arch/arm/mm.c         |    3 +++
 2 files changed, 21 insertions(+), 3 deletions(-)

Comments

Julien Grall July 20, 2014, 8:42 p.m. UTC | #1
Hi Ian,

On 18/07/14 17:12, Ian Campbell wrote:
> Level 0 does not support superpage mappings, meaning that systems on where Xen
> is loaded above 512GB (I'm not aware of any such systems) the 1:1 mapping on
> the boot page tables is invalid.
>
> In order to avoid this issue we need an additional first level page table
> mapped by the appropriate L0 slot and containing a 1:1 superpage mapping.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>

Regards,

> ---
> v2: Fixed stray hard tab
> ---
>   xen/arch/arm/arm64/head.S |   21 ++++++++++++++++++---
>   xen/arch/arm/mm.c         |    3 +++
>   2 files changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
> index 5d7b2b5..6ba9d94 100644
> --- a/xen/arch/arm/arm64/head.S
> +++ b/xen/arch/arm/arm64/head.S
> @@ -267,13 +267,28 @@ skip_bss:
>           orr   x2, x1, x3             /*       + rights for linear PT */
>           str   x2, [x4, #0]           /* Map it in slot 0 */
>
> -        /* ... map of paddr(start) in boot_pgtable */
> +        /* ... map of paddr(start) in boot_pgtable+boot_first_id */
>           lsr   x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */
>           cbz   x1, 1f                 /* It's in slot 0, map in boot_first
>                                         * or boot_second later on */
>
> -        lsl   x2, x1, #ZEROETH_SHIFT /* Base address for 512GB mapping */
> -        mov   x3, #PT_MEM            /* x2 := Section mapping */
> +        /* Level zero does not support superpage mappings, so we have
> +         * to use an extra first level page in which we create a 1GB mapping.
> +         */
> +        ldr   x2, =boot_first_id
> +        add   x2, x2, x20            /* x2 := paddr (boot_first_id) */
> +
> +        mov   x3, #PT_PT             /* x2 := table map of boot_first_id */
> +        orr   x2, x2, x3             /*       + rights for linear PT */
> +        lsl   x1, x1, #3             /* x1 := Slot offset */
> +        str   x2, [x4, x1]
> +
> +        ldr   x4, =boot_first_id     /* Next level into boot_first_id */
> +        add   x4, x4, x20            /* x4 := paddr(boot_first_id) */
> +
> +        lsr   x1, x19, #FIRST_SHIFT  /* x1 := Offset of base paddr in boot_first_id */
> +        lsl   x2, x1, #FIRST_SHIFT   /* x2 := Base address for 1GB mapping */
> +        mov   x3, #PT_MEM            /* x2 := Section map */
>           orr   x2, x2, x3
>           and   x1, x1, #0x1ff         /* x1 := Slot offset */
>           lsl   x1, x1, #3
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index fdc7c98..0a243b0 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -68,6 +68,7 @@ struct domain *dom_xen, *dom_io, *dom_cow;
>   lpae_t boot_pgtable[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
>   #ifdef CONFIG_ARM_64
>   lpae_t boot_first[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
> +lpae_t boot_first_id[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
>   #endif
>   lpae_t boot_second[LPAE_ENTRIES]  __attribute__((__aligned__(4096)));
>   lpae_t boot_third[LPAE_ENTRIES]  __attribute__((__aligned__(4096)));
> @@ -491,6 +492,8 @@ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr)
>   #ifdef CONFIG_ARM_64
>       memset(boot_first, 0x0, PAGE_SIZE);
>       clean_and_invalidate_xen_dcache(boot_first);
> +    memset(boot_first_id, 0x0, PAGE_SIZE);
> +    clean_and_invalidate_xen_dcache(boot_first_id);
>   #endif
>       memset(boot_second, 0x0, PAGE_SIZE);
>       clean_and_invalidate_xen_dcache(boot_second);
>
diff mbox

Patch

diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 5d7b2b5..6ba9d94 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -267,13 +267,28 @@  skip_bss:
         orr   x2, x1, x3             /*       + rights for linear PT */
         str   x2, [x4, #0]           /* Map it in slot 0 */
 
-        /* ... map of paddr(start) in boot_pgtable */
+        /* ... map of paddr(start) in boot_pgtable+boot_first_id */
         lsr   x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */
         cbz   x1, 1f                 /* It's in slot 0, map in boot_first
                                       * or boot_second later on */
 
-        lsl   x2, x1, #ZEROETH_SHIFT /* Base address for 512GB mapping */
-        mov   x3, #PT_MEM            /* x2 := Section mapping */
+        /* Level zero does not support superpage mappings, so we have
+         * to use an extra first level page in which we create a 1GB mapping.
+         */
+        ldr   x2, =boot_first_id
+        add   x2, x2, x20            /* x2 := paddr (boot_first_id) */
+
+        mov   x3, #PT_PT             /* x2 := table map of boot_first_id */
+        orr   x2, x2, x3             /*       + rights for linear PT */
+        lsl   x1, x1, #3             /* x1 := Slot offset */
+        str   x2, [x4, x1]
+
+        ldr   x4, =boot_first_id     /* Next level into boot_first_id */
+        add   x4, x4, x20            /* x4 := paddr(boot_first_id) */
+
+        lsr   x1, x19, #FIRST_SHIFT  /* x1 := Offset of base paddr in boot_first_id */
+        lsl   x2, x1, #FIRST_SHIFT   /* x2 := Base address for 1GB mapping */
+        mov   x3, #PT_MEM            /* x2 := Section map */
         orr   x2, x2, x3
         and   x1, x1, #0x1ff         /* x1 := Slot offset */
         lsl   x1, x1, #3
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index fdc7c98..0a243b0 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -68,6 +68,7 @@  struct domain *dom_xen, *dom_io, *dom_cow;
 lpae_t boot_pgtable[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
 #ifdef CONFIG_ARM_64
 lpae_t boot_first[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
+lpae_t boot_first_id[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
 #endif
 lpae_t boot_second[LPAE_ENTRIES]  __attribute__((__aligned__(4096)));
 lpae_t boot_third[LPAE_ENTRIES]  __attribute__((__aligned__(4096)));
@@ -491,6 +492,8 @@  void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr)
 #ifdef CONFIG_ARM_64
     memset(boot_first, 0x0, PAGE_SIZE);
     clean_and_invalidate_xen_dcache(boot_first);
+    memset(boot_first_id, 0x0, PAGE_SIZE);
+    clean_and_invalidate_xen_dcache(boot_first_id);
 #endif
     memset(boot_second, 0x0, PAGE_SIZE);
     clean_and_invalidate_xen_dcache(boot_second);